Sunday, December 21, 2008

Happy strings

Yup, it's Dada again! I love useless things!

So, I was browsing through Think Python and found an exercise to print stuff on the screen. I figured it would be fun just to make it in one go - no loops or anything.

Here's how it looked. And by the way, you can run all the code in a Python interpreter - it's all safe.
 
1 print \
2 ( ('+' + 5 * '-') * 3 + '+' + "\n" + \
3 ( ( '|' + 5 * ' ' ) * 3 + '|' + "\n" ) * 2 ) * 3 + \
4 ('+' + 5 * '-') * 3 + '+'


But then I figured... that's not nearly fun enough. So, long story short, I made this:
 
1 print \
2 ',' + '_' * 2 + ',' + '\n' + \
3 '(' + 'x' * 2 + ')' + '_' * 4 + '\n' + \
4 '(' + '_' * 2 + ')' + ' ' * 4 + ')' + '\\' + '\n' \
5 + ' ' + 'U' + '|' * 2 + '-' * 2 + '|' * 2 + ' ' * 2 + '*'


Much more fun.

So then, I took it up a notch and wrote a program to generate that sort of thing. It took me three complete attempts, because I mostly produced bugs today... damn bugs. But it's all nice and thought-through now.

Here's the code:
 
1 #!/usr/bin/python
2 #
3 # Happy strings
4 #
5 # More or less purposeless script, which takes strings, splits
6 # them up into characters and then creates a Python print
7 # statements which reproduce the same strings in a
8 # complicated, slightly less readable form... but a slightly
9 # happier form, methinks.
10 #
11 # Parameters:
12 # a list of strings to reproduce
13 # Author:
14 # Konrad Siek
15
16 import sys
17
18 def escape_string(string):
19 if string in ["\'", "\"", "\\"]:
20 return "\\" + string
21 elif string == "\n":
22 return "\\n"
23 return string
24
25 def output_string(string, counter, last):
26 output = "'" + escape_string(string) + "'"
27 if counter != 1:
28 output += ' * ' + str(counter)
29 if not last:
30 output += ' + '
31 return output
32
33 for string in sys.argv[1:]:
34 output = 'print '
35 previous = None
36 counter = 0
37 length = len(string)
38 for i in range(0, length):
39 character = string[i]
40 if character == previous:
41 counter += 1
42 else:
43 if previous != None:
44 output += output_string(
45 previous,
46 counter,
47 False
48 )
49 counter = 1
50 previous = character
51 output += output_string(
52 previous,
53 counter,
54 True
55 )
56 print output


Yay!

The code is also available at GitHub as python/happy_strings.py.

No comments: