Bubbles and triangles

Lately, I’ve been looking at more information visualizations, and it’s not been said enough that simple geometry is often ignored.

Media_httpinfobeautif_emael

Often times, I’ll see visualizations like this, where bubbles are employed to visually compare different records. It seems likely that people judge and compare difference in size by area. However, the artist/designer makes the mistake of mapping the data to the radius instead. This doesn’t work for circles because of your old 4th grade math, stating that A = pi * r^2, where the area doesn’t increase linearly as a proportion of the radius.

For the record, it’s done correctly here in the visualization above, as far as I can tell.

Here, the designer decided to use triangles. If he mapped the data to the height of the triangles, that’s fine, because for triangles, A = 0.5 * b * h, and hence area varies in linear proportion to height.

However, looking at Hungary, the red triangle doesn’t seem quite a quarter of the black triangle.

Beyond that, for these two examples, I really see no reason to use circles or triangles. People are able to judge spatial difference much more easily, as opposed to size. It would have been far more effective to use bar charts and rectangles instead of shapes like triangles and circles. In my opinion, you only use that if the spatial x and y axis are already being used to convey other information already.

Practice coding faster

map_with_index.  Why is there no map_with_index in ruby?  Ends up it's because you don't need it.  You can simply do this:

1
2
3
4
["Two", "Birds", "In", "Hand"].each_with_index.map { |element, index|
  "#{element}: #{index}"
}
# => ["Two: 0", "Birds: 1", "In: 2", "Hand: 3"]

Even now, I'm learning things about Ruby.  The rabbit hole is deep.

Anyway, a post about learning how to code fast came across my desk.  I knew that I wasn't quite as fast as other coders, but I had always thought that I thought deeper on the solution.  But I think what he says makes sense.  I know that violinists slowly ramp up their speed to a point where they're almost making mistakes, faster than they'd actually play the piece to practice playing it at the correct speed.  Same with drawing.  The more you practice drawing faster, the better you get at being economic with your strokes.  So I figured I'd try the same with programming, since I've never done much of this type of exercise.

I decided to do the first Ruby Quiz, since I was most familiar with Ruby, and I should be able to do it quickly.  It took me about three hours, including reading the instructions, going on bathroom breaks, etc.  I think I should have been faster, and I noticed where I slowed down.  I found myself trying things out in irb a lot because I didn't know the exact behavior of some array and string functions.  Also, I spent some time in the beginning pondering how to structure it–should it be a class, or just a collection of functions, or should I extend the classes?  

I'm not thrilled about how it's structured, but it works.  Well, there's a small bug in there, but I'm going to refrain from fixing it.  It'll tack on another 30 mins.  The point of the exercise is that I can see what I need to work on.  I'll try again next time with the next ruby quiz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/ruby

class Encrypter
  private
  def value(symbol)
    return 53 if symbol == "A" or symbol == "B"
    return symbol.to_i
  end

  def triple_cut
    if @deck.index("A") > @deck.index("B")
      top_index = @deck.index("A")
      bottom_index = @deck.index("B")
    else
      top_index = @deck.index("B")
      bottom_index = @deck.index("A")
    end
    bottom = @deck[0...bottom_index]
    middle = @deck[bottom_index..top_index]
    top = @deck[(top_index) + 1..-1]
    @deck = top + middle + bottom
  end

  def count_cut
    count = value(@deck.first)
    @deck = [@deck[0]] + @deck[-count..-1] + @deck[1...-count]
  end

  public
  def initialize
    @deck = ["B", "A"] + (1..52).to_a.reverse
    # key the deck

  end

  def next_key
    jokerA_index = @deck.index("A")
    @deck.move(jokerA_index, jokerA_index - 1)
    jokerB_index = @deck.index("B")
    @deck.move(jokerB_index, jokerB_index - 2)
    @deck = triple_cut
    @deck = count_cut
    top_count = value(@deck.last)
    return [@deck[-(top_count + 1)]].to_alpha
  end
end

