Sunday, 24 April 2011
Python Challenge #007 - oxygen
Have to use command line tool Image Magick.
>>> import subprocess >>> subprocess.check_call(['convert', 'oxygen.png', 'oxy.txt']) 0Read in the Image Magick text file.
>>> with open('oxy.txt') as f:
... lines = f.readlines()
...
Parse file header.>>> m = re.match(r'# ImageMagick pixel enumeration:\s*?(\d+),(\d+),.*', lines.pop(0))
>>> w, h = [int(g) for g in m.groups()]
>>>
>>> print('Dims: ', w, 'x', h)
Dims: 629 x 95
Read in pixel data.>>>
>>> p = re.compile(r'(\d+),(\d+): \(\s*?(\d+),\s*?(\d+),\s*?(\d+),.*')
>>> pixdata = []
>>> for i in range(h):
... pixdata.append([0] * w)
... for j in range(w):
... m = p.match(lines[i * w + j])
... x, y, r, g, b = [int(g) for g in m.groups()]
... pixdata[i][j] = (r, g, b)
...
>>> s = ''.join(chr(pixdata[48][j][0]) for j in range(0, 608, 7))
>>> print(s)
smart guy, you made it. the next level is [105, 110, 116, 101, 103, 114, 105, 116, 121]
>>> print(''.join(chr(int(n)) for n in s[43:-1].replace(',', '').split()))
integrity
Python Challenge #006 - channel
The zip is a clue. The file can be opened with the zipfiles library.
>>> import re
>>> import sys
>>> import zipfile
>>> n = '90052'
>>> history = []
>>> f = zipfile.ZipFile("channel.zip")
>>> print(f.read(n + '.txt'))
b'Next nothing is 94191'
>>> print(f.getinfo(n + '.txt').comment)
b'*'
This function follows the nothings through the zipped files.>>> def next_zip(n):
... history.append(n)
... text = f.read(n + '.txt').decode()
... m = re.search('\d+', text)
... if m is None: return m
... n = m.group()
... return n
...
Now collate the file comments in the zip archive in the order of the nothings.>>> while n: n = next_zip(n)
...
>>> print(''.join(f.getinfo(n + '.txt').comment.decode() for n in history))
****************************************************************
****************************************************************
** **
** OO OO XX YYYY GG GG EEEEEE NN NN **
** OO OO XXXXXX YYYYYY GG GG EEEEEE NN NN **
** OO OO XXX XXX YYY YY GG GG EE NN NN **
** OOOOOOOO XX XX YY GGG EEEEE NNNN **
** OOOOOOOO XX XX YY GGG EEEEE NN **
** OO OO XXX XXX YYY YY GG GG EE NN **
** OO OO XXXXXX YYYYYY GG GG EEEEEE NN **
** OO OO XX YYYY GG GG EEEEEE NN **
** **
****************************************************************
**************************************************************
Python Challenge #005 - peak
Peak hell? What does that sound like? The page source links to banner.p, so let's have a look at it.
>>> from urllib.request import urlopen >>> url = 'http://www.pythonchallenge.com/pc/def/banner.p' >>> text = urlopen(url).read() >>> text[:20] b"(lp0\n(lp1\n(S' '\np2\nI"This is a streamed encoding called Pickle.
>>> import pickle
>>> data = pickle.loads(text)
>>> len(data)
23
>>> from pprint import pprint
>>> pprint(data[:5])
[[(' ', 95)],
[(' ', 14), ('#', 5), (' ', 70), ('#', 5), (' ', 1)],
[(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)],
[(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)],
[(' ', 15), ('#', 4), (' ', 71), ('#', 4), (' ', 1)]]
This is numbers and types of characters to print on each row like a Unix Banner.>>> for row in data:
... print(''.join(pair[0] * pair[1] for pair in row))
...
##### #####
#### ####
#### ####
#### ####
#### ####
#### ####
#### ####
#### ####
### #### ### ### ##### ### ##### ### ### ####
### ## #### ####### ## ### #### ####### #### ####### ### ### ####
### ### ##### #### ### #### ##### #### ##### #### ### ### ####
### #### #### ### ### #### #### #### #### ### #### ####
### #### #### ### #### #### #### #### ### ### ####
#### #### #### ## ### #### #### #### #### #### ### ####
#### #### #### ########## #### #### #### #### ############## ####
#### #### #### ### #### #### #### #### #### #### ####
#### #### #### #### ### #### #### #### #### #### ####
### #### #### #### ### #### #### #### #### ### ####
### ## #### #### ### #### #### #### #### #### ### ## ####
### ## #### #### ########### #### #### #### #### ### ## ####
### ###### ##### ## #### ###### ########### ##### ### ######
>>>
Python Challenge #004 - linkedlist
Clicking the image leads to linkedlist.php?nothing=12345, which suggests replacing the value at the end of the URL. Let's define a function to get the next value.
>>> import sys
>>> from urllib.request import urlopen
>>> BASE_URL = 'http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing='
>>> def next_nothing(n):
... text = urlopen(BASE_URL + n).read().decode()
... m = re.match('and the next nothing is ([0-9]+)', text)
... if not m: print('\n\n' + text + '\n')
... n = m.group(1)
... sys.stdout.write(n + ', '); sys.stdout.flush()
... return n
...
Note that this will raise an AttributeError when the regular expression fails to match and m.group is called when m is None.>>> n = '12345' >>> while True: n = next_nothing(n) ... 92512, 64505, ...Feed in the next value and repeat as necessary.
>>> n = '50010' >>> while True: n = next_nothing(n) ... 29193, 89924, ...
Saturday, 23 April 2011
Python Challenge #003 - equality
The bodyguards seem to refer to capital letters. Use regular expressions to parse.
>>> import re
>>> text = urlopen('http://www.pythonchallenge.com/pc/def/ocr.html').read()
>>> text = text.decode()
>>> print(''.join(re.findall('[^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z]', text)))
linkedlist
Python Challenge #002 - ocr
If urlopen is already imported, the first statement won't do much.
>>> from urllib.request import urlopen >>> url = 'http://www.pythonchallenge.com/pc/def/ocr.html' >>> text = urlopen(url).read()Chop the interesting characters from the html.
>>> start = text.index(b'%%') >>> stop = start + text[start:].index(b'-->') >>> chars = text[start:stop]Find the histogram of letter counts and any lower case ASCII characters.
>>> hist = {}
>>> t = []
>>> for c in chars:
... if c in hist:
... hist[c] += 1
... else:
... hist[c] = 1
... if c > 96 and c < 123:
... t.append(c)
...
Use pprint to format standard output.
>>> from pprint import pprint
>>> pprint(hist)
{10: 1220,
33: 6079,
35: 6115,
36: 6046,
37: 6104,
38: 6043,
40: 6154,
41: 6186,
42: 6034,
43: 6066,
64: 6157,
91: 6108,
93: 6152,
94: 6030,
95: 6112,
97: 1,
101: 1,
105: 1,
108: 1,
113: 1,
116: 1,
117: 1,
121: 1,
123: 6046,
125: 6105}
>>> t
[101, 113, 117, 97, 108, 105, 116, 121]
>>> ''.join(chr(c) for c in t)
'equality'
Python Challenge #001 - 274877906944
What about making trans?
Examining the page source reveals a Caesar Cipher. Get the mission HTML data with urlopen.
Examining the page source reveals a Caesar Cipher. Get the mission HTML data with urlopen.
>>> from urllib.request import urlopen >>> CHALLENGE_URL = 'http://www.pythonchallenge.com/pc/def/map.html' >>> text = urlopen(CHALLENGE_URL).read()Create a translation table to shift each lower case ASCII byte by 2 places cyclically.
>>> lower = bytes(i for i in range(97, 123)) >>> lower b'abcdefghijklmnopqrstuvwxyz' >>> t = bytes.maketrans(lower, lower[2:] + lower[:2])Find the enciphered text.
>>> start = text.index(b'g fmnc') >>> stop = start + text[start:].index(b'\n') >>> enc = text[start:stop] >>> enc[:20] b'g fmnc wms bgblr rpy'Translate enciphered text.
>>> enc[:38].translate(t) b'i hope you didnt translate it by hand.' >>> b'map'.translate(t) b'ocr'
Python Challenge #000: 0
Welcome to my introduction to Python 3 programming via the Python Challenge. The first thing to do is to install it either from a recent release or, on Debian-derived platforms such as Linux Mint, enter the following in a terminal (with superuser privileges):
The Python 3 interpreter can be invoked as follows:
apt-get install python3To confirm installation:
python3 --version0.html: warming up
The Python 3 interpreter can be invoked as follows:
python3The image shows a number raised to a power. This is expressed in Python as follows:
>>> 2**38 274877906944
Subscribe to:
Posts (Atom)