Saturday, December 13, 2014

Baby monitor antenna fix

Our three year old son woke up early one morning this week. Before my wife and I were able to wake up, he had already somehow snapped the antenna casing off of his sister's baby monitor on the nightstand.

Through the course of the morning, the casing became lost in the shuffle. It's either in the garbage or somewhere in the house behind a heavy piece of furniture. I waited a few days to see if it would  turn up. For all I know it's on another planet by now. This morning I decided to make an attempt at covering up the fragile antenna wire. Some hot glue and an old pen seemed to do the trick. Here's a video of the fix:

Pretty much anything would have worked fine for fixing this, as long as it didn't conduct electricity. Conductive materials would attenuate the radio signal and decrease the range of the device. I had even considered hot gluing the antenna wire to a piece of wood, but I think this solution will make my wife happier.

This is the second time I've written about fixing baby monitors. In my other post about a different baby monitor I fixed a bad power port. The first fix was much tougher than this cheap pen trick.

If you've been following my videos or blog for a while, you might notice the antenna wire looks like a tiny coaxial co-linear. The size of the segments looks about right for the higher frequencies these monitors use. Here's an old video of me building a co-co antenna to capture ADS-B traffic. That was a fun project that worked, but I never ended up writing much about it. There's already great resources on the Internet about that if  you're interested in ADS-B and I didn't add much to what others have done.

Tuesday, December 9, 2014

Building strings in Python

The Saturday morning Python Christmas tree was fun and brought up a few interesting questions. A friend, Chris, made the comment that building strings as a list and then joining is more efficient than concatenating as you go along (like I did). I'm sitting in a room waiting for new tires to be placed on my truck, so this is a great little problem to take a look at.

Here's the code in question:

We build each line of the tree by concatenating strings together. This is a common thing to do and worthy of closer examination.

Here's an example of what I did in the Christmas tree code:
string = "" # start with a blank string
for _ in xrange(i): # make a loop
    string += " " # for each iteration of the loop, redefine the string

Here's what I think Chris recommended:
appendlist = [] # start with an empty list
for _ in xrange(i): # make a loop
  appendlist.append(" ") # append to the list
string = string.join(appendlist) # join the list into a string

As a first step, I wrote each of these and timed them using the Linux time command. By just picking random sizes of strings and timing the results, it seemed like my version was faster.

I then used Python's cProfile module to take a closer look, but wasn't able to discover anything useful with it. Plotting the two methods over a range of string lengths seemed like a logical next step and ended up making things much more clear. With a timing decorator that wrote results to csv files and another loop to iterate over a range of string lengths, I was able to create the data to make this chart:

It appears that "append as you go" does outperform "build a list" up until a point. The erratic behavior of appending to larger strings probably has to do with how memory is allocate for strings vs lists. Lists are made to grow smoothly, while strings are more difficult to allocate memory for because growing them in this manner isn't something that happens often. Even though strings can be abstracted as a list of characters, they aren't the same thing according to this. All that said, if your concatenating a string that's under 6 million characters (even on my little XPS12 laptop), it seems there's no real benefit to either method.

The work on my truck is complete, so I have to end this post. Maybe I'll pick this back up some other time and try it on different computers. If you end up looking at this, share your code or thoughts on the github repository.

Here's the code I used to generate the data for the chart which I made with OpenOffice Calc:

(thanks reddit user dangerbird2)
The better performance of += operations can be explained by optimizations in the CPython compiler. This might not hold true for other compilers (but probably does). However, the Python Style guidelines recommend against relying on compiler specific optimizations. So it's still good form to use list based string concatenation.

There's also a great reference to an article by Spolsky with a joke about a painter that illustrates the problem we'd expect to see by concatenating strings poorly.

Here's the article:

Here's the joke:
This code uses the Shlemiel the painter's algorithm. Who is Shlemiel? He's the guy in this joke:
Shlemiel gets a job as a street painter, painting the dotted lines down the middle of the road. On the first day he takes a can of paint out to the road and finishes 300 yards of the road. "That's pretty good!" says his boss, "you're a fast worker!" and pays him a kopeck.
The next day Shlemiel only gets 150 yards done. "Well, that's not nearly as good as yesterday, but you're still a fast worker. 150 yards is respectable," and pays him a kopeck.
The next day Shlemiel paints 30 yards of the road. "Only 30!" shouts his boss. "That's unacceptable! On the first day you did ten times that much work! What's going on?"
"I can't help it," says Shlemiel. "Every day I get farther and farther away from the paint can!"
If you ever hear the term "Schlemiel the Painter algorithms" this is what is being referenced.

Sunday, December 7, 2014

Leather axe sheath

Tonight I made a sheath for the axe I posted about a few days ago. Here is a picture of the completed project.

Below is a list of supplies to do this type of leather work. It's fairly straight forward once you have the basic tools and doesn't take very long for small projects like this.

Here's the steps I took:

  1. Draw your design on the leather with a pencil and cut it out.
  2. Use a hollow punch to make a hole for the first rivet. Secure the first rivet before doing the rest, this will keep everything aligned.
  3. Draw a line where you want the stitches, then follow the line with the leather stitch hole punchers.
  4. Follow the directions include with the sewing awl to insert the threads and tie it off.
  5. Place grommets.

Some lessons learned:

  • Placing the rivets before sewing was a good idea. It would be difficult to keep everything straight without them.
  • Wherever possible, leave extra leather so that the pieces can be trimmed together after the project is complete.

Although I've horded leather scraps for years, I used this stuff from Amazon and it worked fine.

Leather stitch hole punchers (my name for them). They look like this:

A sewing awl. They usually come with string.

Some small rivets.

Small gromets.

A small hollow punch set, like this. I got mine at Harbor Freight for slightly less, quality of steel isn't a big deal since we're just punching leather.

Oil to protect the leather.


Saturday, December 6, 2014

Python Christmas tree

I woke up this morning and meant to clean my office. But I ended up drinking coffee and writing this program to avoid doing that.

It works, and I learned how to record my desktop to show an animation I created by looping it in a bash command. But there are several places it can be optimized. Can you spot them? Comment on the youtube video if see the places for improvement.

# Prints a christmas tree on the terminal made up of ascending and descending integers
# 2014
import sys
import random

size = int(sys.argv[1]) # first argument is an integer which is the height of the tree
probability_green = .7 # how much of the tree will be green vs a random ornament

class colors: # colors
    purple = '\033[95m'
    blue = '\033[94m'
    green = '\033[92m'
    yellow = '\033[93m'
    red = '\033[91m'
    end = '\033[0m'
ornaments = [colors.purple,, colors.yellow,, '']
def decorate(s):
  if random.random() > probability_green:
    color = random.choice(ornaments)
    return color + str(s) + colors.end
    return + str(s) + colors.end
for i in range(1,size+1):
  line = ""
  for s in range(i, size): # this will loop over each digit left
    for c in range(0,len(str(s))): # prepend a space for each character of each digit
      line += " "
  for j in range(1,i+1):
    line += decorate(j)
  for j in range(i-1,0,-1):
    line += decorate(j)
  print line
trunk_length = 3 #TODO: if this wasn't a joke I'd make this an argument
for i in range(0, trunk_length):
  line = ""
  for s in range(1, size): # this will loop over each digit left
    for c in range(0,len(str(s))): # prepend a space for each character of each digit
      line += " "
  print line + "00"


 Getting in the spirit, a friend (Sage) sent me this bash version a few hours after I posted this.

to run: ./ 10

