Tag Archives: python

The Python Challenge – 4

I thought I would write my first python function for this one.  They appear to need to be at the top of the script though with a little casual searching I couldn’t confirm that.

Python 2.7.2 Solution

This got me there but is pretty flaky and needed manually fixing to get to the answer.

import urllib, re
count = 1

def getNextCode(lastCode):
    while True:
        try:
            page = urllib.urlopen('http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s' % lastCode).read()
            code = re.findall('(?<=and the next nothing is )\w*',page)
            print "Code %i is %s.  \nPage message was '%s'.\nPage tried was http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s'.\n" % (count, code[0], page, lastCode)
            return code
        except (IndexError, NameError):
            print "Error: Page message was '%s'\nPage was: http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s'." % (page,lastCode)
            return False
       
nextCode = getNextCode('12345')

count = 1

for count in range (1,400):
        if count == 84:
            nextCode[0] = int(nextCode[0])/2
        nextCode = getNextCode(nextCode[0])

Python 3.2.3 Solution

This deals with the message that you must divide by two when you get 16044 as a code. It also loads the page.  The 3.2.3 has a very different urllib approach.  3.2.3 seems to do crazy stuff with variable types.

import urllib.request, re, webbrowser
count = 1
       
def getNextCode(lastCode):
    while True:
        try:
            if lastCode == '16044': lastCode = str(16044 / 2)
            page = urllib.request.urlopen('http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s' % lastCode).read()        
            code = re.findall(r'(?<=and the next nothing is )\w*',page.decode("utf-8"))
            print ("\nCode %i is %s.\nPage tried was http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s'.\nPage message was '%s'." % (count, code[0], lastCode, page.decode("utf-8")))
            return code
        except (IndexError, NameError):
            print ("Error: Page message was '%s'\nPage was: http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s'." % (page,lastCode))
            return False
     
nextCode = getNextCode('12345')

count = 1

for count in range (1,400):
    if nextCode != False:
        answer = nextCode[0]
        nextCode = getNextCode(nextCode[0])
    else:
        new = 2 # open in a new tab, if possible
        test4url = "http://www.pythonchallenge.com/pc/def/" + urllib.request.urlopen('http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=%s' % answer).read().decode("utf-8")
        webbrowser.open(test4url,new=new) 
        break
print ("Done.")

The Python Challenge – 3

This one was not so hard.  (Or so I thought).  I could see that it was a regular expression problem right away.  The hardest bit was getting the regex right.

Python 2.7 Solution

import re
data = ''.join([line.rstrip() for line in open('3_message.txt')])
# Looking for the pattern lUUUlUUUl (U = UPPER, l = lower)
regex = r'(?the_answer = re.findall(regex, data)
if len(the_answer) == 1:
    print the_answer[0]
else:
    print "Sorry, your regex is crap.  There were %i matches " % len(the_answer)
    from pprint import pprint
    pprint(the_answer)

But the evil setters were much cleverer than that.  I got:

Sorry, your regex is crap.  There were 10 matches
[‘IQNlQSL’,
 ‘OEKiVEY’,
 ‘ZADnMCZ’,
 ‘ZUTkLYN’,
 ‘CNDeHSB’,
 ‘OIXdKBF’,
 ‘XJVlGZV’,
 ‘ZAGiLQZ’,
 ‘CJAsACF’,
 ‘KWGtIDC’]

This made me sad, even though it was a message to myself.  I pondered the problem and then looked at the middle letters.  They said “linked list”.  wtf?!

I looked up linked lists and was none the wiser.  I then thought I would just try typing linkedlist in to the url, and it worked.  I wonder if Linked Lists are key to the next one.  I rewrote the code so it outputted this.

Better Python 2.7 Solution

import re
data = ''.join([line.rstrip() for line in open('3_message.txt')])
regex = r'(?the_answer = re.findall(regex, data)
print 'You are regex GOD. The answer is %s' % ''.join(word[3] for word in the_answer)

Python 3.2 Solution

import re
data = ''.join([line.rstrip() for line in open('3_message.txt')])
regex = r'(?the_answer = re.findall(regex, data)
print ('You are regex GOD. The answer is %s' % ''.join(word[3] for word in the_answer))

I think I am learning slowly.  But there were about 50 ways of doing this in the solutions and my regex was very basic.  The next one looks pretty basic given my experience with php.

The Python Challenge – 2

This challenge is interesting in that it is confirming to me how inexperienced my programming actually is. I can get to the solution but the answer shows how limited I am. Here is my solution to 2 (I’d copied and pasted the text from the source to a document 2_message.txt.)

My Python 2.7 Solution

# find rare characters in the mess below:

maxoccurence = 1 #how many do I think is rare?

# load up the file
s = open(r"2_message.txt", "r").read()
#find the unique characters
uniqueones = set(s)

#find the rare characters (<= maxoccurence) and their position
rareones = []
for one in uniqueones:
position = []
if s.count(one) <=1:
position.append(one)
position.append(s.index(one))
rareones.append(position)


#rareones is now a multi dimensional list with the character and its position
from operator import itemgetter
solution = ""
for final in sorted(rareones, key=itemgetter(1)):
solution += final[0]
print solution