class String
  def keystream
    enc = Encrypter.new
    self.gsub(/[^A-Za-z]/, "").split("").map { |char|
      enc.next_key
    }.join
  end
  
  def segment_by(number)
    segments = []
    self.gsub(/[^A-Za-z]/, "").upcase.split("").each_slice(number) do |slice|
      segments << slice.join
    end
    (number - segments.last.length).times { segments.last << "X" } if segments.last.length < number
    return segments
  end

  def to_numeric
    self.split("").map { |char| char[0] - 64 }
  end

end

class Array
  def to_alpha
    self.map { |number| (number.to_i % 26 + 64).chr }.join
  end

  def move(from, to)
    element = self.delete_at(from)
    to -= 1 if (to < 0)
    self.insert(to, element)
  end
end

def merge_numerics(message, keystream)
  message.each_with_index.map do |segment, segment_index|
    segment.each_with_index.map do |message_number, char_index|
      keystream_number = keystream[segment_index][char_index]
      yield message_number, keystream_number
    end
  end
end

def codec(command, message)
  message_numerics = message.segment_by(5).map { |s| s.to_numeric }
  keystream_numerics = message.keystream.segment_by(5).map { |s| s.to_numeric }
  merge_numerics(message_numerics, keystream_numerics) { |m, k|
    case command
    when "encode"
      (m + k) % 26
    when "decode"
      (m - k) % 26
    end
  }.map { |segment|
    segment.to_alpha
  }
end

puts "Welcome to the Solitaire Cipher"
puts

# get the input
command = ARGV.shift
message = ARGV.shift
puts "You entered: #{message}"
puts "Output: #{codec(command, message).join.inspect}"

On to the new old thing

Ever since I quit my job at the lab 4 years ago to pursue a startup, I’d been fumbling around learning all sorts of things.  And though I had determination and persistence, I simply didn’t know a lot of things outside of coding.  Who wants this?  Why would they pay money for it?  Where do you find them?  How do you change your idea if it doesn’t work?  Going into it, I knew I didn’t know anything and that I’d learn, but I also didn’t know what I didn’t know.  

For the past year and a half, I’ve been with a startup that went into the YC program. So as much as I wanted to pursue my own ideas, I was advised to join up and watch other people and learn.  And learn a lot I did.  What to do, and what not to do.  And just seeing founder from other startups helped.  What their thought processes and attitudes about their line was work was.  Meeting role models are easier than reading about them, I guess.  

And yet, while I’ve been learning about things outside of code, I felt like I’ve been sailing downwind when it came to technical things.  Sure, I’d mess around with chickens flocking (which embarrassingly, I haven’t gotten back to), but for the most part, I was consumed by work.  Getting the tickets done and getting better at communicating with other team members.  

However, much of my creativity was sapped.  It was hard to fire up the editor afterwards and explore something new.  I have a whole list of things I wanted to dive into more deeply.  Haskell’s type system.  Erlang servers.  Spatial trees for Frock.  Arc language.  Potion language.  Prof Strang’s Linear Algebra lectures.  Visualizations and info graphics.  Mobile web apps.  3D printers.  And though I’ve dabbled in all of the above, it’s not yet been enough to satiate my cravings.  

But I have learned that it’s also a lesson in keeping things small and simple at first.  Much kudos to those working a full time job and are able to get a side project up and running.

This blog also suffered as a result.  I was afraid that the things I was learning outside of code might reveal too much about the internals of the startup I was with, so I just left nothing to chance.  I simply fell out of the habit of blogging about what I’ve learned, and as a result I feel like my writing skills have deteriorated.  

But now I’ve left the startup, moved to Mountain View, and I’m pursuing my own once again.  It’s not a secret what I’m working on, but I’d just rather talk about it in a separate post.  I’ve also started exploring other technical topics as well, as I hinted in the last post about Potion.  I’ll start finishing up the backlogged technical posts.

So for those of you that still are subscribed, well, thanks for your faith.  I’ll be writing more, and I hope you’ll be able to learn something from reading this blog as well.  Have a great holiday!

Playing with potion

For fun this morning, I cloned _why’s potion and started going through the tutorial.  After cloning it, I was able to compile it on my mac, and then I tried to run:

“hello world” print

and it seg faulted.  Boo.  So in case any of you are looking for a work around, this worked:

And looking through the source, I found the about function’s easter eggs.  Humorous.

1
2
3
4
1 times:
  about("_why") print
  about("stage fright") print
.