2016-11-19

Shitty Robot

Quick-and-dirty, rough-and-ready. I came up with an ugly and ridiculous-looking contraption that the Queen of shitty robots herself might approve of.

Here was the problem: where I live, there is only one switch to control the light in the staircase leading to the basement. You turn the light on before going downstairs. And it stays on until you come back upstairs, since there is no way to turn it off from below. What a waste of energy! Especially when people spend hours in the basement (don't ask)! It upsets me. I don't own the house, so I can't modify the wiring. The landlord is not keen on upgrading the place.

I knew what I had to do. To devise a clunky, inelegant solution to a simple problem. A remotely operated arm that flips the switch on and off. I thought of using a servomotor and a microcontroller. I also wanted to use an old TV remote control... but alas, it wouldn't work from downstairs (Infrared communications usually require a line-of-sight path). So I went for radio signals instead.

That's when the gods of serendipity smiled on me. I had ordered an RC cat toy for a different project of mine (More on that later). When I received the $5 gizmo, I realized that making turns is not an option: you can only drive straight and back. Boo. Silver lining: cheap RC parts!

The not-so-little bugger.

Then everything fell into place fast. I did not change any of the electronics, just removed some plastic things and added two lollipop sticks, one rubber door stop, one tea box, zip ties, the obligatory duct tape. Done.

2016-11-08

Philosophy Bit

Today, American citizens elect their new president. Coincidentally, an interesting thought crossed my mind. I was pondering over biology and evolution, but it applies as well to political systems, religious beliefs, software engineering, you name it:

You think the body's sole function is to keep the head alive? Wrong.
The body grew a head to increase its chances of survival. The head's duty is to protect the body.
But the head is betraying the body. The head dreams of getting rid of the body, of living as a pure spirit, forever, for its own sake.
The head thinks the body's sole function is to keep the head alive.

Bodies that grow heads will be used and betrayed.

2016-11-01

Hail to the Queen

Last night I've met with the self-proclaimed queen of shitty robots, Simone Giertz... inasmuch as watching someone's youtube channel counts as meeting them. I fell in love with her antics and goofy machinery. She might not be as technically savvy as Limor Fried, but she's quite the entertainer!

She inspired me to add some moving parts to my projects. I'm envisioning a mix of a video game and a toy... that would hopefully make me laugh as much as her videos! The player would use a "robot" to try to build a pyramid... or pick an object with a crane... or move a marble... but the game AU (Artificial Unintelligence) would get in the way and ruin their efforts when they least expect it. I giggle at the thought of a printed kitten picture popping out of nowhere (with a meow?) and pushing the marble or destroying the pyramid.

Oh, and this nutty Swede is turning 26 today, so happy birthday to her! :)

2016-10-31

Response Time

Years ago I cobbled up a web-based version of the timeless classic, the addictive video game Tetris. Now I'm starting again from scratch. Programming an AVR microcontroller makes the matter slightly more difficult/interesting. My motivation was to re-use the monochrome Liquid-Crystal Display of a twentieth century cell phone, the Nokia 5110.

Its bare-bones resolution of 84*48 sufficed for the tetraminos to look half decent. But the initial tests proved disappointing. There was a visible flicker as the blocks moved down the screen. I assumed it had something to do with the code. Perhaps storing the bitmaps in flash memory was too slow? Or some routines in the Adrafruit_GFX library sucked? I tried different things, without changing the outcome one bit.

I even tried with a different monochrome display. Exactly the same result. Then it hit me. The issue was not the software, but the hardware. In the datasheet of the second display, the response time is stated: 200 to 300 milliseconds. Pretty awful. It's the time pixels take to fully turn on or off. Meanwhile, a tetramino falling at 40 pixels/second has already traveled far. In consequence, the display is simply incapable of showing a sharp image at this speed. The response time should be at least five times smaller to make it enjoyably playable.

I learned that I cannot repurpose any display. I have to pay attention to more than just the resolution. Cheap LCDs cannot handle animations. TFT LCDs are faster. OLED displays, even more so. Hmm. A good STN LCD could be enough, since the Game Boy sported one.

2016-10-23

Blown Away

Nihil novi sub sole. This result was already known since the 18th century, but I've only heard about it last week: `1+2+3+4+\cdots=-1/12`

The infinite sum of all the natural numbers is somehow equal to negative one twelfth. I happened upon this crazy science on Youtube:



