A Colorful Challenge

MISSION: Print colors to the terminal
SKILLS: Basic string manipulation

Computer graphics have always been a curiosity for me. Ever since I started programming, printing pretty things to screen was always something I just found to be really cool. Unfortunately, graphics involve a lot of setup, libraries, and copy-and-paste code - not something I'm too fond of. And (as I found out the hard way) even hard-coding the most basic 3D scene requires a ton of preliminary code and a good understanding of topics like Linear Algebra. So today we're going to take it slow.

Colors on the Terminal

You might be thinking, "The only colors I see in my terminal are a few shades of blue and red, highlighting file names. What am I supposed to do with that?" Well, you'd be surprised. We're going to be using some ANSI Escape Sequences to actually draw our colors.

So how do they work?

These escape sequence, when picked up by your terminal, will mess with its settings a bit. Think of the newline character (\n). When the terminal comes across a back slash and an n, it moves the cursor to the next line. This is what's known as an escape code and we'll be using some of them to draw colors. Now, when I say draw colors, what we're actually going to do is change our terminal background color, write something, then change it back. It's a little confusing, so let's go through it step by step.

My motivation for this post was the fact that, when I wanted to experiment with color escape codes, I had a tough time figuring out what exactly I had to do. I hope this solves such frustration for others. There are many ways (and libraries) to go about printing colors to your terminal, but this is something that worked for me. So let's recognize an escape code in the format

\033[XYm

Where X and Y are two numbers. Here,

  • X sets the mode (foreground, background): 3 or 4
  • Y sets the color: 0-7
  • The code \033[0m sets everything back to default

As a reference, I set the follow constants in my code.

BLACK_FG  = '\033[30m'
RED_FG    = '\033[31m'
GREEN_FG  = '\033[32m'
YELLOW_FG = '\033[33m'
BLUE_FG   = '\033[34m'
PURPLE_FG = '\033[35m'
CYAN_FG   = '\033[36m'
GRAY_FG   = '\033[37m'

BLACK_BG  = '\033[40m'
RED_BG    = '\033[41m'
GREEN_BG  = '\033[42m'
YELLOW_BG = '\033[43m'
BLUE_BG   = '\033[44m'
PURPLE_BG = '\033[45m'
CYAN_BG   = '\033[46m'
GRAY_BG   = '\033[47m'

END       = '\033[0m'

So let's say I wanted to print the following
Hello, world

That is, yellow on black for "Hello, " and blue on red for "world!" How would we do this? It's simple, really.

  • We set the foreground color to yellow
  • Write "Hello, "
  • Set the foreground color to blue
  • Set the background color to red
  • Write "world"
  • End.

That's right, you can stack many of these bad boys on top of each other. So what would the string look like that we need to print?

\033[33mHello, \033[34m\033[41mworld\033[0m

Go ahead and verify this with

python -c "print '\033[33mHello, \033[34m\033[41mworld\033[0m'"

To see the expected output.

So, can you see the individual pieces? First we set the FG to yellow with \033[34m. Then, we put "Hello, ". Next, \033[34m to set the FG to blue, followed by \033[41m to set the background to red. Finally we wrote "world" and printed the "END" sequence. Using the constants, this could be easily achieved with

print YELLOW_FG + "Hello, " + BLUE_FG + RED_BG + "world" + END

Now, what if you wanted to print a "pixel," that is, a colored square with nothing in it. Not a problem, just escape the string with a background color, print a space, and end it. That's all!

So now, your challenge? I want you to experiment with this stuff and have fun your own way, but I am proposing a graphical puzzle of sorts to those looking for something to code (that's the point here anyway, right?) Your task, shall you accept it, is to print the American flag. Here's my attempt at it.


See my terminal prompt? That, too, uses color escape codes. Check out your environment variable, $PS1, and play around with it.

And, of course, if you're not a US citizen, feel free to print your own flag - or any flag you'd like! Bonus points for clean code, which is tough to do without extracting some sort of pattern from the design. Some basic guidelines for the American flag...

  • The flag should have 13 stripes - starting with red and ending with red
  • 50 stars, arranged in 9 rows of (7,6,7,6,7,6,7,6,7)
  • Dimensions close to the actual American flag

That's all for now, I'm looking forward to your solutions and cool drawings. Be sure to show them off in the comments section below.
Jordan

PS - For those curious, my $PS1 is exported to \033[32m\u\033[0m\033[36m@\033[0minitech(\033[44m\W\033[0m) \033[95m§\033[0m in ~/.bash_profile

Numbers for People

MISSION: To print a number in human-readable format
SKILLS: Modular arithmetic, String operations

Numbers are pretty awesome. People are also pretty awesome. However, the relationship between humans and numbers is fuzzy to most. We do some pretty complex stuff with numbers in our heads without even knowing it. Let's take reading numbers for instance.

464,723,104,643

If I asked you to read this number aloud, you'd do without issue. What's going on in your head when you do this? Well, a few things pop into my head.

  • Well, there are 4 groups of numbers, so we'll start at billion
  • Okay the first one is 4. four hundred
  • The second is 6. sixty
  • And lastly, 4. four
  • Putting this all together, we start with four hundred sixty-four billion

I don't need to teach you how to read numbers - you all know how. But modeling this process with computer code is pretty interesting! So that's what we'll be doing today.

Now, guidelines are kind of fuzzy - but I'm hoping you can closely match my output. A lot of people get confused when to use 'and' and when to use, hyphens, etc. As usual, feel free to do whatever looks best or makes the most sense for you! However, many of you will try to match my output, which is cool too.

initech:numbers-for-people jordan$ ./num-to-human.py 9
nine
initech:numbers-for-people jordan$ ./num-to-human.py 12
twelve
initech:numbers-for-people jordan$ ./num-to-human.py 64
sixty-four
initech:numbers-for-people jordan$ ./num-to-human.py 587
five hundred eighty-seven
initech:numbers-for-people jordan$ ./num-to-human.py 590
five hundred ninety
initech-2:numbers-for-people jordan$ ./num-to-human.py 10000000000
ten billion
initech:numbers-for-people jordan$ ./num-to-human.py 45671
fourty-five thousand six hundred seventy-one
initech:numbers-for-people jordan$ ./num-to-human.py 123456789
one hundred twenty-three million four hundred fifty-six thousand seven hundred eighty-nine
initech:numbers-for-people jordan$ ./num-to-human.py 1234567890
one billion two hundred thirty-four million five hundred sixty-seven thousand eight hundred ninety
initech:numbers-for-people jordan$ ./num-to-human.py 464723104643
four hundred sixty-four billion seven hundred twenty-three million one hundred four thousand six hundred forty-three
initech:numbers-for-people jordan$

Be sure to save this code (why wouldn't you?) because we'll be using it for some analysis next time.

All the best,
Jordan

Further Development

Hey folks,

I hadn't used WordPress before, and I must say I am pretty impressed with the way things have been working lately. However, I prefer to do my own thing.



So for the next couple of weeks/months/millenia I'll be making a custom version of ProgramThis to suit my needs. This includes a less-bloggy platform and a more challengey feel to the site. Some things I hope to achieve...

  • Mailing lists
  • API
  • Better viewer submissions model
  • Submission voting
  • Post ratings
  • Lots of other goodies

So yeah, things will be pretty awesome :) What this means for you as a reader is, well, nothing. I'll still be updating this site with challenges, and I promise you won't need to re-register. All of the accounts and challenges will be here once the new site launches.

Here's to the future,
Jordan