Python Challenge

Python Challenge is a website featuring a series of small challenges that can only be solved by coding, preferably in Python. These challenges are organized into levels that get unlicked as you solve the previous one.

The levels have an air of mystery about what needs to be done, encouraging lateral thinking and making it very addictive. Although they can be solved using other languages, the hints and solutions are geared towards Python, to motivate learning more about its libraries and specific functionalities.

In this post, I describe the solutions to the first 20 levels of this challenge that I've managed to solve, with a link to each level in the title. You can find the solution code on Github.

Level 0: Warming up

This introductory level simply requires you to calculate the power shown in the image and replace the 0 in the URL with this value. This method of navigation by replacing parts of the URL is common in Riddle games.

Level 1: What about making trans?

Another straightforward level, where the page title itself hints at what to do. We're given a text encrypted by rotation and told which rotation to use, solved using maketrans. Upon doing so, we get this text:

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.

Applying the same maketrans to the URL takes us to the next level.

Level 2: OCR

The level itself suggests looking at the source code. Upon doing so, we find two comments, the first of which is:

find rare characters in the mess below:

Followed by a nonsensical string of characters. By only keeping the letters from the string, we obtain the key to the next level.

Level 3: Re

The clue suggests searching for a lowercase letter surrounded by exactly three uppercase letters on each side. Using regular expressions, we search [^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z] and find several letters that together form the solution to this level.

Level 4: Follow the chain

Clicking on the image, we're taken to a page ending in ?nothing=12345 with the text:

and the next nothing is 44827

Changing the number in the URL takes us to another similar page, again pointing to a different number. It seems we could be doing this all day, so it's time to use an HTTP request library, such as urllib (included in Python) or requests.

Through navigation, we encounter an exception: a level where one of the codes must be divided by two. Other than this, the level isn't too complicated; we follow 250 pages and reach the link to the next level.

Level 5: Peak hell

The clue this time is in the level title, which suspiciously sounds like Pickle, Python's object serialization library.

In the source code, we find a pickle file. Upon importing and examining it, we see it's a list of lines of text. Each line, instead of being a list of characters, is a list of pairs (character, repetitions). Reconstructing the text, we get a nice ASCII art:

ASCII art solution to the level 5 of the Python Challenge

Level 6: Now there are pairs

This level is quite similar to the 4th. We're shown an image of a zipper (zip in English), and changing the image extension from png to zip, we find a compressed file with many txt files and a readme, which says:

welcome to my zipped list.

hint1: start from 90052

hint2: answer is inside the zip

Navigating the files the same way as in level 4, this time using the zipfile library, we eventually find the text "collect the comments". However, this text is not the solution to the problem.

Since zip files have a comment field for files, we keep the comments from each file as we navigate. When combined, they again form a message in ASCII art.

In this case, the ASCII art is meant to mislead. The word it forms is not relevant, but the characters that make up the letters are.

Level 7: Smarty

This level shows us an image with a strange pattern of gray tones. Reading the gray intensity of each of the squares, we get the following series: 105 110 116 101 103 114 105 116 121 Converting each of these numbers into an ASCII character, we get the word integrity, the key to the next level.

Level 8: Working hard?

In the source code of this level, we find a username and password that are compressed using bzip2. Using Python's bz2 library, we get the username (huge) and password (file). Clicking on the image, we're asked for a username and password, which are the ones we just found, taking us to the next level.

Level 9: Connect the dots

Again, by looking at the source code, we find two strings, this time two sequences of numbers. After some analysis, we realize that the even numbers are close to each other and so are the odd numbers in both sequences. Treating each sequence as a list of number pairs, we can use the ImageDraw module of the PIL library to construct a figure that gives us the key to the next level.

Cow solution to the level 9 of the Python Challenge

By the way, if we put 'cow' as the solution, it tells us we got the gender wrong, a very accurate guide not to mislead the player who solved it.

Level 10: What are you looking at?

In this level, we find an image with a link to a sequence of numbers. Since it's a sequence of integers, we can search on OEIS to see if it's known, and indeed it is. It's the Look and Say sequence, which consists of describing the previous number in numbers.

The series works like this:

Level 11: Odd even

We observe an image with a strange effect, like those WhatsApp images that have one thumbnail and open to another thing entirely. Looking closer, we see that two images are interleaved, and by keeping the pixels with odd coordinates, we get the key for the next level.

Solution to the level 11 of the Python Challenge

Level 12: Dealing evil

Again an image with a strange effect on its pixels. I confess that I spent quite a while on this level. After gaining some experience with these types of challenges, I suspected something when I saw that the image of the level was called evil1.jpg, so I tried evil2.jpg and bingo! The image explains that we should change the extension to gfx.

Interestingly, trying evil3.jpg we encounter the text "no more evils…", and trying evil4.jpg we find an image that is actually a text file that says: "Bert is evil! go back!".

After much frustration, I decided to open the image with a hexadecimal editor, and I found the key to solving the level, the tag ÿOÿà that identifies the beginning of a jpeg file.

Image of the level 12 opened with a hexadecimal editor

The tag appears discontinuously several times, as does the GIF8 tag. If we take one out of every 5 pixels and convert it into 5 images, we get the key for the next level: disproportional.

Level 13: Call him

Looking at the source code, we find a link to an XML-RPC server. By doing listMethods() on it, we find a single defined method, phone. Since the level's clue is "phone that evil", and we know Bert is evil from the previous level, we call Bert and get the solution to the level.

At this point, the levels become quite challenging and less intuitive. I lost many hours because calling bert yielded no result if the B wasn't capitalized.

Level 14: Walk around

This level is relatively simple compared to the previous one: we find an image of a spiral (like a cinnamon roll) and below, an image that, when opened, is only 1px high.

By rolling it into a spiral shape, we get an image of a cat. Entering cat in the URL shows us the cat, named Uzi. Putting Uzi in the URL takes us to the next level.

Level 15: Whom?

We find a peculiar image of a calendar from the year 1XX6, where February had 29 days, and Monday was the 26th. The clue in this case is in the source code, and it's "buy flowers for tomorrow". Since the question is whom?, a simple Wikipedia search for January 27th gives us a long list of people born on that day. Limiting the search to years following the 1XX6 pattern and that fell on a Monday, we get a single result: the birth of Wolfgang Amadeus Mozart.

Level 16: Let me get this straight

After several levels of this style, it becomes quite intuitive to solve. If we join the entire image into a single 1px high strip, and introduce a break for each repetitive sequence of white and pink pixels we find, we get the key to the level:

Solution to the level 16 of the Python Challenge

Level 17: Eat?

We encounter an image of cookies (a classic hint about cookies) with a small image referencing level 4.

Returning to this level, we notice that a cookie tells us "you should have followed busynothing". Since the URLs of this level were of the type ?nothing=..., we change the first one to ?busynothing=... and start following the chain, while saving the information given by the info cookie. We get the following phrase:

is it the 26th already? call his father and inform him that "the flowers are on their way". he'll understand.

A quick search reveals that his father was Leopold Mozart. Since we're told to call him, we use the phone from level 13 to call Leopold, who tells us 555-VIOLIN. Replacing the URL with VIOLIN takes us to the Leopold page, asking us what we want.

Unfortunately, I haven't managed to advance beyond this point yet. If I continue making progress, I'll update this post.


Adrián Reply
Este challenge es super!

Vi el post y resolvi los 10 primeros con tu ayuda pero no consigo resolver el 13 conectando al servidor, algún consejo?
Juan C. Roldán Reply

Replying to Adrián:

Ánimo con el resto, si tienes dudas sobre cómo programarlo puedes echar un ojo al código de las soluciones que he dejado en Github, el enlace está en la introducción

Leave a comment

Get a mail