Monday, April 28, 2014

Some Surprises from Day 1

Of all the things I didn't expect to learn with the 'living below the line' challenge, the most surprising was how good the food tasted on Day 1. Obviously, I'm lucky I can cook with safe and sanitary food and water, that many of the 1.2 billion people living on $1.50 a day don't have access to. And it's a choice for me, so I'm sure if I spent 100 consecutive days eating the same thing it would lose its appeal. But still...

When I was shopping I noticed any type of prepared food would be impossible to buy. We don't buy a lot of prepared foods, but we do buy some. Cereals, yogurts, tofu, bread, etc. all counted as prepared foods. So I was kind of expecting to choke down the meals for 5 days since the ingredients were the cheapest ones I could find at the supermarket. But my experience was the exact opposite.

Breakfast was a bowl of oatmeal with brown sugar and 1/2 a banana. It's hard to describe how good, that actually tasted! It tasted like a fresh loaf of banana bread straight from the oven.

And lunch was a quarter of a homemade loaf of bread ( actually straight from the oven ). I had enough in my budget for a tablespoon of peanut butter, and it was undoubtedly the best peanut butter sandwich I've had in my entire life.

Dinner was the classic Cuban dish with the politically-incorrect name of Moros y Cristianos ( Moors and Christians ). It's rice and black beans, and I enjoyed it with a fried egg on the side and a bit of Sriracha sauce. I've probably paid 10x the cost of it at some restaurants and not had 1/10 of the pleasure eating those meals.

I'm sure this wasn't the point of the challenge, but it was a nice benefit :-)

Sunday, April 27, 2014

Preparing for Week of 'Living Below the Line'

