There's this feature called "Monetize" in the blog settings. It's even there for all of my blogs.
As most of my posts go: little, if any, research. Take the information here with a grain of salt. I write these posts fairly quickly and am bound to make mistakes. If there is a mistake, point it out with relevant sources and I'll happily edit the content.
Many of which do not have any readers. This one, if Google's stats are right (I think they're inflated), has about 100 page hits a month. That's less than 100 readers a month. And this blog actually has more readers than any of my other blogs. Admittedly, if we're optimistic, I might say that the potential revenue is $0.15$ a month (assume a CPC of $0.30$, each person actually clicks, and we get 50% - you can verify these numbers Google Traffic Estimator Sandbox and http://adsense.blogspot.com/2010/05/adsense-revenue-share.html).
So... let's say that to make this venture break even (writing takes time), then $100.00 a month would cover my time to write silly rants. Assuming I'd even care about the cash.
Ok, that's about 666 clicks per month. If (assumption again, beware) 10% of readers click (I'm sure my target audience loves ad-block. I love ad-block too!), that's about 6660 readers a month.
Why did I feel like ranting? Consider this: blogs with few readers that have ads will benefit whoever serves ads (larger accumulated potential user-base). It also makes blogs that exist in the hopes to make profit stick out like a sore thumb. It is possible for a new blog to attract a large user-base on the first or second post. Enough to make ads a good idea.
On the other-hand - wouldn't a blog like that try to keep the momentum going for a few months? See that success is good after the first month (or so) and then monetize?
Why did I write this? I enjoy looking at the stats. Trying to understand why 100 lost souls would wander to this blog each month. Looking for patterns. I've found a few, but that's for another post. This one arose when I compared the stats to the monetize features.
I'm aware there are plenty of sites that offer hints on how to maximize profit using ads. I don't care for that. This blog is my little soap box. It has no focus. It has no research. It just rants. 100 readers a month is amazing for something with so little focus that it hurts. 100 is amazing since I'm not targeting anyone, just writing what I'd contemplate anyhow. Writing what I'd write anyhow and forget in a drawer....
Now my rants are forgotten, but indexed by search-engines all over!
Saturday, January 22, 2011
Doxygen: Step-by-step
I've started to use Doxygen to document a small little experimental library of mine. Here are the steps I would use to document in retrospect.
First step was to create a header file for the library. Call it myLibrary.h. In addition to including any files that should be publicly available, I put in a nice piece of documentation to specify what the library does.
/*! \mainpage
My library does something. It's awesome.
Here are two examples:
- \subpage AwesomeDemo1
- \subpage AwesomeDemo2
*/
This just sets up our main page. It states what the library does. I have two example pages. One of them is called AwesomeDemo1 and the other is AwesomeDemo2. The dash denotes that this is a list of items.
Ok, that's a good first step. Now, let's look at AwesomeFunctionality.h. All of the following are fragments from AwesomeFunctionality.h with some comments mixed in to explain what's going on:
/*! \file AwesomeFunctionality.h
\brief This is awesome
Awesomeness is achieved by doing awesome things. These awesome things arise from the awesome code made available in this header file.
*/
This declares what the file does. What should we find in this file?! It sort of emphasizes the simple fact that no file should be a catch-all for garbage that belongs elsewhere. Give your file a purpose! In Doxygen, when you generate a file list, the text after "brief" becomes a short description of the file (call it an overview so someone knows if they want to know more). The text afterwards is for once the reader decides to get more information.
/*! \page AwesomeDemo1 First Awesome Demo
Here's something awesome:
\code
Awesome *x = new Awesome();
\endcode
*/
Recall our AwesomeDemo1? Here we name it "First Awesome Demo", which will be linked to from the main page (and also serves as the name for this page). Following is the text on the page, and a piece of sample code.
I tend to learn from example, and Doxygen will link the sample code to the documented classes. Be clear and concise about what the demo does with little added fluff and your reader will be happy.
/*! \defgroup AwesomeGroup The awesomeness begins here
This group contains a set of things that are awesome and you should look at!
*/
This defines a module that the user will see as "The awesomeness begins here". You might want to name it something reasonable, such as "Compositing Capabilities". Imagine if you're a reader that wants to do "awesome things". Then if functions and classes related to "awesome thing" can be found in a single place, it makes the reader's life easier.
Finally, let's get to the interesting part:
//! Does something awesome
/*! \ingroup AwesomeGroup
This is an awesome thing!
Look at the function \ref AwesomeFunction for more details!
*/
class Awesome
{
//! Awesome data member
int m_awesome;
};
Finally, some code. This is just a header file, so it's just a skeleton. The first comment is the brief. "Does something awesome" should give the reader a clear idea of what the object does. The longer documentation, using C-style comments (don't forget the !), first specifies that this has something to do with the AwesomeGroup. Then we give a longer description of what the object does. Notice we use "\ref", it will make a link to the function called AwesomeFunction. Normally, for classes, links are automatically created.
For each member within the class, we document them as our next example. If there isn't much, we just leave in the brief comment.
//! Initializes the awesomeness
/*! \ingroup AwesomeGroup
\param[in] something something or other
\pre The awesomeness has not been initialized
\post The awesomeness is initialized
\exception If the awesomeness was already initialized
\return An awesome integer
*/
int AwesomeFunction(int something)
Now... for methods within a class, normally I wouldn't use "\ingroup". The rest is to be used judiciously. Your goal is to give enough information so that the object may be used without drowning the user with too much information.
The parameters can be named as either [in], [out], or [in,out]. Specify if data will change or not. Const should be used for [in] though.
The pre-condition, post-condition, and exception parts should be used judiciously. Or so I believe. It is nice to have them though.
Return - well, it's always a good idea to say what that is.
I used the GUI front-end. Upon compiling the documentation, I did not include any private headers or source (.cpp) files. Essentially, only the public documentation should be easy to get. Private documentation should be accessible within the headers but more challenging to get at.
As a reader, you must have realized that most of my efforts have been for the reader. And the logic is quite simple - the documentation is for another person - a future reader. Documentation simply makes your project more accessible to others. Something that is essential for open-source projects. To be used, it has to be easy, and require minimal effort on the part of the user (regardless of functionality).
First step was to create a header file for the library. Call it myLibrary.h. In addition to including any files that should be publicly available, I put in a nice piece of documentation to specify what the library does.
/*! \mainpage
My library does something. It's awesome.
Here are two examples:
- \subpage AwesomeDemo1
- \subpage AwesomeDemo2
*/
This just sets up our main page. It states what the library does. I have two example pages. One of them is called AwesomeDemo1 and the other is AwesomeDemo2. The dash denotes that this is a list of items.
Ok, that's a good first step. Now, let's look at AwesomeFunctionality.h. All of the following are fragments from AwesomeFunctionality.h with some comments mixed in to explain what's going on:
/*! \file AwesomeFunctionality.h
\brief This is awesome
Awesomeness is achieved by doing awesome things. These awesome things arise from the awesome code made available in this header file.
*/
This declares what the file does. What should we find in this file?! It sort of emphasizes the simple fact that no file should be a catch-all for garbage that belongs elsewhere. Give your file a purpose! In Doxygen, when you generate a file list, the text after "brief" becomes a short description of the file (call it an overview so someone knows if they want to know more). The text afterwards is for once the reader decides to get more information.
/*! \page AwesomeDemo1 First Awesome Demo
Here's something awesome:
\code
Awesome *x = new Awesome();
\endcode
*/
Recall our AwesomeDemo1? Here we name it "First Awesome Demo", which will be linked to from the main page (and also serves as the name for this page). Following is the text on the page, and a piece of sample code.
I tend to learn from example, and Doxygen will link the sample code to the documented classes. Be clear and concise about what the demo does with little added fluff and your reader will be happy.
/*! \defgroup AwesomeGroup The awesomeness begins here
This group contains a set of things that are awesome and you should look at!
*/
This defines a module that the user will see as "The awesomeness begins here". You might want to name it something reasonable, such as "Compositing Capabilities". Imagine if you're a reader that wants to do "awesome things". Then if functions and classes related to "awesome thing" can be found in a single place, it makes the reader's life easier.
Finally, let's get to the interesting part:
//! Does something awesome
/*! \ingroup AwesomeGroup
This is an awesome thing!
Look at the function \ref AwesomeFunction for more details!
*/
class Awesome
{
//! Awesome data member
int m_awesome;
};
Finally, some code. This is just a header file, so it's just a skeleton. The first comment is the brief. "Does something awesome" should give the reader a clear idea of what the object does. The longer documentation, using C-style comments (don't forget the !), first specifies that this has something to do with the AwesomeGroup. Then we give a longer description of what the object does. Notice we use "\ref", it will make a link to the function called AwesomeFunction. Normally, for classes, links are automatically created.
For each member within the class, we document them as our next example. If there isn't much, we just leave in the brief comment.
//! Initializes the awesomeness
/*! \ingroup AwesomeGroup
\param[in] something something or other
\pre The awesomeness has not been initialized
\post The awesomeness is initialized
\exception If the awesomeness was already initialized
\return An awesome integer
*/
int AwesomeFunction(int something)
Now... for methods within a class, normally I wouldn't use "\ingroup". The rest is to be used judiciously. Your goal is to give enough information so that the object may be used without drowning the user with too much information.
The parameters can be named as either [in], [out], or [in,out]. Specify if data will change or not. Const should be used for [in] though.
The pre-condition, post-condition, and exception parts should be used judiciously. Or so I believe. It is nice to have them though.
Return - well, it's always a good idea to say what that is.
I used the GUI front-end. Upon compiling the documentation, I did not include any private headers or source (.cpp) files. Essentially, only the public documentation should be easy to get. Private documentation should be accessible within the headers but more challenging to get at.
As a reader, you must have realized that most of my efforts have been for the reader. And the logic is quite simple - the documentation is for another person - a future reader. Documentation simply makes your project more accessible to others. Something that is essential for open-source projects. To be used, it has to be easy, and require minimal effort on the part of the user (regardless of functionality).
Monday, January 17, 2011
Simulating a Simple Fluid on I.B.M.'s Cell Broadband Engine...
I have just spent a bit more quality time with a PS3 running Linux (I opted to not update the firmware). Upon coding, I realized one thing: spe_context_run is extremely slow. My programming strategy was to use the PPE to quickly assign tasks to the SPU in a way that would minimize cache misses.
I'll step back a bit. The PPU runs a simple piece of code that tells it what it should run on each SPU once a task completes. What it should run depends upon what data is already loaded into the SPE's local store, what data is already local to the cell but within another SPE's local store, and what has to be uploaded. The problem is that I can't call spe_context_run too often or else the application is too slow. The best performance I obtained by doing the same amount of work and DMA data transfers while minimizing the number of calls to spe_context_run.
What does this mean? The SPE should be treated as an independent machine that so happens to share memory with other SPEs and the PPE. It should be given a big list of tasks that it can work on without any support from the PPE.
Why is this a challenge? I'm integrating the equations of fluid flow. Communication should occur between the SPEs for the boundary conditions. Rather, I'm betting that border conditions only need to be worried about during the change of frame. Why? If I can run the simulations sufficiently fast (80+fps) then my calculations say that this little cheat will not be noticed by the user of the system.
Numerical modelling for my claim? consider the CFL condition. Let's say the grid-size is 1. Then the maximum velocity should be about 1 grid-cell per pass of a finite-differencing-based advection scheme. I'd suggest using forward and backwards finite differencing for integration rather than central differencing as central differencing will have trouble with sharp edges. Anyhow, we have a maximum velocity of 1/timestep. At 80fps, that's about 80 pixels that data can travel per second across the grid.
That is sufficient for my purposes. For a 1024x1024 grid, it would take 12.8 seconds for something to travel across it. Projected onto a sufficiently large surface (not a monitor) the user will feel like the fluid is moving at a brisk pace.
Maybe a Lagrangian method would be better. Or even a finite-element method. I've already tuned my code for Eulerian grids... unfortunately. I'll build something better in the next development cycle.
I'll step back a bit. The PPU runs a simple piece of code that tells it what it should run on each SPU once a task completes. What it should run depends upon what data is already loaded into the SPE's local store, what data is already local to the cell but within another SPE's local store, and what has to be uploaded. The problem is that I can't call spe_context_run too often or else the application is too slow. The best performance I obtained by doing the same amount of work and DMA data transfers while minimizing the number of calls to spe_context_run.
What does this mean? The SPE should be treated as an independent machine that so happens to share memory with other SPEs and the PPE. It should be given a big list of tasks that it can work on without any support from the PPE.
Why is this a challenge? I'm integrating the equations of fluid flow. Communication should occur between the SPEs for the boundary conditions. Rather, I'm betting that border conditions only need to be worried about during the change of frame. Why? If I can run the simulations sufficiently fast (80+fps) then my calculations say that this little cheat will not be noticed by the user of the system.
Numerical modelling for my claim? consider the CFL condition. Let's say the grid-size is 1. Then the maximum velocity should be about 1 grid-cell per pass of a finite-differencing-based advection scheme. I'd suggest using forward and backwards finite differencing for integration rather than central differencing as central differencing will have trouble with sharp edges. Anyhow, we have a maximum velocity of 1/timestep. At 80fps, that's about 80 pixels that data can travel per second across the grid.
That is sufficient for my purposes. For a 1024x1024 grid, it would take 12.8 seconds for something to travel across it. Projected onto a sufficiently large surface (not a monitor) the user will feel like the fluid is moving at a brisk pace.
Maybe a Lagrangian method would be better. Or even a finite-element method. I've already tuned my code for Eulerian grids... unfortunately. I'll build something better in the next development cycle.
Saturday, January 15, 2011
Education Through Games? (arithmetic)
One of my favourite quotes is something along the lines: "the human body can do infinite amounts of work -- as long as it isn't what it's supposed to do..."
I'm talking specifically about the use of video-games. Since people tend to enjoy playing them there must have a way to infuse them with educational material. So the logic goes. Likewise, the same logic should work for board-games, or any other type of game.
However, overtly claiming the educational nature of a game makes it less entertaining. Requiring someone to "play" an educational game is about as fun as doing homework.
To successfully make a game that teaches something, the game must be primarily designed to entertain and challenge. The learning should occur implicitly.
For example, let's consider a turn-based battle sequence in an RPG. Each action by the player balances how much damage that can be taken versus what can be dealt. Let's say the player has one unit and the computer opponent has a single unit.
The units on both side have HP (health power) and Damage. Both are integral values. Damage from one player deducts health power from another player. If health power reaches 0, then a player loses (dies).
A step back reveals that the player can compare both numbers. If Damage exceeds HP then the opponent is guaranteed to fail. This leads to the typical strategy: concentrate all fire-power on the weakest of the opponent's units. The weakest unit of the opponent will die off.
What we have described is a system that requires knowledge of the concepts underlying the number system and a means to compare. Many games display meters to reflect the underlying integral value as a quick-reference metric. But the end result is the same. I'll argue that this type of game can be more effectively used as an educational game then games designed to be educational for use in an educational setting.
Even this is an over-simplification of the scenario. Often, the HP of the opponent's units are unknown. Through defeating an opponent once, the player can estimate how much HP that opponent has. This requires the ability to sum up values and maintain a mental dictionary of the capabilities of each opponent.
Further within the game, the human player must deal with more and more complex scenarios. Poison, applied to a unit, will decrease the unit's HP each and every turn by some amount. Resistance to different magics (fire and ice could be the magics) also affects how the player positions their units against opponent units.
Tactical RPGs take this concept a step further and adds in the lay of the land to the mix. Attacking a unit from behind leads to more damage being dealt at the expense of having to move a unit in place to do the attack.
In the end, if I wanted someone to learn something about arithmetic, I would suggest an RPG. With any luck, the one they'll choose will force them to consider the underlying numerical system.
I'm talking specifically about the use of video-games. Since people tend to enjoy playing them there must have a way to infuse them with educational material. So the logic goes. Likewise, the same logic should work for board-games, or any other type of game.
However, overtly claiming the educational nature of a game makes it less entertaining. Requiring someone to "play" an educational game is about as fun as doing homework.
To successfully make a game that teaches something, the game must be primarily designed to entertain and challenge. The learning should occur implicitly.
For example, let's consider a turn-based battle sequence in an RPG. Each action by the player balances how much damage that can be taken versus what can be dealt. Let's say the player has one unit and the computer opponent has a single unit.
The units on both side have HP (health power) and Damage. Both are integral values. Damage from one player deducts health power from another player. If health power reaches 0, then a player loses (dies).
A step back reveals that the player can compare both numbers. If Damage exceeds HP then the opponent is guaranteed to fail. This leads to the typical strategy: concentrate all fire-power on the weakest of the opponent's units. The weakest unit of the opponent will die off.
What we have described is a system that requires knowledge of the concepts underlying the number system and a means to compare. Many games display meters to reflect the underlying integral value as a quick-reference metric. But the end result is the same. I'll argue that this type of game can be more effectively used as an educational game then games designed to be educational for use in an educational setting.
Even this is an over-simplification of the scenario. Often, the HP of the opponent's units are unknown. Through defeating an opponent once, the player can estimate how much HP that opponent has. This requires the ability to sum up values and maintain a mental dictionary of the capabilities of each opponent.
Further within the game, the human player must deal with more and more complex scenarios. Poison, applied to a unit, will decrease the unit's HP each and every turn by some amount. Resistance to different magics (fire and ice could be the magics) also affects how the player positions their units against opponent units.
Tactical RPGs take this concept a step further and adds in the lay of the land to the mix. Attacking a unit from behind leads to more damage being dealt at the expense of having to move a unit in place to do the attack.
In the end, if I wanted someone to learn something about arithmetic, I would suggest an RPG. With any luck, the one they'll choose will force them to consider the underlying numerical system.
Saturday, January 8, 2011
Pickles Wrapped in Melted Cheese
Over the past few years, I have seen things that I did not want to see. Things that I would have characterized as nightmares. Today, these things still progress like a train wreck in slow motion. Pickles wrapped in melted cheese is just a minor glitch on the radar. I might have eaten it if it were prepared as a dare. Maybe.
As life progresses, I question my sanity. Every day I question what I have done (did I do the right thing? could I have been a better person? is my mental state ok?). These external circumstances have made me more alert to my mental state of mind.
These external circumstances have set a dark cloud over my thoughts. To make the light shine through, I've been avoiding parts of my life. Splitting my personality. Different people see different sides. I try to not mix the two worlds. This barrier is set up for a reason. For my sanity. And I don't want other people's pity (everyone has bad things in their lives -- so it would probably pass as normal).
This dark cloud has gotten me interested in stories that emphasize interpersonal relationships (typically in darker scenarios). Things happen. Yes. Good and bad. In society, good arises from good relationships among people. Could it be I wish to know the future? Do I want to subconsciously desire a means to avoid the worst? Or am I consoling myself by emphasizing that things could be worse? Who knows.
I think that I need to change parts of my environment. In some, there is no light at the end of the tunnel. In lieu of light there are traps. The train-wreck is in slow motion. For years. I can sense it. I can hear it. I could even taste it...
Initial Thoughts on 9 Hours 9 Persons 9 Doors
Due to circumstances (standard barter) I got my hands on this game. I've seen 3 endings so far (there are 6 as far as I can tell). Each one I've seen, the protagonist has died. I'm forcing myself to put the game down while I reflect upon the storyline.
A warning of sorts first. 9 Hours, 9 Persons, 9 Doors is a puzzle game for the DS where things go bad. Horribly bad. There are deaths in the game. What follows is my thoughts into trying to figure out who did the murders -- given incomplete information.
Ignoring that the story is attempting to poison my mind with facts that could appear real, but probably aren't, I should see how much is real or fiction. The part about the Titanic's sister ships is real -- as is the idea that the ship was cursed -- I don't know about the predicted sinking in previously published fiction or whether there is any discussion (prior to the game) that Titanic was sunk on purpose and Olympic is really the Titanic... For all purposes, the warning at the beginning of the game should put my mind at ease: it's all fiction. Relation to any actual occurrences is purely coincidental.
What has me more bothered is that even though I've gone through the game 3 times -- nobody really looks like the murderer. Of course, I can make educated guesses; but each play-through has negated the possibility.
The first time I played, one character -- after going mad -- seems to have gone on a murderous rampage. Well; the protagonist didn't survive getting axed.
The second time, while the protagonist was examining a corpse, he got stabbed and didn't see his assailant. I assumed it was the same murderer as the last time I played the game.
The third time, the protagonist was again back-stabbed (elsewhere) and only saw the silhouette of the murderer. This time, though, the murderer from the first time I played the game was already dead. Doing a bit of arithmetic, I have to assume that one character pretended to be dead (in this case I think I know who -- but then that would be messed up beyond belief). The other is the person who captured everyone and put them in the situation they are in. The first play-through revealed the old man (who assumedly captured everyone) as dead. I don't think anyone of the 9 captured players would actually had the chance to axe the old man.
Following that logic, there can have an 11th person on the ship (they are on what seems to be an abandoned replica of the Titanic retrofitted to become a prison)...
I want there to be an 11th person. It makes the story easier to digest. All the other characters seem well-intentionned (even the one that murdered the protagonist with an axe...). It would also make the death of the second character easier to digest (or else you have to assume that the murderer is one of the 7 remaining characters)
The first time I played through this game, I was glued to the screen. The second time as well. The third I rushed through it; but I never realized that I'd fail again. Is this game rigged to make us fail until the sixth and last try?
A warning of sorts first. 9 Hours, 9 Persons, 9 Doors is a puzzle game for the DS where things go bad. Horribly bad. There are deaths in the game. What follows is my thoughts into trying to figure out who did the murders -- given incomplete information.
Ignoring that the story is attempting to poison my mind with facts that could appear real, but probably aren't, I should see how much is real or fiction. The part about the Titanic's sister ships is real -- as is the idea that the ship was cursed -- I don't know about the predicted sinking in previously published fiction or whether there is any discussion (prior to the game) that Titanic was sunk on purpose and Olympic is really the Titanic... For all purposes, the warning at the beginning of the game should put my mind at ease: it's all fiction. Relation to any actual occurrences is purely coincidental.
What has me more bothered is that even though I've gone through the game 3 times -- nobody really looks like the murderer. Of course, I can make educated guesses; but each play-through has negated the possibility.
The first time I played, one character -- after going mad -- seems to have gone on a murderous rampage. Well; the protagonist didn't survive getting axed.
The second time, while the protagonist was examining a corpse, he got stabbed and didn't see his assailant. I assumed it was the same murderer as the last time I played the game.
The third time, the protagonist was again back-stabbed (elsewhere) and only saw the silhouette of the murderer. This time, though, the murderer from the first time I played the game was already dead. Doing a bit of arithmetic, I have to assume that one character pretended to be dead (in this case I think I know who -- but then that would be messed up beyond belief). The other is the person who captured everyone and put them in the situation they are in. The first play-through revealed the old man (who assumedly captured everyone) as dead. I don't think anyone of the 9 captured players would actually had the chance to axe the old man.
Following that logic, there can have an 11th person on the ship (they are on what seems to be an abandoned replica of the Titanic retrofitted to become a prison)...
I want there to be an 11th person. It makes the story easier to digest. All the other characters seem well-intentionned (even the one that murdered the protagonist with an axe...). It would also make the death of the second character easier to digest (or else you have to assume that the murderer is one of the 7 remaining characters)
The first time I played through this game, I was glued to the screen. The second time as well. The third I rushed through it; but I never realized that I'd fail again. Is this game rigged to make us fail until the sixth and last try?
Subscribe to:
Posts (Atom)