I tried to make sense out of this. I wanted a graphical representation of this infinite sum. If the result is not infinity, there should be a way to visualize the limit, right?! Well, I failed to find one. The only thing I could do was to show that the growth is logarithmic: $$\begin{align} A[n]&=n, \forall n\in\mathbb{N}_{>0} \\ B[n]&= A[n]+\cases{0 & \text{if } n = 1 \cr B[n-1] & \text{if } n > 1}, \forall n\in\mathbb{N}_{>0} \\ C[n]&=\frac{A[n]}{B[n-1]}, \forall n\in\mathbb{N}_{>1} \\ \\ A&=1,2,\ 3,\ 4,\ \ 5,\cdots \\ B&=1,3,\ 6,\ 10,15,\cdots \\ C&=\ \ \ \frac{2}{1},\frac{2}{2},\frac{2}{3},\frac{2}{4},\cdots \end{align} $$ Adding the `n`-th integer (thus `n`) to the sum means adding `2/{n-1}` time(s) the current sum to the sum. In other words, the sum increases by a factor of `{n+1}/{n-1}` at each step. When `n` tends towards infinity, this factor approaches `1`. The infinity we're adding is nothing but an epsilon...

Graphically, if we plot `B[n]` against `n`, the gradient of the curve (it's not actually a curve, just a set of points, but I guess the notion of gradient/slope still makes sense in this discrete context?) is equal to `n` (or `n-1`, or `n-1/2`? Not sure. Not important.) at each step. The gradient is ever increasing, so the series seems to increase exponentially. Absolutely no sign of a plateau; the slope gets more and more "vertical", forever. No limit. Yet our analysis above shows that the growth slows down. Well. The growth rate does decrease... but a smaller growth factor (which is by definition always greater than `1`) multiplied by an ever-bigger base yields an ever-bigger result. Oh, and not a trace of `-1/12`!

I was hooked. I youtube'd some more. The following video vulgarizes related mathematical concepts such as Cesàro mean, Cesàro sum, Riemann zeta function:



John Baez elaborates on the relevance of this equivalence in quantum mechanics, and how this result yields that string theory is 26-dimensional:



I am not very good at maths, nor knowledgeable in physics. Yet I find these explanations surprisingly clear and simple. It does makes sense... And at the same time it does not make sense. How can we can get a negative result by summing only positive numbers? As a programmer, my first thought was that we ran into a glitch in the Matrix. More likely, this is a clue about how the universe is really shaped. There is no reason for human mathematics to accurately represent a universe largely unknown to humans. If there are indeed 26 dimensions, why would our numbers only have two dimensions, "real" and "imaginary"?... [Edit 2016-10-25: I've just read about hypercomplex numbers] Who knows, a great discovery might be for tomorrow. That's exciting! It makes me want to brush up on my calculus.

2016-05-24

Get Rich or Die Try-Catchin'

Gambling on a lottery is a poor investment. By design, the bank profits, players lose. All things being equal, the smart choice is to abstain. You miss out on the 1 in 292,201,338 chance to hit the jackpot (unless you steal or find stray tickets, I guess), but you save $2 on each draw – no odds required. As Joshua puts it, the only winning move is not to play. But we don't exactly play to win; we play to not not win. [sic]

We ogle the prize. A eight- to nine-figure jackpot, occasionally exceeding one billion dollars. A life-changing amount of money. We long for change. Not playing is renouncing this possibility (unless, again, you happen upon an unattended ticket). Yes, the probability to get the right numbers is ridiculously small, but you have a chance. Partakers revel in this mysticism, bask in the dream. Get high on hope. Each week, an ordinary life may turn out to be extraordinary. Regularly buying tickets is a thrill, and an insurance of sorts. An insurance against the certainty to never win. A reason to go through the day. An escape.

But why do we yearn for such excessive wealth? Money is a mixed blessing at best, sometimes a curse. We tend to discount all the trouble associated with suddenly getting filthy rich (spoiled relationships, incessant requests, threats to personal safety, overindulgence, losing touch with reality, moral issues, depression or ennui...) and focus instead on the bright side: self-ownership. Freedom.

Considering the federal minimum wage in the United States ($7.25 per hour), unskilled labor is exploitative. On the other hand, educated masses struggle to pay off their huge student loans. Millennials' goal is not to save for retirement; their first ambition is to be "debt-free". Zero wealth, the bar is low... but they start at the bottom of a pit. They are money-hungry because they strive to redeem themselves. The fetters of debt keep modern-day galley slaves working the oars. Freedom is not free... Neither is education, nor healthcare, nor lodging, nor healthy food. Basic necessities have become a luxury.

At the same time, people demand more meaningful lives. They want to feel that they contribute to the betterment of mankind. Protect our environment. Make a difference. Sadly, meaning is in short supply. Too much human activity revolves around manufacturing and selling dispensable goods and services. Somehow, the falsehood that employment and economic growth matter has pervaded the minds. Machines eliminated most of the need for manpower, and what remains of the workforce concentrates in the tertiary sector, where busywork happens. Jobs often deprive people of their time, energy and soul. Hence the craving for change. Hence the lottery ticket.

The truth is, we don't need to put everyone to work. Only a fraction of the population. We should call for volunteers. Free and Open-Source Software proved that people who want to contribute do so for free. Citizens should receive an ample allowance to be free from want and free to choose their projects. Right. But that's not the world we live in today, so let's go back to the lottery.

I consider myself quite fortunate. My occupation, software developer, suits me. Programming compares to puzzle solving and riddle guesswork. If I were rich, I bet I would pursue the craft for the fun of it. This said, I could use an extra helping of freedom. I've started buying Powerball tickets on a regular basis. I pick numbers at random.

Twice a week, five white balls are drawn from a set of 69, plus a sixth, the "powerball", from a set of 26. For $2, you choose 5+1 numbers. A couple lucky guesses are worth a few bucks. With the correct five white balls (in any order) and powerball, you share the jackpot with the other winners. If nobody gets the six numbers right, the jackpot increases after the draw. A classic lottery. I disdainfully ignore the option called "power play", that adds $1 to the fare and multiplies the winnings... barring the jackpot.

A Powerball ticket bought in Maryland. Not a winner. :(

Besides the draw date, your beloved numbers, and mysterious pictograms, a ticket bears a large 25-character alphanumeric string titled "rewards points code". As the name suggests, a loyalty program allows you to collect rewards points with this code. You must claim them online. For the state of Maryland, the address is rewards.mdlottery.com, and for other states, I have no idea. The funny detail is that the number of points you get for each ticket is somewhat random. So what can you do with points? Trade them against useless items on the same website. Considering the retail value of these wares, the point-to-dollar change rate is crap. Alternatively, bid them on a virtual lottery. Yes. Quite the mise an abyme.

Sorry for this lengthy preamble. I come to the point now. The Freetinker showcases DIY projects. For starters, an attempt to streamline the chores of indulging in Powerball:
  1. Checking the numbers after each draw.
    • IRL: Locate a lottery retailer (usually inside convenience stores, gas stations, restaurants, bars, bowling alleys and grocery stores) and go for the terminal – the crimson cobble:

      Mid-late Neolithic artifact, exceptionally preserved.

      Pro(s):
      • If you win $600 or less, you can cash in right away.
      • You get to go out and see people!
      Cons:
      • If you win the jackpot, forget about anonymity.
      • The machine is rather slow.
      • There is often a line. If you have a bunch of tickets, people might hate you.
      • You have to go out and see people.
    • Online: mdlottery.com/games/powerball/winning-numbers/
      Pro:
      • Pretty much everyone has Internet access at home, or in their pocket.
      Con:
      • You rely on a fallible human brain to ascertain whether you hold a winning ticket.
  2. Punching in the "rewards points code". This is totally optional, so the best optimization would be to simply disregard this step. Yet thrifty voices in my head urge me to collect points. Maryland Lottery's website is a pain to use, but there is no alternative. Or is there?

Maryland Lottery offers a free smartphone app, but it still does not feature the oft-requested ticket reader. With an other official app you can scan tickets, but only to claim the rewards points. Anyway, I don't even own a smartphone. Yes, I'm one of those guys. You can also receive the winning numbers by text message. You still have to verify them yourself... And heck, each incoming text costs me. I don't have a plan either.

Ideally, we would contrive a system that not only emulates a Maryland Lottery terminal, but also includes the functionality of automatically claiming the rewards points. One scan of the ticket, then we are done with everything, without waiting in line or waking our torpid neocortex. A lofty goal. But is it feasible? And how? Good questions.

Checking the Numbers

Let's reverse engineer the terminal a little. How does it read our numbers? As you can see on the animated picture above, it only scans the bottom of the ticket, where the maze-looking pictograms are. These are QR codes; similar to bar codes, but information is encoded in two dimensions instead of just one. We can already tell that the two bigger QR codes are identical. The smaller one looks different. A free application or an online service such as zxing.org will decode them for us:
small one: V1;J0;S11094003818150447;
big ones:  V1;J0;S11094003818150447;w0P19B0QDQZK9G100N012RC5VB

Not only are the big ones twins, but they also contain all the data from the smaller one. A lot of redundancy here. So what do we have? Fields separated by semicolons. The first two are very short. Perhaps they form a version number. Useless. The third, of meaning unknown, also appears (minus the initial letter "S") in various places on the ticket. We recognize the fourth as our rewards points code, inexplicably prefixed with the letter "w". And, wait... That's all? Where are our numbers? How can the terminal tell whether we won without reading our numbers?

Here is an educated guess. When someone buys a lottery ticket, the cashier's machine connects to a centralized information system. A record is created, which holds the selected numbers, plus (maybe) ancillary notes such as the date, time, location, etc. An index is generated to uniquely identify this record. This index is sent back to the retailer, where it is printed on the ticket... as part of the QR-encoded data. So that's what the third field is about! When checking a ticket, the terminal decodes a QR code, transmits the index to the database via the network, then receives the numbers from the matching record. Maybe the remote server even takes care of the math and returns directly the gains. In any case, we don't know where the database is located, and even if we knew, it's very likely password protected. Without credentials, we simply cannot do the same as the terminal. Bummer.

Well, the numbers are printed on the ticket, after all. We could take a picture, then run an optical character recognition (OCR) program to extract them. I have tried. It does not work so well. On one hand, the software makes mistakes at times, and on the other hand, the print of the ticket is often of mediocre quality, so it's not helping. I know that it's possible to train the OCR to get better results... but it's never going to be perfect. I want to be absolutely sure that I did not win before I toss my ticket. At this point, I give up the idea of a machine reading the numbers. We will transcribe them manually.

The prize payout is a given. We also need to know which balls were drawn. Luckily, it's public information. It's all over the web... Now we can be picky. Since we want to automate the process, a source in a machine-readable format is the best. The text file at www.powerball.com/powerball/winnums-text.txt is as good as it gets: a table detailing two decades' worth of lottery results, steadfastly updated one hour after a draw. Nice.

We've defined all the pieces of our prospective system. Programming is the glue to bind them. Our program will prompt the user for their numbers, retrieve the drawn numbers, compare and output the gains, if any. For the hardware, any kind of computer with a keyboard, screen and Internet connection will do. For the software, I recommend a script language: Python. I've only started playing with it this year, but I'm fond of it. The documentation is not as helpful as Java's, and there is a weird split between versions 2.x and 3.x... No further complaints. Python comes with handy building blocks: we'll make use of the provided routines to read CSV files, to carry out operations on sets... Less on our plate, fewer lines of code required to make it happen. That's what you call powerful. In Python, the source code is interpreted (not compiled), so it doesn't matter whether your operating system is Linux, Windows or whatnot, as long as a Python interpreter is installed. This said, I use Linux and the first line of code below is Linux-specific. It's a hack to run a Python script just like a regular shell script. Note that for this to work, the script must be executed from a command-line interface, and its "execute" permission must be set.


Loyalty Program

Next challenge: to enter the rewards points code automatically. We already know how to extract it from the QR code. We still have to interface our system with the Maryland Lottery's to claim the points. Their website complicates the task by splitting the code into five parts. My initial idea was to mitigate the difficulty with a custom extension for Chrome. I wrote a helper tool to fill the fields, so that the user only has to paste once the whole code:

When the user hits the Enter key, the fields are populated.

The user is still involved in the process, so this solution is not automated enough. New approach: to reverse-engineer the website and figure out how to do without. An HTML form is meant to be used by humans. It relays the user input to some service. For the program meant to replace the soft machine, calling directly the target service is simpler. Let's find its URL. Read the HTML and JavaScript in the source of the web page. Audit the HTTP requests sent by the page. Browser extensions can help. Learn about the syntax of the command "curl." The man page will come in handy. It takes some trial and error too... Eventually, you should be able to log in and send a form without using a browser at all. You will eliminate the need for human intervention by writing a Bash script as follows:


Quick note about the hardware. We still need the usual computer, keyboard, monitor and Internet access, but also a peripheral to take pictures. I experimented with various models of webcams. The most convenient setup was to use the camera embedded above the screen of a laptop computer. To position the ticket quickly and reliably in front of the lens, I improvised a holder with reclaimed materials:

Introducing the ticket holder.
The ticket holder in action.

It works. At times. The construction is admittedly subpar; the plastic sheet bends out of shape until it loses its function. Above all, the concept itself is not satisfactory. The ticket stands so close to the lens that it must be lit from behind with a blinding USB lamp (not pictured). When it's slightly crumpled, the process fails. Even in perfect conditions, the image is often too blurry for the QR code to be readable. I switched to a flatbed scanner. Bulkier, but a much more pleasant experience:


Final Thoughts

That's it. We end up with two standalone scripts instead of one integrated system. The user is still coerced into typing in their numbers. I fell short of meeting all the objectives... but an ideal solution is more of a general direction than a specific destination. Feel free to improve upon my code; there's a lot left to do. Try to account for tickets with multiple draw dates or sets of numbers. Work with an ADF to really take the wight out of the loop. Yes, the effortless alternative is to download the existing apps on your smartphone... But it's so much fun to use the tools you've shaped and honed yourself! :)