declare -a a=('.' '~' "'" 'O' "'" '~' '.' '*')
[[ $# = 0 ]] && s=9 || s=$1
[[ $s -gt 5 ]] || s=5
for (( w=1, r=7, n=1; n<=$s; n++ )) ; do
  for (( i=$s-n; i>0; i-- )) ;  do
    echo -n " "
  for (( i=1; i<=w; i++ )) ; do
    echo -n "${a[r]}"
    [[ $r -gt 5 ]] && r=0 || r=$r+1
  echo " "
echo " "

Update 2:
A new post to follow up on concatenating strings in python:

Sunday, November 30, 2014

Another axe handle

I found an axe head that was just a little too large for any of the pre-fabricated axe handles I could find for sale at hardware stores. I was committed to saving it from the scrap pile as soon as I saw it, but it's been sitting in my garage for the better part of a year for lack of the right piece of wood. I was recently able to find a satisfactory piece of hickory to make a new handle from and accomplished the task over two days this last week. Here are some pictures of the build.

Of course I took it out immediately and started hammering on a fallen tree. I was confident in my craftsmanship, but it felt good to just feel the solid thunk of the axe into the wood and feel that the shape and fit were as good as they looked during construction. In one of the pictures is a previous axe I restored with about an overall weight of 5lbs, it feels like a feather compared to this new monster. This new axe is HEAVY coming in closer to 8lb overall weight with the much larger head and thicker handle. It is a lot of steel and wood to swing through the air. I imagine it will be great for splitting. Not that I get much use out of my outdoor tools where I live, but it's nice to bring tools like this back to life. Something tangible to hold up as a completed project always feels great.

When I brought the axe home I put on the first coat of boiled linseed oil. There were other oils at the shop, but it was worth waiting the few days to do the right thing.

Update: A few weeks later I made a leather sheath for this axe. Post here

Saturday, November 29, 2014

Mean people fail (2014)

Children and technology

Parenting rant.

Some of the junk people are writing about children and access technology are perfect examples of why activists should seek consult before interpreting scientific research. Contradictory research findings by an army of grad students studying the soft (pseudo) sciences are not a basis for the sound raising of children. Why do I say pseudo science? Because I've always enjoyed and agreed with this Feynman rant.

The "studies" linking access to technology to this malady or that malady and the articles attempting to summarize or use them as a call to action are just silly. I don't believe they are malicious, just ignorant and misguided. I refuse to even link to them here because I don't want people receiving attention for this type of behavior. We can only speculate as to how they can divine and attach to such rigid certainty about their conclusions that they are ready to scream for legislation or world wide bans on this or that random technology to x random threshold. 

Plausibility alone is not a criterion for accepting speculative tales, but enough people just run with this to make it perpetuating. Here's a classic paper on the topic of something called adaptationism in biology. To paraphrase the topic of the paper, they poke fun at biologists that identify some trait of an organism and jump to conclusions about why it makes sense from an evolutionary perspective. The problem becomes worse when considering phenomenon like citogenesis. Randall Munroe explains:

Now, that said, I certainly monitor what my young children watch (avoiding violence and media that I feel teaches the wrong lessons), but I'm excited to see him grow up with technology I didn't have. Already he amazes me every day with his aptitude for taking advantage of the tools and what he pays attention to as he tries to wrap his brain around bigger concepts. Every day we have thoughtful conversations that are really amplified by the other things he is learning. I'll be getting him his own tablet as soon as he is responsible enough. I don't know when that is yet, but probably soon. Until then I don't deny him access to devices unless there are externalities such as bed time, dinner, etc.

So where do parents go wrong with technology? I suspect, as with many things it's complacency. We are all guilty of it to some extent, whether it's because we get lazy or are focusing on something else like our careers. You'll hear terms like "the electronic babysitter". This is funny (and, honestly, sometimes true), but all too often I believe people just throw the towel in and give up. Ignoring the children's development or blaming your conflicts with them on factors out of your control are recipes for disaster. I believe that to be a good parent you can't make excuses or give up. You constantly need to deliberately detect, approach, and overcome where you might be going wrong. But first and foremost you need to let the child know you love and care for them and that you're acting in their interest. Never give up and have the humility to adjust when you might have been wrong. ...oh, and make them laugh while you mentor them. Approaching with love really means with love, not an iron fist.

That's the end of this rant. I'll come back to it in a few years and see if I feel the same way.