But here is the first of the suggested solutions

import collections
data = ''.join([line.rstrip() for line in open('2_message.txt')])
OCCURRENCES = collections.OrderedDict()
for c in data: OCCURRENCES[c] = OCCURRENCES.get(c, 0) + 1
avgOC = len(data) // len(OCCURRENCES)
print ''.join([c for c in OCCURRENCES if OCCURRENCES[c] < avgOC])

I want to understand this! So I spend as much time working it out as I do solving the first problem.  This is a great way of learning. I have had to learn what a Dictionary is in python (a sort of associative 2 dimensional array).  Link this to the collections library and you have got something pretty powerful.
The code appears to

  1. Load the data in to a massive string, removing the carriage returns.
  2. Make a container "Dictionary" for the characters
  3. Whiz through the massive string using the character as a key and simply adding 1 to the number attached to the key.  
  4. Getting the integer (floor) average (//) for each letter if they were distributed evenly.
  5. Concatenating all the items in the Dictionary that are less frequent than the average

This is actually not that different to what I did!!!  Just much more efficient.

[c for c in OCCURRENCES if OCCURRENCES[c] < avgOC]

Is very clever.  It is one line that only outputs a string if the occurrences are less than average.  I am still wrapping my head around it.

My Python 3.2.3 Solution

# find rare characters in the mess below:

# official version
import collections
data = ''.join([line.rstrip() for line in open('2_message.txt')])
OCCURRENCES = collections.OrderedDict()
for c in data: OCCURRENCES[c] = OCCURRENCES.get(c, 0) + 1
# avgOC = len(data) // len(OCCURRENCES)
avgOC = 1
print (''.join([c for c in OCCURRENCES if OCCURRENCES[c] == avgOC]) )

This just needed the modification to "Print" though I did find on python 3 it didn't run because there was no collections library.

The Python Challenge – 1

So, my first effort in about 5 minutes gave me the following secret message:

The answer is: ” fone you biblr rp{lsj{re ir zy f{lb. rf{rs wf{r comnureps {pe dop. boilg ir il zy f{lb is ileddicielr {lb rf{r’s wfy rfis revr is so jolg. usilg srpilg.m{kerp{ls() is pecommelbeb. low {nnjy ol rfe upj.”

Not so good. This was better:

The answer is: “i”hope”you”didnt”tr{nsl{te”it”|y”h{nd0″th{ts”wh{t”computers”{re”for0″doing”it”in”|y”h{nd”is”inefficient”{nd”th{t)s”why”this”text”is”so”long0″using”string0m{ketr{ns*+”is”recommended0″now”{pply”on”the”url”

And this was the last wrong one:

The answer is: “i hope you didnt tr{nsl{te it |y h{nd. th{ts wh{t computers {re for. doing it in |y h{nd is inefficient {nd th{t’s why this text is so long. using string.m{ketr{ns() is recommended. now {pply on the url”

So here was the message:

The answer is: “i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that’s why this text is so long. using string.maketrans() is recommended. now apply on the url”

string.maketrans()!? My code looked like this:

question = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
output = 'The answer is: \"'
for x in range (0 , len(question)-1):
# 97 - 122
if ord(question[x]) >= 97 and ord(question[x]) <= 120:
output += chr(ord(question[x]) + 2)
elif ord(question[x]) >= 121 and ord(question[x]) <= 122:
output += chr(ord(question[x]) - 24)
else:
output += question[x]
print output + '\"'

Python 2.7.5 Solution

But maketrans sounded fun, so I quickly did this.

from string import maketrans   # Required to call maketrans function.
question = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
output = 'The answer is: \"'
intab = "abcdefghijklmnopqrstuvwxyz"
outtab = "cdefghijklmnopqrstuvwxyzab"
trantab = maketrans(intab, outtab)
print question.translate(trantab);

Which was a lot faster, cleaner and easier. But didn’t work at all with Python 3.0 which died on “TypeError: maketrans arguments must be bytes objects”.  I found out quickly that I needed to declare the intab and outtab with a “b” onthe front so they became byte objects.  That, and the changed “print” call and I was done.

Python 3.0 Solution

from string import maketrans   # Required to call maketrans function.
question = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."
output = 'The answer is: \"'
intab = b"abcdefghijklmnopqrstuvwxyz"
outtab = b"cdefghijklmnopqrstuvwxyzab"
trantab = maketrans(intab, outtab)
print (question.translate(trantab)); 
 

In the answers they use string.ascii_lowercase for b”abcdefghijklmnopqrstuvwxyz” and  string.ascii_lowercase[2:]+string.ascii_lowercase[:2] for b”cdefghijklmnopqrstuvwxyzab”, which is just showing off.

Fiddling with python and pyrow

Got pyrow working last night.  Today not so good, so going to document steps here.  It is as good a place as any other.

cstate = results[‘CSAFE_GETSTATUS_CMD’][0]

Throws “TypeError: list indices must be integers, not str” all of a sudden.  I have changed nothing.  I think that this is because there is nothing coming back from the erg so the results array is empty.

CSAFE is some sort of open source means of communicating with gym equipment I think.

I give up for now.  Frustrating that it worked last night!

Bleah.