Preparing for five days of 'Living Below the Line' to raise funds for Heifer International ( https://www.livebelowtheline.com/me/revanbus ). I'm not sure where the idea came from, but it seems great! Instead of running a marathon or something unrelated to the charity, people try to live below the line of poverty for five days. This year it means spending less than $1.50 a day on food.

The challenge starts on Monday, so this weekend I spent some time menu planning and shopping. Even though 1.2 billion people around the globe live on $1.50 or less, I didn't realize what that number meant until I started to calculate the food I could buy with that.

Two really surprising conclusions from this weekend's menu planning were:

  1. Sadly, I spend more daily on coffee than 1.2 billion people have to spend for their entire day :-(
  2. The incredible impact that an organization like Heifer International must have on people's lives. After spending a day calculating how to squeeze every penny from my weekly budget, it made me realize the impact a gift of a goat or even a chicken would have on a family. The free milk or eggs must make a huge difference.

So anyways... after a lot of wrangling and penny-pinching, it looks like the dinner menu for this week is (drum-roll please :-)

  • Arroz Cubano - Fried eggs and tomato sauce over rice
  • Lentils with potatoes and peppers
  • Pasta with spaghetti sauce
  • Black beans and rice with peppers
  • Fried rice with eggs and peas
Breakfast is pretty much oatmeal with banana and brown sugar every day. Lunch is homemade bread (maybe with peanut butter... I still have to crunch the numbers...) And maybe.. possibly... I can fit in a cup of drip coffee or a tea bag for around $0.16 to $0.18 . ( If I can fit that into the budget any day, it's probably going to taste like the best cup of coffee I've ever had in my life :-)


Sunday, September 22, 2013

My Micro Green Roof - Planning

Last winter a huge wind storm, with gusts of up to 75 mph, passed through my town knocking down trees and power lines. I remember hearing the wind howl and watching the hanging lights inside gently swinging back and forth. One casualty was my garden shed's roof, which lost a few rows of shingles. By July I still hadn't repaired it, but was reluctantly preparing to buy some asphalt shingles from Home Depot and repair it.

Before buying the supplies, though, I spotted a book called Small Green Roofs. The authors' premise is that while big green roofs for houses or offices are expensive and complicated, any idiot with a hammer can build a small green roof. "Hey, I'm an idiot with a hammer," I thought to myself, so I kept reading. Although, the book wasn't a step by step manual, it still had all the information I needed. I guess the field is too new and once they can write step by step instructions, it won't be as interesting.  So I decided as long as I needed to fix my roof, I would try to make the project interesting.

Two initial concerns were with the wind and the fire protection of a green roof. As I mentioned above, the Caribou Valley in Nederland gets some strong winds. And unfortunately, wildfires are a yearly danger here, too.  I was pleasantly surprised to learn a green roof can be more resistant to wind than a shingled roof because the roots can grow it into one big mat that can't be lifted by the wind. Also, since a green roof tends to be mainly rocks, dirt and succulent plants, one source said the fire risk is equivalent to a tile roof.

Project Planning
My first step was to assess the shed's roof and do some background research for my area. I drew out the following map of the roof :



Next I calculated the maximum load for the roof. The authors say "You can have fun with all of the other elements of a green roof, but you must make sure the roof does not collapse." I calculated out about 107 sq feet of area for my shed. Next, using the handy load chart in Small Green Roofs I realized that if I put up five inches of rock and top soil on the roof, I could have a maximum load of around 4500 lbs ( ~2000 kg ) when it got wet!

So I started checking out my shed to see if it could handle the weight. Once again I was pleasantly surprised. The guy we bought the house from had built a solid shed. The rafters were spaced one foot apart. The walls were solid wood made of stacked two by fours.

Still, I talked to my Dad who knows a lot about carpentry, and he suggested I reinforce the main beam going across and some of the rafters. He suggested getting a long 2 x 4 and using liquid nails to glue it to the current beam, then attach them together with screws.

Local Research
The authors of the book are located in England, but I'm in Colorado. Our climate is semi-arid, alpine with 17 inches of precipitation per year, while they receive about 33 inches. So I searched on local green roofs and found some excellent resources:
I thought my local weather wouldn't allow me to have a green roof, but I was surprised how flexible they can be. Even though my climate is totally different from the UK, it still can support a green roof. In fact the typical green-roof plants are selected because they can grow in harsh conditions in rocky, nutrient-poor soils. Many of the plants that fit the bill are alpine plants and sedums. To be honest, reading through a list of appropriate plants for a green roof is like reading through a catalog of the plants growing in my yard! ( More on this in a later post ).

The Carpentry
There really isn't a lot to say about this. For the box to contain the garden I just decided on some 1 x 6's of weather-proof wood. I attached these to the roof with angle brackets. I also decided to follow my Dad's advice and bought enough 2 x 4's to reinforce the rafters and main supporting beam. Altogether, the lumber and hardware ended up costing me just under $50.

The Design of the Waterproof Layers
One goal on this project was to complete it without breaking the bank. Even a small roof like this could have cost $1000 or more. I was shooting for something in the $300 range. This was still a lot more that the $50 or so asphalt tiles would have cost me at Home Depot, but hopefully the final result is nicer :-)

So for the waterproof layer I decided on an inexpensive pond liner from Amazon.com. Checking amazon.com now, I see they have a 10' x 13' pond liner for just $60. Unfortunately for me the square footage was good, but the dimensions wouldn't work for me. So I ended up buying some pond liner tape for $20 so I could cut apart the pond liner and tape it together to the size I needed.

The Design of the Soil
My initial plan was to take a few wheelbarrows full of dirt and rocks and dump them on top of my shed. But after my initial calculations, I realized soil and gravel might be enough to collapse even my bomb-shelter quality roof when it got wet. So I looked around at the different alternatives and decided to stick with a standard for green roofs -- lightweight expanded shale. It's a lightweight rock made by heating shale to high temperatures. It's also pretty cheap. I could have gotten it in bulk from a local manufacturer for only about $50 / ton. Unfortunately hiring a construction truck to get it to my place would have cost me way more than the cost of the shale :-(

I also looked into zeolite which has a lot of great advantages for a green roof, but since I didn't own a truck and the guy I was talking to had it marked up to around $400/ton, I ruled that out as well.

So I paid a guy with a pickup truck to go to a building supply center in Longmont and pick up the ton and a half I needed. I decided on a mixture of 70% shale with 15% compost and 15% peat moss, ( according to the information I'd found from the sources listed above ). The cost of the shale and transport ended up being $200.

Plants
I thought this would the easiest part of the roof design process. I went to my local nursery and told them I was looking for recommendations for green roof plants. The response was along the lines of "Oh cool -- I have no idea what to recommend." They thought the green roof was a great idea, but apparently they didn't get a lot of business from green roofs and had no idea what to recommend. They suggested I visit the Denver Botanic Garden's green roof, which was a great recommendation because I could see the plants and create a list there and then go back and buy them. Ultimately I spent about $90 on plants for the roof.

Conclusion
Overall, I've been pretty happy with the design of the shed roof, although if I could go back there are some things that I'd like to change:
  • Use natural substances - I used pressure-treated lumber and a PVC-based liner for the roof. Ideally I'd have liked something that could be recycled. When the shed is at the end of its useful life, both the lumber and the liner will have to be thrown away. All of the hardware can be 100% recycled or re-used. And the shale can be mixed into the yard soil to improve the drainage. It's just the liner and the boards that ultimately don't have anywhere to go.
  • Use local plants - Since I live at around 8,500 feet a lot of the alpine plants that do well on a green roof also grow in my yard. In retrospect I should have saved myself $90 and just selected wildflowers and ground cover from my yard rather than buying plants at the nursery. One of the methods they mention in the book for populating the roof with plants is just to let natural plants take over. In retrospect I probably would have been better off doing this.



Tuesday, July 3, 2012

Step 7a - The Comments Object

I haven't posted anything for awhile since I had a crazy/fun work project going on. I learned four new tools/technologies: RabbitMQ, HTML5 drag and drop file uploading, Phil Sturgeon's CodeIgniter REST libraries and PostGreSQL. It was fun, but limited my time for the Go Reader :-(  But since it's winding down, I've got more free time to devote to finishing this up. 

Go Comments

Every stone in Go means something. Sometimes the difference of a single line can have a completely contrary meaning. If black plays on the third line, she may want to create a safe group. On the fourth line she may be testing the waters and be prepared to run.

As a beginner, I find it difficult interpreting the meaning of each play. Fortunately, there are a lot of games out there professionals and strong amateurs have commented on. For this post I'll talk about displaying these comments.

Programmatically, the challenge in displaying the comments is:
  • The commented area shouldn't be covered, so the user can see the comments and the stones referred to at the same time
  • The commented stone can appear just about anywhere on the board, so the comment must position itself in different places, so as to not overlap the stone
  • It's easy to figure out a single stone mentioned in the comment, but hard to know what other stones are involved. So there is a danger of accidentally overlapping stones you want the user to see
Some ways of addressing these problems are to:
  • Have semi-transparent comment balloons, so stones are visible underneath the comment
  • Allow the user to close the comment balloon after reading it
Since there is only one comment at a time, my first attempt was to display it on a single canvas on top of the other ones. I thought this would work well because HTML5 canvases are transparent. After my first test, I realized this approach wasn't going to work, though. It came out looking like this:


( The left side is the comment object. ) I found out that when you draw text into the canvas object it doesn't wrap the words :-(

So there seemed to be three obvious solutions:
  • Add in line breaks into my stored comments and perform a carriage return in my code when I detect those
  • Use a JavaScript function to automatically calculate line breaks
  • Give up the idea of a canvas and use a div instead, which has the word-wrap built in
The last one seemed like the simplest solution. Since there's already a wheel out there, re-invent it? Although it would have been more interesting to use a canvas, it seemed the wrong tool for the job. Besides, it'd be good to work on my paltry CSS skills for a bit.

Drawing the Bubble

The comment bubble ended up being just a plain div, with the following CSS style:

#comment_div {
    color: black;
    background-color:#FCF6CF;
    opacity: 0.5;
    border-radius: 20px;
    border-color: black;
    border-width: 2px;
    border-style: solid;
    padding: 20px;
    z-index:1000;
    overflow:hidden;
}

The text color is black. The opacity is 50%. I gave it some curved corners with the border-radius attribute. The padding ensures the text doesn't go right up to the edge, and the z-index field ensures the div floats on top of everything else.

One difficult decision was the choice of overflow:hidden vs overflow:auto. If I had set the div's style to overflow:auto, it would have scrolled the content. with overflow:hidden it just chops the text off at the end of the div. I was worried that on a touch interface the overflow:auto would be difficult to manage. Maybe a control that expands the comment ballon to full screen if there is overflow will be good for the future. 

Not Obscuring Stones

In order to avoid obscuring any important stones on the board, I employed three methods:
  1. As I mentioned above the comment bubble is semi-transparent
  2. I position the bubble away from the main stone mentioned
  3. If the user clicks/touches the bubble it disappears
For #2 it took awhile for me to realize just a simple algorithm will work to position the bubble. For the display method, all I need to do is send it the position of a stone that is being referenced in the comment. Then I calculate the quadrant that stone is in, and put the comment bubble in the opposite quadrant.

For example, if the mentioned stone is in the top, right then the comment bubble is placed in the bottom, left. This seems to work fine.

Here is the code for the "algorithm" :-)


 display: (stoneX, stoneY ) ->

  #figure out the quadrant of the referenced stone
  widthLoc = if stoneX < 10 then 'left' else 'right'
  heightLoc = if stoneY < 10 then 'top' else 'bottom'

  #position the comment in the diagonally-opposed quadrant
  x = if widthLoc is 'left' then @quadrantWidth else 0
  y = if heightLoc is 'top' then @quadrantWidth else 0
  
  #move the div to the correct position over the board
  position = $('#goBoardImage').offset()
  position.left = position.left + x
  position.top = position.top + y
  $('#comment_div').css(position)
  $('#comment_div').show()

I know I could have reduced the "algorithm" from 4 lines down to 2. However, it's not really a computation-heavy area of the code. And I like it, if I can just walk up to it later and figure out what it's doing at a glance.

Here's What it Looks Like
I figured I could use the first comment bubble to provide initial instructions:

And here's the comment bubble automatically positioning itself in a the quadrant diagonally-opposite from the first stone played:





What's Next

Since I'm already in tl;dr - territory with this post I'll finish off the comment object in the next post. I'll put in how I modified the JavaScript SGF parser to pull out the comments and added in a pointer from the comment to the mentioned stone.

Thursday, April 12, 2012

Step minus 1 - Re-Writing Everything

I don't know if this step is forwards or backwards... A colleague at work had been posting about CoffeeScript . It's a scripting language that compiles into JavaScript. Although skeptical, I tried it and absolutely fell in love with it! So I rewrote everything.

If you know Python or Ruby, CoffeeScript is a more natural way to program than JavaScript. And the code it generates is way better than (my crappy) JavaScript code. Even with the relatively small codebase I was trying convert, I still found 4 major JS coding errors in the conversion process. Any one of those would have caused a long, painful debugging session. And CoffeeScript fixes a lot of JS problems like that auto-magically!

So I decided to re-write everything. In my limited experience there are three ways to rewrite code:
  1. Don't. If everything is already working, just use the code you have as modules and don't worry about what's inside those black boxes.
  2. Make small changes, test them, make some more changes, test them, etc. Otherwise known as the 'smart approach'.
  3. Make a huge amount of changes in a language you've never used before and then spend the next few weeks tracking down the bugs while simultaneously trying to learn the new language. A.K.A. the fun approach :-)
Obviously, I chose #3.

My experience with CoffeeScript was pretty straight-forward:

Install
The install with node.js's npm was super-easy, and well-documented:

npm install -g coffee-script

Set up

There are a lot of ways to run CoffeeScript. The method I chose was to have it monitor all of the JavaScript that I was writing and whenever it detected a difference it would automatically compile that script. The terminal window showed any compile-time errors after each save.

Another option I liked was the -join option. It takes all of the CoffeeScripts you specify and outputs them into a single file. So in order to start using CoffeeScript I would just cd to the correct directory and issue the following command:


coffee --watch --compile --join uno.js *.coffee


I had an individual coffeescript file for each object and it all compiled into a single JS file 'uno.js'.

Found Errors

Some of the biggest errors CoffeeScript found and fixed automatically for me were in the board module where I was accidentally declaring some variables as global. ( Note to the JavaScript language designers: global variables by default? Seriously? )

My Toughest CoffeeScript Error to Debug

The actual re-writing didn't take much time... except for one bug. I was calling the _drawStone method for one class. The method didn't take any parameters so I wrote the call as:

@_drawStone

( The @ symbol is like the 'this' keyword. So that would be equivalent to this._drawStone )

This might initially seem like an odd decision, however, it kind of makes sense because the parentheses are optional for function calls with parameters, so I left them off of the parameter-less call as well. However, it should have been:

@_drawStone( )

The main problem was that the CoffeeScript compiler didn't raise this as an issue. No warning, no runtime, error, nothing... I checked the line and it compiles into:

this._drawStone;

What does that even mean? It creates a property but it has no value assigned to it. Why would anybody do that? I lost 20 hours of my life tracking this down :-(

The only thing that made me feel any better was that I wasn't the only person who ran into this:

https://github.com/jashkenas/coffee-script/issues/514

https://github.com/jashkenas/coffee-script/issues/1412

I may enter this as a request to raise a warning during the compile phase and see what they say...

Edit: Before opening the request I did my due diligence and found out this had been opened before ( https://github.com/jashkenas/coffee-script/issues/988 ) The comments mentioned why this would be such a tricky problem to fix... I may just change my coding style and always use parentheses, even when they're not required.

A Great Resource

If you want to learn CoffeeScript one of the best resources is Alex MacCaw's great book The Little Book of CoffeeScript .

Sunday, January 29, 2012

Step 6 - The Stone Image

A Better-Looking Stone

There are a lot of enjoyable experiences in playing Go on a real board. There is the polished, wooden pine board.  There's the feel of the stones and the small 'click' they make as they are played. The stones drawn in the previous posts were just flat disks that didn't recreate the image of a real go board. In order to make the stones a bit more evocative of a real Go board, let's add a highlight and shadowing to make them more three-dimensional.

One of the great things about the HTML5 Canvas element is its flexibility. If you can imagine an image, there must be a way to draw it. One perfect effect for creating a 3-D stone is the radial gradient effect that can create a realistic highlight for the stone.

To use a radial gradient with jCanvas you just create a gradient color and draw objects with it. It's kind of like creating a gradient color and adding it to your palette. So instead of drawing a stone with black or white, you draw it with your custom-made radial gradient color.

The radial gradient is built by assuming there are two circles of different colors and the gradient flows between them. The x1,y1 and x2,y2 are the center points of the two circles. The r1 and r2 values are the radii of the circles. C1 is the color of the first circle and c2 is the color that it gradually flows into.

After playing with the values for awhile, I placed the center points of the circles to the upper-left of the center point of the main circle. I started with a small radius of 2 for the smaller circle and made the second circle match the full radius.
// set the begin and end colors for black
var beginColor = "#4C4646";
var endColor = "#000000";

// figure out the color of the piece
if(theMove.charAt(1)== "W")
{
 // begin and end colors for white
 var beginColor = "#ffffff";
 var endColor = "#DDDDDD";

}

// calculate the radius so it is half of the line spacing minus one pixel so stones aren't on top of each other
var theRadius = (this.lineSpacing / 2) - 1;

var radial = $("canvas").gradient({
          x1: theConvertedValue.x-(theRadius/2), y1: theConvertedValue.y-(theRadius/2),
          x2: theConvertedValue.x-(theRadius/2), y2: theConvertedValue.y-(theRadius/2),
          r1: 2, r2: theRadius,
          c1: beginColor,
          c2: endColor
          });


After looking at the white piece, it looked really plastic-like. So to change this, I added a shadow blur around the edge of the piece. This was accomplished by adding the following attributes when the stone was drawn:
   shadowColor: "#000",
   shadowBlur: 2,


It looked better, but still not quite realistic. So finally I added just a subtle drop shadow on the lower-right side:
shadowX: 1, shadowY: 1,


So the final drawing routine was just:
// use jCanvas to draw the piece
$("canvas").drawArc({
   fillStyle: radial,
   shadowColor: "#000",
   shadowBlur: 2,
   shadowX: 1, shadowY: 1,
   strokeWidth: 1,
   x: theConvertedValue.x, y: theConvertedValue.y,
   radius: theRadius
 });
}


And so now the new stones look like this!:


Saturday, January 21, 2012

Step 5 - The New and Improved Board Object!

The first step in implementing the UML diagram is to create the board object.

The main changes I made to the board-drawing code were:
  1. Encapsulating the code inside a JavaScript object
  2. Removing the code for drawing the wood grain on the canvas
  3. Modifying the code so it would support multiple screen widths
The first step was pretty easy. Just like the game object, all it took was to define the object and then instantiate it in the code. In the constructor, I pass in the padding (in pixels) around the board, the width (in pixels) of the board, and the number of lines. Although currently it only supports 19 x 19 line boards.

The constructor looks like this:

// the code that draws the board encapsulated as an object
function Board( padding, width, lines )
{
	this.padding = padding; // padding around the board
	this.width = width;	// width of the actual playing area
	this.lines = lines;	// number of lines on the board 
	this.lineSpacing = (this.width)/(this.lines -1 ); // the spacing between the lines
	this.starPoints = [";S[dd]",";S[jd]",";S[pd]",";S[dj]",";S[jj]",";S[pj]",";S[dp]",";S[jp]",";S[pp]"]; //star points for a 19 x 19 board in SGF format

with the rest of the object being the methods drawBoardLines( ), sgfToXy( ), and drawPiece( ). The sgfToXy( ) and drawPiece( ) are going to disappear when I define the Stone object. Right now it's not 100% matching the UML diagram, but we're getting there :-)

Initially, when I created the board object, the callback wasn't working to start drawing the board lines. Since I'm just learning JavaScript I figured it had something to do with the way I was defining it as this.drawBoardLines( ). I planned to change the design so the board and stones were on separate canvases on top of the board image. Since the callback wasn't working, I thought it would be better to invest my time learning how to layer canvas elements than getting the callback working.

Since the canvas is transparent, this part just required some simple jQuery and CSS to position the canvas on top of an image of the board. It just took some googling and experimentation to figure it out. In go.js the new code looks like this:

// wait until the page is loaded to size and draw the board
$(document).ready(function()
{
	var thePadding = 10;
	var theLines = 19;
	
	// calculate the size of the board
	var boardWidth = Math.round($('#gameSelectBtn').width());
				  
	// after we know the width of the board we can instantiate a board object
	theBoard = new Board(thePadding, boardWidth, theLines);
	
	// next we set the image and board lines to the same value
	$('#goBoardImage').width(boardWidth +    (thePadding * 2));
	$('#goBoardImage').height(boardWidth +   (thePadding * 2));

	// NOTE: need to set width and height with .attr because $('#goBoard').width() will stretch the image and not 
	// change the actual size of the canvas
	$('#goBoard').attr("width", boardWidth + (thePadding * 2));    
	$('#goBoard').attr("height", boardWidth+ (thePadding * 2));
				  
	// thank you stackoverflow.com for the code to position the canvas over the top of the image of the board !!
	// http://stackoverflow.com/questions/683339/how-do-i-find-the-absolute-position-of-an-element-using-jquery
	var position = $('#goBoardImage').offset();
	$('#goBoard').css(position);
				  
    // finally, draw out the lines on the board
	theBoard.drawBoardLines();
});

Lines 33 and 34 position the canvas over the image. And Lines 22-29 resize the board after the page has loaded. One interesting thing is that if you use the .width() and .height() jQuery functions it will stretch the canvas instead of resizing it. So if the canvas originally started out as 100 x 100 pixels and you set the width x height to 400 x 400, you would still have a 100 x 100 canvas, but it would be displayed four times the original size!

The last step was to remove all of the hard-coded values in the original board code. Hard-coding values is a really bad practice, obviously. However, I like to code by making lots of small, fast refactorings, instead of a lengthy, massive push to get it all working perfectly right away.

All of the hardcoded values can be calculated from the three parameters initially passed in. The slightly tricky part was dynamically resizing the board based on the initial screen width. Eventually the board will be a property of the Player object. For now I created a global variable to hold the board object, but I couldn't instantiate it until after the page was loaded because I needed to know the page width. So I created the variable theBoard and assigned it 'null'.  Then later I assigned the instantiated board object, once I knew the page width:

var theBoard = null; // need this as a global variable but can't instantiate until after the page is loaded
...
// after we know the width of the board we can instantiate a board object
theBoard = new Board(thePadding, boardWidth, theLines);

The final change was a small improvement in the routine drawing the star points. The routine I had would work for a 19 x 19 board. If the board size changed in the future, the number and position of the star points would change. Since I had to re-write this method anyway to get rid of the hard-coded variables, I figured I could leverage the sgfToXy( ) method and use that to draw the star points.

In the future this will make it easy to add a multi-dimensional array indexed by the number of board lines which provides the appropriate star point pattern. So a 19 line board would be 'this.starPoints[19][ ]' and a 9 line board would be an array like 'this.starPoints[9][ ]'.