Volume Volume
Total Page:16
File Type:pdf, Size:1020Kb
Full Circle THE INDEPENDENT MAGAZINE FOR THE UBUNTU LINUX COMMUNITY PROGRAMMING SERIES SPECIAL EDITION PYTHONPYTHON VolumeVolume Ten Parts 54 - 59 Full Circle Magazine is neither ailiated, with nor endorsed by, Canonical Ltd. HHOOWW--TTOO Program In Python - Part 54 Written by Greg D. Walters Program In Python - Part 54 anyyears ago, I was dealing numbers), and the other uses What you will learn for each floss color. It seems that M with high blood pressure totally blank aida that you count • Revisitation ofdatabase and XML HSVis the easiestwayto find the issues. My doctor suggested that I stitches from the pattern. The manipulation. “closest” representation of a color do something that allowed me to second is much harderthan the • Revisitation ofTkinter GUI that will match the floss colors. Of concentrate on something fairly first. Go to your favorite fabric programming. Ifyou missed the course, the human eye is the useful, but rather trivial. I dealt store or craft section ofyour local previous articles on this, please ultimate decision maker. Ifyou are with it by trying to do counted mega-mart and you’ll get the idea. referto FCM issues 51 thru 54. not familiar with HSV color cross stitch. It’s creative, focused, • Image manipulation using PIL representations, there is a rather and keeps yourmind occupied on Also a while back, I started (http://pillow.readthedocs.org/en/l complex writeup on Wikipedia at whatyou are doing, notwhatis playing with creating a program atest/). http://en.wikipedia.org/wiki/HSL_a bothering you. I find myselfin that thatwould take an image and • PDF creation using pyFPDF nd_HSV. Itmighthelp, butitmight position again, so I broke outthe convert it into a cross stitch (https://code.google.com/p/pyfpdf make things less clear. hoop and needles and started pattern. One thing lead to another, ). again. and I had to shelve the program for The firstthing we need is an other things. I’ve now dusted off GETTING STARTED XML file that has the DMC floss In case you aren’t familiar with the idea and started anew. colors with a RGB conversion. The counted cross stitch, I’ll give you a The first thing in ourlist oftasks bestone I found isat gross overview ofwhat it is. Cross We will spend the next few is to create the database that will http://sourceforge.net/p/kxstitch/f stitch is a type ofneedlework that articles dealing with this project. It hold the DMC(™) floss colors and eature-requests/9/. The file you uses tiny ‘x’ patterns ofthread that will take a while, since some things reference them to the closest want is dmc.xml. Download it and eventually make up a picture. The are fairly complex and have many approximation to the RGB (Red, putitin a folderthatyou willuse thread is called “floss” and the parts to them. Here is the “game Green, Blue) values that are used in to hold the Python code. fabric that you use is called “aida”. plan”: images on the computer. At the According to Wikipedia, aida is a • Create a database forthe pixel same time, the database will hold Nowwe willbe using apsw special fabric that has tiny squares colors to floss colors. the hexvalue and the HSV(Hue, (below) to do our database that have small holes at regular • Create a GUI using Tkinterforthe Saturation, Value) representations manipulation, which you should intervals that form the squares. application. This facilitates the placement of • Flesh out the application to do # makedb.py # DMC.xml to SQLite database the “x” patterns that make the the manipulation ofthe image files. # For Full Circle Magazine #85 image. There are two types ofcross • Create a PDF file thatwillbe the stitch. One has an image printed on ultimate pattern for the project. import apsw from xml.etree import ElementTree as ET the aida (sortoflike paintby tablename = "DMC" full circle magazine #85 1 1 contents ^ HOWTO - PYTHON PART 54 already have and ElementTree to get started. We also use a counter do the XMLparsing (which is variable to show that something is <floss> <name>150</name> included in Python version 2.7+). happening while the parsing and <description>Dusty Rose Ultra VDK</description> database inserts are going on. <color> <red>171</red> As always, we start with our <green>2</green> imports. In this program, we have Nowthatwe have allourdata, <blue>73</blue> onlythe two. We also setthe name we need to create the SQL insert </color> </floss> ofthe table. statement and execute it. Notice the “\” after the word VALUES in The next portion should be the SQL statement. That is a line- def ReadXML(): global connection familiar ifyou have been reading continuation character to make it global cursor the articles for a while. We create a easier for printing here in the fn = 'dmc.xml' function that will read the XML file, magazine. We will be creating the tree = ET.parse(fn) root = tree.getroot() and parse itforus. We then can use database and table in a few cntr = 0 the information to load the moments. for floss in root.findall('floss'): database. A snippet ofthe XML file name = floss.find('name').text desc = floss.find('description').text is shown top right. SQL = "INSERT INTO DMC for colour in floss.findall('color'): (DMC,Description,Red,Green,Bl red = colour.find('red').text ue) VALUES \ We are looking for the <floss> green = colour.find('green').text blue = colour.find('blue').text tag for each line ofinformation. To ('%s','%s',%s,%s,%s)" % do this, we use the .findall(‘floss’) (name,desc,red,green,blue) command. Once we have the def OpenDB(): cursor.execute(SQL) global connection information line, we break each tag global cursor (name, description, etc.) into global ucursor separate variables to place into the Now, we print to the terminal global dbname connection = apsw.Connection("floss.db3") database. When it comes to the window that something is going on: cursor = connection.cursor() <color> tag, we use the ucursor = connection.cursor() .floss.findall(‘color’) command to print "Working record geteach value ofRed, Green and {0}".format(cntr) work before, you will notice that since ifyou modifya cursorin the Blue. we are using two cursors this time. middle ofa logic statement, you cntr += 1 The cursor variable is used for the lose everything with the new We start by telling the function Now we create and/or open the “normal” inserts, and later on in command. By using ‘ucursor’, we thatwe will be using the global database in the OpenDB routine the select statement for the can use thatforthe update variables connection and cursor. (bottom right). Ifyou’ve been with update to setthe hexand HSV statements. Other than that, it is We then set the filename ofthe us when we have done database values. We have to use two cursors, our normal OpenDB routine. XML file, parse the XML file, and full circle magazine #85 1 2 contents ^ HOWTO - PYTHON PART 54 Now that the database is def MakeTables(): created and/or opened, we can set sql = '''CREATE TABLE IF NOT EXISTS DMC up our table (top right). Notice that (pkID INTEGER PRIMARY KEY, DMC INTEGER, Description TEXT, Red INTEGER, Green INTEGER, Blue INTEGER, the SQL statement below uses the HEX TEXT,H INTEGER,S INTEGER,V INTEGER)''' triple quote to allow forthe line to cursor.execute(sql) break neatly for viewing. def rgb2hex(rgb): def EmptyTables(): The EmptyTables routine return '%02x%02x%02x' % rgb sql="DELETE FROM %s" % tablename cursor.execute(sql) (middle right) is there just to make sure thatifwe wantto orneed to cursor variable to hold the data. run the application more than We then step through the returned def rgb2hsv(r, g, b): data, and read the RGB values, and r, g, b = r/255.0, g/255.0, b/255.0 once, we startwith a clean and mx = max(r, g, b) empty table ifit exists. pass them to the rgb2hex function mn = min(r, g, b) as a tuple and to the rgb2hsv df = mx-mn function as three separate values. if mx == mn: IF we were to stop here, we h = 0 would have a reasonable working Once we get the return values, we elif mx == r: database with the DMC color, color use the update SQLcommand to h = (60 * ((g-b)/df) + 360) % 360 match the proper record by using elif mx == g: name and the RGB values h = (60 * ((b-r)/df) + 120) % 360 associated with each. However, as I the primary key (pkID). As I stated elif mx == b: before, we have to use a separate h = (60 * ((r-g)/df) + 240) % 360 alluded to before, it is easierto if mx == 0: pick the closest floss color by using cursor for the update statement. s = 0 the HSVdata. else: The lastthing we do is calleach s = df/mx v = mx We next create the hex value ofthe functions in order to create return int(round(h,0)), int(round(s*100,0)), from the RGB values (middle left). the database, and, atthe end, we int(round(v*100,0)) print “Finished” so the user knows The next function creates the everything is done. created in the same folder where to refresh your memory by looking HSVvalues from the RGB values. I the code and XML file are located. atFCM issues 51 thru 54 where I OpenDB() As always, the full code can be take you through Tkinter. found the algorithm on the MakeTables() internet. You can research it there. EmptyTables() # Just to be found at safe http://pastebin.com/Zegqw3pi. Until nexttime, have a good ReadXML() month. Finally, we create the UpdateDB UpdateDB() function (next page, top left).