[Tutor] newbie code review please!
Hi, I'm a middling amateur coder in C and elisp, trying to wrap my head around python syntax. I've implemented the code for the markov chain random text generator from Kernighan and Pike's "The practice of programming", and I'd appreciate any tips on how to make it more pythonic. The code appears to work as intended. It reads a file, breaks the text into a list of individual words. It then builds a hash table in the form of: (prefix-word-1, prefix-word-2):[list-of-possible-following-words] It finishes by using the hash table to generate a nonsensical, and occasionally amusing bit of text based on the input. Any comments welcome! Thanks, Tyler #! /usr/bin/python import sys, random word_max = 1000 # Read in file infile = open(sys.argv[1], 'r') ifstring = infile.read() # break file into words iflist = ifstring.replace('\n', ' ').split() # build hash of form (prefix1, prefix2): [word] word_hash = {} for i in range(len(iflist) - 2): pr1 = iflist[i] pr2 = iflist[i+1] tv = iflist[i+2] tk = (pr1, pr2) if word_hash.has_key(tk) and tv not in word_hash[tk]: word_hash[tk].append(tv) else: word_hash[tk] = [tv] if word_hash.has_key((iflist[-2], iflist[-1])): word_hash[(iflist[-2], iflist[-1])].append('\n') else: word_hash[(iflist[-2], iflist[-1])] = ['\n'] # output first two words w1, w2 = iflist[0:2] print w1, w2, # generate new words from hash word_num = 0 while w2 <> '\n' and word_num < word_max: w1, w2 = w2, random.choice(word_hash[(w1, w2)]) print w2, word_num += 1 ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] newbie code review please!
On Sun, Feb 03, 2008 at 04:35:08PM -0500, Kent Johnson made several helpful suggestions: Thanks! That cleaned up a lot. However, I couldn't figure out a way to do random.choice(word_hash[(w1, w2)]) on a dict with set-type values. The closest I could get was word_hash[(w1, w2)].pop(), but then I need to add a few lines to put the value back into the set afterwards. Is there a way to randomly lookup a value in a set without removing it from the set? I had better success with collections.defaultdict(list), as pasted below. Cheers, Tyler #! /usr/bin/python2.5 import sys, random, collections word_max = 1000 # Read in file infile = open(sys.argv[1], 'r') ifstring = infile.read() # break file into words iflist = ifstring.split() # build hash of form (prefix1, prefix2): [word] word_hash = collections.defaultdict(list) for i in range(len(iflist) - 2): tk = tuple(iflist[i:i+2]) tv = iflist[i+2] if tv not in word_hash[tk]: word_hash[tk].append(tv) word_hash[(iflist[-2], iflist[-1])].append('\n') # output first two words w1, w2 = iflist[0:2] print w1, w2, # generate new words from hash for word_num in range(word_max): w1, w2 = w2, random.choice(word_hash[(w1, w2)]) print w2, if w2 == '\n': break ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] results not quite 100 percent yet
On 2008-02-21, bhaaluu <[EMAIL PROTECTED]> wrote: > On Thu, Feb 21, 2008 at 7:32 AM, Kent Johnson <[EMAIL PROTECTED]> wrote: >> >> > Other beginning programers shouldn't have any problems using >> > these routines. >> >> As long as they use the same number of rooms and entrance and exit >> rooms, or they know the places to make the magic edits... >> >> Kent >> > > > What? You show me what you're talking about, and I'll run it through my > test script. Your 'clarity' solution should be easily dropped in to replace > the two routines that already work 100% of the time already. > Python please. > The reorganization should be for 'clarity' (a Noob should be able to > understand > it, and port it easily to other games that have more or less rooms > [will they have > to make any magic edits anywhere]. Oh, and these clarity routines should be > shorter (in length?). Not shorter, but definitely clearer would be to replace your magic numbers with variables: entrance = 6 exit = 11 death_room = 13 Replacing each occurrence of those numbers in your code with the variables means you only have to make one change that propagates through the entire program if you change the map layout. It also means that if you're reading your code in a year you won't have to remember that '6' means something special in this context. I'm just a novice python programmer, but it's a good rule of thumb to avoid magic numbers in any language. Tyler ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] results not quite 100 percent yet
On 2008-02-20, bhaaluu <[EMAIL PROTECTED]> wrote: > As far as I can see, these routines give me the results > I'm looking for. I get a distribution of four negative numbers, > four positive integers in the range 10 to 110, and nothing > is placed in room 6 or room 11: > Just for the hell of it, here's my stab at the problem. Note that your spec doesn't match your code, as there's something special about room 13, which is also excluded from this process. Also, since you appear to be adding treasure and aliens to the same cell in each list, I've rolled the procedure up into a single while loop. The algorithm, such as it is, is just four lines to build a list of modifiable rooms and a list of additions, and a four line loop that does the work. As I said, I'm new to Python, so I suspect someone who knows how to use list comprehensions or generators could clean it up further. Also, the tmp = random.choice() bit might be replaceable by some kind of random.pop() thing, but I couldn't figure that out. That would cut the last line out of the loop. Not the short is better than clear, but I don't think this is very complicated, and it takes advantage of Python's listy goodness. My 2 cents! Tyler import random entrance = 6 exit = 11 death_room = 13 table= [[ 0, 2, 0, 0, 0, 0, 0], [ 1, 3, 3, 0, 0, 0, 0], [ 2, 0, 5, 2, 0, 0, 0], [ 0, 5, 0, 0, 0, 0, 0], [ 4, 0, 0, 3,15,13, 0], [ 0, 0, 1, 0, 0, 0, 0], [ 0, 8, 0, 0, 0, 0, 0], [ 7,10, 0, 0, 0, 0, 0], [ 0,19, 0, 0, 0, 8, 0], [ 8, 0,11, 0, 0, 0, 0], [ 0, 0,10, 0, 0, 0, 0], [ 0, 0, 0,13, 0, 0, 0], [ 0, 0,12, 0, 5, 0, 0], [ 0,15,17, 0, 0, 0, 0], [14, 0, 0, 0, 0, 5, 0], [17, 0,19, 0, 0, 0, 0], [18,16, 0,14, 0, 0, 0], [ 0,17, 0, 0, 0, 0, 0], [ 9, 0, 0,16, 0, 0, 0]] room_list = range(0,19) ## the list of rooms to modify ## exclude the special rooms: for i in [entrance, exit, death_room]: room_list.remove(i) ## build a list of random treasure and four aliens: additions = random.sample(range(10,110), 3) additions.extend(range(-4,0)) while (additions): ## continue until all additions are added tmp = random.choice(room_list) ## randomly pick a room if table[tmp][6] == 0: table[tmp][6] = additions.pop() ## add a value room_list.remove(tmp) ## don't pick the same room twice! ## not strictly necessary for i in table: print i ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] noob python cgi
Hi, I'm writing a webpage as a learning exercise. My first objective is to allow myself to upload files to directories in /images/, and have cgi scripts automatically generate the pages that will allow users to navigate through the images. I have a very basic prototype that does what I want, at least for a website served by Apache on my laptop (not web-accessible). Any comments or feedback on the sanity of this approach, or ways to improve it generally would be appreciated! I understand what I've done, but I have no idea what other approaches there might be. I'd like to avoid a complicated CMS at this point, as I want to learn about the basics of serving up webpages. Three files follow. First, the html index page, followed by the gallery picker, followed by the thumbnail displayer. Thanks! Tyler index: My home page Home Only one thing to do - visit the http://localhost/tycgi-bin/gallery.py";>galleries. gallery picker: #! /usr/bin/python import cgitb; cgitb.enable() import cgi, os print """Content-type: text/html Galleries Select a gallery: """ for gal in os.listdir("../images/"): print '%s' % gal print """ """ thumbviewer: #! /usr/bin/python import cgitb; cgitb.enable() import cgi, os form = cgi.FieldStorage() gal = form["gallery"].value print """Content-type: text/html """ print '%s' % gal print""" %s gallery:""" % gal for file in os.listdir("".join(("../images/", gal))): print 'http://localhost/~tyler/images/%s/%s";>' % (gal, file) print "" ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] noob python cgi
On 2008-03-16, Luke Paireepinart <[EMAIL PROTECTED]> wrote: > Tyler Smith wrote: >> Hi, >> [snip explanation] >> Three files follow. First, the html index page, followed by the >> gallery picker, followed by the thumbnail displayer. >> >> Thanks! >> >> Tyler >> [snip code] >> > In the future please include your code as attachments, to avoid e-mail > programs mangling the code, unless it's just a few lines. Not to be obtuse, but what did you see? I sent plain ascii text, no tabs, so I'm not sure what there was that an email program might want to mangle. Tyler ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor