#
# piet.py
#
# generates piet programs (.png format) based on a user-inputted wanted output.
#
# Required PyPNG module can be downloaded here: https://p...content-available-to-author-only...n.org/pypi/pypng
# To run your piet programs you can use npiet - http://w...content-available-to-author-only...e.de/npiet/
#
# I strongly recommend reading up on the Piet programming language - http://w...content-available-to-author-only...e.net/esoteric/piet.html
# I find it really interesting, and this program will make more sense.
#
# For help, visit: http://s...content-available-to-author-only...t.edu/discuss/topic/74722/
#
r"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Hello!
I recently wrote a Python script which generates valid [url=http://w...content-available-to-author-only...e.net/esoteric/piet.html]Piet programs[/url] in a png format!
I was (as normal) browsing esoteric languages, and stumbled across Piet - http://w...content-available-to-author-only...e.net/esoteric/piet.html
I thought it was a very unique, cool idea, so I tried it myself using [url=http://w...content-available-to-author-only...e.de/npiet/]npiet[/url] as my interpreter (TIP: make sure you get the version intended for your OS, I downloaded the Linux one and spent the next half-hour scratching my head as to why it didn't work :P).
Soon, though, I got a bit tired of drawing out every design myself, and had a go at creating a generator for it.
I used Python 3.4.2 to create this command-line tool:
I'm not sure if any features within here are specific to 3.4.2, but if you are experiencing unexpected problems the version could be why.
It uses the PyPNG module, so you'll have to download that first: https://p...content-available-to-author-only...n.org/pypi/pypng
I also recommend reading about Piet - http://w...content-available-to-author-only...e.net/esoteric/piet.html - I found it really interesting :)
This example is for Windows:
[list=1]
[*] To use my program, first download the PyPNG module from the link above, and then go to the folder you downloaded it to.
[*] Now, you can Shift+Right-Click the folder and choose "Open Command Window Here". (<-- learning cool new tricks all the time, aren't we ;))
[*] Basically, you just need a command prompt running in the directory containing piet.py
[*] You can type this command:
[code]
md tests
[/code]
[*] And then to use the program, type
[code]
piet "Hello, World!" /r tests\helloworld.png
[/code]
[*] It should now display a heart-warming success message! If it didn't, you can post any queries here: http://s...content-available-to-author-only...t.edu/discuss/topic/74722/, ask for help etc.
[*] Your png has been generated, and should work when interpreted by a piet interpreter.
[*] If you have downloaded npiet, move it into C:\Windows\System32 (somewhere in your path) and run the following commands to try out your newly generated program:
[code]
cd tests
npiet test1.png
[/code]
[*] Ta da! Have fun!
[/list]
Currently the program only generates boring single-pixel lines, but I hope to update this soon to create interesting patterns.
You can have a look inside the program itself, I've tried my best to comment it and keep it helpful and intuitive :)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
import sys
import os
import os.path
import png
# for command-line arguments and relative paths:
#################################################### the piet colors ####################################################
# current_hue increases ------------->
# hue cycle red yellows green cyans blues magenta # lightness cycle
# # |
piet_colors = [[[255,192,192],[255,255,192],[192,255,192],[192,255,255],[192,192,255],[255,192,255]], # light | current_lightness
[[255,000,000],[255,255,000],[000,255,000],[000,255,255],[000,000,255],[255,000,255]], # normal | increases
[[192,000,000],[192,192,000],[000,192,000],[000,192,192],[000,000,192],[192,000,192]]] # dark V
def help():
print('\npiet.py')
print('A python program to generate piet programs by George, theonlygusti.')
print('Piet programming language: http://w...content-available-to-author-only...e.net/esoteric/piet.html\n')
print('Requirements:\n')
print(' Python - downloa... wait, how are you reading this?') # just in case you are, download python here: https://w...content-available-to-author-only...n.org/downloads/
print(' The PyPNG module - download here: https://p...content-available-to-author-only...n.org/pypi/pypng\n')
print('Usage:\n')
print(' piet [/?] textoutput [/R] file\n')
print(' textoutput output you wish the piet program to create.')
print(' file path to the file (.png) you wish to write to.')
print(' /? display this help/info message.')
print(' /R States the file path to be relative.')
print('Example:\n') # and an example because, well, who doesn't like those? I could always do with one.
print(r' piet "Hello, World!" C:\myPythonTests\Piet\test.png')
print('\n The above line would generate a piet program (that outputs Hello, World!)\n in the file C:\myPythonTests\Piet\\test.png')
############################################### Okay, program starts here: ##############################################
# this is a command-line tool,
# check user has entered the correct number of arguments:
if (len(sys.argv) < 3) or (sys.argv[1] == '/?'):
# display help/info message
help()
sys.exit()
# now store the command-line flags
text_for_output = sys.argv[1]
# has to check if relative or absolute path, hence all this mumbo-jumbo
# V
file_path = sys.argv[2] if sys.argv[2] not in ('/R', '/r') else os.getcwd() + (sys.argv[3] if sys.argv[3].startswith('\\') else '\\' + sys.argv[3])
# converts all the characters in the wanted output text to their ASCII codes
char_codes = [ ord(x) for x in text_for_output ]
# initialization!
current_hue = 0
current_lightness = 0
outputted_png = [[]]
######## generate piet program ########
# The idea here is to use the char_codes array to generate single-color pixel bands,
# the width of which is determined by the character (so 'a' (char code 97) would create
# a band of one color 97 pixels wide.)
#
# It might be useful to look at your generated png's top understand the above concepts.
#
# Then we push that number (in piet numbers are represented by blocks of solid color)
# onto the stack, and putchar (print) it.
for char_code in char_codes:
for i in range(char_code): # so here, this loop just creates that 1 color band to represent the character.
outputted_png[0] += piet_colors[current_lightness][current_hue]
current_lightness = (current_lightness + 1) % 3 # changes the lightness by 1
outputted_png[0] += piet_colors[current_lightness][current_hue] # so that now when we add that new color,
# it pushes the number (character) to the stack.
# Remember, in Piet commands are transitions between colors.
current_lightness = (current_lightness + 2) % 3 # Now, these two lines just change the lightness
current_hue = (current_hue + 5) % 6 # And hue the correct amount for a putchar command (2x5)
# This color is used for the new "band" color above (line 69)
# This next section just puts a little loop-looking thing at the end of the program, which terminates it.
# It adds an extra 2 pixels to the height of the image.
outputted_png[0] += piet_colors[current_lightness][current_hue]
outputted_png[0] += [0,0,0]
png_width = int(len(outputted_png[0])/3) # stores pixel-width of file
outputted_png.append([255, 255, 255]*(png_width-4))
outputted_png[1] += [0,0,0]
outputted_png[1] += piet_colors[current_lightness][current_hue] * 2
outputted_png[1] += [0,0,0]
outputted_png.append([255, 255, 255]*(png_width-4))
outputted_png[2] += [0,0,0] * 4
# ^^ don't worry, this code won't make any sense
# to me when I re-open it 2 days later ;)
######## Write to file! ########
# outputted_png now contains an array for writing to a png file
# so lets write it to a file!
piet_png_output_file = open(file_path, 'wb') # remember file_path is the user-specified path, set on line 49
file_writer = png.Writer(png_width, len(outputted_png))
file_writer.write(piet_png_output_file, outputted_png)
piet_png_output_file.close()
# And we're done!
print("\nHurrah! .png succesfully generated!")
# Remember to check out the Piet language: http://w...content-available-to-author-only...e.net/esoteric/piet.html
# And the PyPng module: https://p...content-available-to-author-only...d.org/pypng/
# With code examples: https://p...content-available-to-author-only...d.org/pypng/ex.html
#
# Hope you learned something!