Re: [Tutor] Question about classes
On Aug 25, 2007, at 12:59 PM, Ara Kooser wrote: > Hello all, > >I am working on trying to understand classes by creating a > character generator for a rpg. I know I am doing something silly but I > am not sure what. When I run the program I and type no when prompted I > get the following message: > Traceback (most recent call last): > File "/Users/ara/Documents/ct_generator.py", line 10, in > class Main: > File "/Users/ara/Documents/ct_generator.py", line 68, in Main > reroll() > File "/Users/ara/Documents/ct_generator.py", line 53, in reroll > upp() > NameError: global name 'upp' is not defined > > I guess it doesn't recognize that I want to call the function upp() > again. I think I might be using the wrong syntax here. My code is > below. Thank you any help or guidance. This is exactly the level I'm at right now, so I got all excited and tried to solve this properly. Unfortunately I've hit a new snag, which I hope the OP or someone else can help me solve. At least the below should represent progress. Instead of calling general methods inside your class, you'll want to use the __init__ method, and then call the other methods from inside that, so that when a new instance of the class is created, all the methods act on that one new instance. That's what the first response was saying. So under __init__ we create a dictionary of attributes, and run both __upp and __career, all on the one new object. Showstats might as well be a separate function, because you'll want that available to players at any time. The new problem is the while loop inside __upp. Every time I say "no", and it generates a new set of attributes, it seems to add another "layer" of unfinished = True, so that once I've got attributes I like, I need to say "yes" as many times as I said "no" before it will let me break out of the loop and go on my way. I guess this is because it's calling the entire method over again, but I don't really understand this, or how else to get around it. Any solutions (and, obviously, general corrections of the whole thing) would be appreciated. Yrs, Eric == import random class Character(object): """Welcome to the Classic Traveller character generator. Written in Python """ def __init__(self): print "Generating statistics for your new character..." self.atts = {} self.__upp() self.__career() def __upp(self): for att in ('strength', 'dexterity', 'endurance', 'intelligence', 'education', 'social'): self.atts[att] = random.randrange(2,12) self.showstats() unhappy = True while unhappy: a = raw_input("Are you satisfied with your UPP? Choose yes or no.").lower() if a == "yes": unhappy = False elif a == "no": print "Rerolling attributes..." self.__upp() else: print "Please choose a valid option." continue return def __career(self): print "This is where the next step would go" def showstats(self): print "Your character's attributes are:" for attribute, value in self.atts.items(): print "%s: %d" % (attribute.title(), value) me = Character() ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Question about classes
> Welcome to the wacky world of recursion. > You call __upp from inside __upp so you do indeed generate > a new layer, in fact you start a new while loop. You need to > move the while loop out into init, something like this: So all those "yes"s were actually backing out of multiple while loops... Should have guessed that calling a method from inside itself was a bad idea. Thanks for your help, E ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] sorting lists in dictionary values
I wrote the stupid little script below for practice; it takes a text file with a list of surnames, and returns a dictionary where the keys are first letters of the names, and the values are lists of names grouped under their appropriate first-letter key, like so: {'A': ['Abercrombie'], 'B': ['Barnaby', 'Black', 'Biggles'], 'D': ['Douglas', 'Dawn', 'Diggle'], 'G': ['Granger', 'Gossen']} This is all well and good, but I want to sort the names in place, so that the names in each list are alphabetical. I tried slapping a sort () onto the dictionary list comprehension in every configuration I could think of. I even replaced the one-line comprehension with a two- step deal, like so: for item in letters: little_list = [name for name in names if name.startswith(item)] phonebook[item] = little_list.sort() That didn't work either, which I thought was very strange. Can anyone help? Another tangential question: why can't I do away with having a separate names = [] list variable, and write the comprehension as: for item in letters: phonebook[item] = [line.strip('\n') for line in x if line.startswith (item)] Many thanks, Eric x = file('/path/to/file.txt', 'r') letters = set() names = [] phonebook = {} for line in x: y = line[0].upper() letters.add(y) names.append(line.strip('\n ')) for item in letters: phonebook[item] = [name for name in names if name.startswith(item)] print phonebook ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting lists in dictionary values
> From noob to noob : sort sorts in place. I seem to remember it > returns nothing. > > This works: > > In [12]: directoryOut[12]: > {'A': ['Abercrombie', 'Aalberg'], > 'B': ['Barnaby', 'Black', 'Biggles'], > 'D': ['Douglas', 'Dawn', 'Diggle'], > 'G': ['Granger', 'Gossen']} > > In [13]: for key in directory: >directory[key].sort() > > In [14]: directory > Out[14]: > {'A': ['Aalberg', 'Abercrombie'], > 'B': ['Barnaby', 'Biggles', 'Black'], > 'D': ['Dawn', 'Diggle', 'Douglas'], > 'G': ['Gossen', 'Granger']} > > Please let me know if I'm wrong! > > Best > > Chris Beautiful, that works perfectly. A single line added to the list comprehension: for item in letters: phonebook[item] = [name for name in names if name.startswith(item)] phonebook[item].sort() and all is well. Thanks for the help, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting lists in dictionary values
Whoa, this made my brain hurt. And I thought I was being clever using a set... I can't say I really understand this yet, but I'm trying. If anyone's following along at home I found this link kind of helpful: http://python.net/crew/mwh/hacks/setdefault.html Thanks a lot for your help, Eric > Try this : > > nameFile = open(r'/path/to/file.txt', 'rU') > phonebook = {} > > for line in nameFile : > phonebook.setdefault(line[0].upper(), []).append(line.strip('\n')) > > for item, names in phonebook.iteritems() : > names.sort() > > print phonebook > > HTH > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] tagging pieces of information
On Aug 28, 2007, at 11:07 AM, Che M wrote: > I don't know if there are any preexisting Python structures which > would help > with this or if it has to be done by scratch, or if it is easy or > difficult. > I also don't know what are good ideas for ways to save the tags, > whether > in a text file, in a database (if so, comma separated in one > cell?), or some > other means, and how to associate them with the data chunk they > refer to, > and lastly how to search for them. My first thought would be to create a class for your 'data chunks', and then make 'tags' a class attribute that is created empty on initialization. The basic code would look like: class Data_chunk(object): def __init__(self): self.tags = set() Then every time you create a new data chunk like so: my_data = Data_chunk() You can add, remove and search for tags using the set methods (I made it a set because that seemed appropriate to a tagging feature, you could use a list or something else): my_data.tags.add('dogs') my_data.tags.add('cats') if 'dogs' in my_data.tags: print "It's about dogs" my_data.tags.remove('dogs') print my_data.tags The pickle module is usually simplest and most convenient for long- term data storage. Enjoy! E ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Accessing Values of specific column in a 2D list or array
> grid = [[1,1,2,7,6,9],\ > [,9,1,1,1,9,1],\ > [8,1,2,0,0,4],\ > [1,4,1,1,8,5]] > > how can i access to all the elements of the list from column no. 5. > > output should be like [6,9,0,8]... Your basic tool is sub-indexing: you can reach items in the sub-lists by using grid[x][x]. So use a 'for' loop to get sub-index four of every item in grid. The most compact way is with a list comprehension: grid = [[1,1,2,7,6,9],[9,1,1,1,9,1],[8,1,2,0,0,4],[1,4,1,1,8,5]] fifth_col = [grid[x][4] for x in range(len(grid))] print fifth_col There might be a more graceful replacement for the range(len(grid)) part. Yrs, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Accessing Values of specific column in a 2D list or array
> > COL = 5 > [i[COL-1] for i in grid] Should have guessed... ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] class awareness of variable name
When instantiating a class, is it possible for that instance to 'know' (via the __init__ method, I suppose) the name of the variable it's been assigned to? Thanks E ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class awareness of variable name
On Sep 17, 2007, at 7:21 PM, Alan Gauld wrote: > > "Eric Abrahamsen" <[EMAIL PROTECTED]> wrote > >> When instantiating a class, is it possible for that instance to >> 'know' (via the __init__ method, I suppose) the name of the variable >> it's been assigned to? > > > Presumably you have a reason for asking this? > If you tell us what you are trying to do we might be able to > come up with a more conventional solution. To be honest, I was mostly curious, as I couldn't think of a good way to do it. I was thinking of cleaner ways of giving an instance a 'name' attribute than instance_name = Class('instance_name') in which the instance_name is repeated, and could be mistyped. I know there are problems with multiple bindings, which is why I was thinking of doing it with the __init__ method, in which case you'd get the first variable name and then none other (even if it was later unbound from the original variable). In the end, though, I was mostly curious by which mechanism you could get the variable name 'inside' the class workings. How do you pass it in as a string? Thanks!, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class awareness of variable name
> This is pretty hard. For one thing, the object will not be bound to > a name until after __init__() is finished. Ah, that's a good thing to know... > you could probably use the stack frame to find the point of call > and inspect the byte codes there to find the name... I was afraid the answer would be something like that! I will be content with the normal way of doing things then. Thanks for the explanation. Yours, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] reading POST method in cgi script
I'm trying to learn the fundamentals of cgi scripting, before moving on to actually using the cgi module and, eventually, mod_python. I've grasped that, if users submit a form to my cgi script, I can read the form contents from os.environ['QUERY_STRING'] if it was stuck in the URL via method=get, and from sys.stdin if it was sent via method=post. The get method works fine, but when it comes to post I can't actually read anything off sys.stdin. What's particularly odd is that in my test script below, the returnform() function should only be called if len(sys.stdin.read())!=0, and yet when I submit a word and the script runs returnform(), it tells me that len(sys.stdin.read()) is equal to 0. If that's the case, how did returnform() get called in the first place? Why didn't it just re-run printform()? At first I tried printing each line of sys.stdin to the HTML page, so I could see the details of how post works. Nothing was printed, and that's when I tried using len() to see whether sys.stdin contained anything. Then, thinking that stdin was getting reset somehow, I tried calling returnform() and directly passing in stdin as a parameter. That had the same result. Now, I'm thoroughly confused... Any help would be much appreciated. Yours, Eric #!/Library/Frameworks/Python.framework/Versions/Current/bin/python import sys import cgitb;cgitb.enable() def main(): if len(sys.stdin.read())!=0: returnform() else: printform() def printform(): print "Content-Type: text/html\n\n" print """ Send us a word. """ def returnform(): print "Content-Type: text/html\n\n" print """ Here's what results for standard in:""" print "Length of stdin is %s" % len(sys.stdin.read()) print """ """ main() ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] reading POST method in cgi script
Thanks for the detailed help. I'm dumping sys.stdin into a variable at the very start now, and operating on that variable for everything else, and all is well. Thanks again, E On Oct 16, 2007, at 12:22 PM, Luke Paireepinart wrote: > Eric Abrahamsen wrote: >> I'm trying to learn the fundamentals of cgi scripting, before >> moving on to actually using the cgi module and, eventually, >> mod_python. I've grasped that, if users submit a form to my cgi >> script, I can read the form contents from os.environ >> ['QUERY_STRING'] if it was stuck in the URL via method=get, and >> from sys.stdin if it was sent via method=post. >> >> The get method works fine, but when it comes to post I can't >> actually read anything off sys.stdin. > Yeah, you can. >> What's particularly odd is that in my test script below, the >> returnform() function should only be called if len(sys.stdin.read >> ())!=0, and yet when I submit a word and the script runs >> returnform(), it tells me that len(sys.stdin.read()) is equal to >> 0. If that's the case, how did returnform() get called in the >> first place? Why didn't it just re-run printform()? >> > Because you're confused about what sys.stdin.read() does. > Imagine stdin is a string: > "Hello, Eric!" > now if I call > sys.stdin.read(5) > it will return > "Hello," > and the contents of sys.stdin.read() will now be > " Eric!" > or, to be more accurate, the current-position pointer will be set > to offset 5, so that future reads will start at that position. > > To understand why they would do it this way, consider you want to > read in 5 characters at a time from a file. > Say the file is 6 GB. If you were to read in the whole file and > loop over it 5 characters at a time, > you'd probably overflow your memory. > However, if you tell the OS you want to open the file for reading, > and you then read 5 characters at a time from the file, > you won't have to load everything into memory. This is > accomplished using pointers inside the file, so you know where you > last read. > > Even though sys.stdin in this case is not a file, it works the same > way, because it's a "File-Like Object." > Python uses Duck Typing, wherein the feature set of a particular > item determines its type, rather than something arbitrary you define. > So if any item has read(), write(), and seek() methods, you can > usually use these in place of file objects. > This is true no matter what your functions actually do. > In other words, your read() function could just count how many > times it's called, but do nothing with the value, or anything else > you may want it to do. >> At first I tried printing each line of sys.stdin to the HTML page, >> so I could see the details of how post works. Nothing was >> printed, and that's when I tried using len() to see whether >> sys.stdin contained anything. Then, thinking that stdin was >> getting reset somehow, > It's not getting reset, really. >> I tried calling returnform() and directly passing in stdin as a >> parameter. That had the same result. > Usually when you get to the point where you're trying random things > hoping something will work, > you've reached the time when you either sleep on it or ask someone > for help. > Even if you reach a solution through exhaustive testing, you still > haven't learned anything, which is pretty useless to you in the > long run. >> Now, I'm thoroughly confused... >> > Don't worry about it. It's good you asked. >> Any help would be much appreciated. >> >> Yours, >> Eric >> >> >> >> #!/Library/Frameworks/Python.framework/Versions/Current/bin/python >> import sys >> import cgitb;cgitb.enable() >> >> def main(): >> if len(sys.stdin.read())!=0: >> > This is your problem right here. > len(sys.stdin.read()) is calling len() on a string returned by > sys.stdin.read() > As mentioned earlier, calling this function sets the current- > location pointer to one after the last-read position. > Since you passed no maximum to read(), the whole stdin contents > were read into this variable, leaving > the pointer at the end of the file. Thus on subsequent calls, > sys.stdin.read() will return nothing. > Try changing this to len(sys.stdin.read(3)) and then pass your > program a string longer than 3 characters. > Your length output in returnform should then be 3 l
Re: [Tutor] Obtaining image date of creation
On Nov 14, 2007, at 9:05 PM, Kent Johnson wrote: > Roy Chen wrote: >> Hello, >> >> I would like to write a simple script that would rename a bunch of >> photos according to their creation date, i.e. the date which the >> photo was taken. >> >> Is there a way to use Python to obtain that information from the >> image file, or is that information not stored in the file? > > os.path.getctime() works on Windows, I'm not clear what it reports > on *nix. > Or you can use the Python Imaging Library (http://www.pythonware.com/ products/pil/) and get ALL the information! E ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Obtaining image date of creation
> And while I haven't tried it, this page (http://effbot.org/zone/pil- > changes-114.htm) appears to indicate exif format is somewhat > supported in PIL; perhaps pyexif does a better job though? PIL does a pretty job, though it's a pain. from PIL import Image from PIL.ExifTags import TAGS def get_exif(fn): ret = {} i = Image.open(fn) info = i._getexif() for tag, value in info.items(): decoded = TAGS.get(tag, tag) ret[decoded] = value return ret I found this here: http://wolfram.kriesing.de/blog/index.php/2006/ reading-out-exif-data-via-python ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] subclassing strings
I'm playing around with subclassing the built-in string type, and realizing there's quite a bit I don't know about what's going on with the built-in types. When I create a string like so: x = 'myvalue' my understanding is that this is equivalent to: x = str('myvalue') and that this second form is more fundamental: the first is a shorthand for the second. What is 'str()' exactly? Is it a class name? If so, is the string value I pass in assigned to an attribute, the way I might create a "self.value =" statement in the __init__ function of a class I made myself? If so, does that interior attribute have a name? I've gone poking in the python lib, but haven't found anything enlightening. I started out wanting to subclass str so I could add metadata to objects which would otherwise behave exactly like strings. But then I started wondering where the actual value of the string was stored, since I wasn't doing it myself, and whether I'd need to be careful of __repr__ and __str__ so as not to interfere with the basic string functioning of the object. As far as I can tell the object functions normally as a string without my doing anything – where does the string value 'go', and is there any way I might inadvertently step on it by overriding the wrong attribute or method? Thanks for any insight, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] subclassing strings
Thanks both of you, that cleared a lot of things up. On Jan 9, 2008, at 11:49 AM, Kent Johnson wrote: > > No, you can't access the actual byte array from Python and you can't > damage it. I don't know a lick of C and probably never will, but I do like to know what it is, exactly, that I don't know, and this is nice. I'll stop worrying about stepping on the actual value of the strings. On Jan 9, 2008, at 11:48 AM, Tiger12506 wrote: > def __str__(self): > return self > def __repr__(self): > return "'%s'" % self #Notice this will give extra single quotes > around string Excellent, this was very helpful. I know about the str() vs .__str__() equivalence, but had never seen what these two functions were actually doing under the hood. What I wasn't figuring out was passing the string value of my custom string class into the constructor of the actual str type, rather than rerouting it into a data attribute of my custom class. So now I've got this, for example: class StampedString(str): def __init__(self, val): super(StampedString, self).__init__(val) import datetime self.timestamp = datetime.datetime.now() so that this: x = StampedString('This is a time-stamped string') works exactly like a string, apart from the metadata. At least, I think I've understood this correctly... Thanks again for the interesting explanations. Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] PIL: preserving exif data
Can any PIL people out there tell me if it's possible to save a jpeg image with exif data? I'm opening an image file, making changes to it, and then resaving it: apparently calling save() chops off its exif data, and there doesn't appear to be a way to re-attach it via a parameter to the save function. Has anyone run into this problem before? Thanks, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] new guy problem, what's wrong with this program.
mumber = 23 running = Ture Both these lines have spelling errors: 'mumber' should be 'number', and 'Ture' should be 'True'. You can see where the problem is coming from by the end of your traceback: NameError: name 'Ture' is not defined A NameError with something being 'not defined' nine times of ten means you've spelled something wrong. Good luck! Eric___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Programming Ideas, need some focus
Hey, on this topic, I spent some time this afternoon googling the One Laptop Per Child (OLPC) project (the GUI is done with Python and PyGTK), to see if there were any collaborative open-source projects I could contribute to. Seems like a perfect opportunity to get a little more Python experience and actually do something useful. I found lots of noble exhortations to help, but very little in the way of specifics. Does anyone know of any ongoing projects that could use volunteers? Of the middling-capable range? Eric On Jan 16, 2008, at 9:29 PM, Michael Langford wrote: > There are programming contests you can enter. I don't know of any more > still running past these two (but would love to hear of more): > > Sphere Online Judge: > http://www.spoj.pl/problems/classical/ > > Topcoder's Development Contests: > http://www.topcoder.com/tc?module=ViewActiveContests&ph=113 > > --Michael > > > On 1/16/08, Fiyawerx <[EMAIL PROTECTED]> wrote: >> I've been over google for hours now, and I'm sort of at a lull in my >> learning, as I don't really have a current "goal". I know I could >> set some >> easy goal like to learn a specific function or feature, but I still >> have a >> hard time with that approach also. I was wondering if anyone knows >> of any >> sites where people might request "projects" almost like rentacoder, >> but for >> free stuff and/or just for fun. Almost an 'It would be nice if I >> had a >> program that did this.. " type of thing to give me some direction. >> Or does >> anyone else have any ideas for some types of programs that might >> actually >> prove useful to people for beginners to work on? >> >> ___ >> Tutor maillist - Tutor@python.org >> http://mail.python.org/mailman/listinfo/tutor >> >> > > > -- > Michael Langford > Phone: 404-386-0495 > Consulting: http://www.RowdyLabs.com > ___ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Programming Ideas, need some focus
I'm on a Mac, and it seems the current advice for Sugar emulation on the Mac is "come back next year, or the year after"... I did get PyGTK working, tho. On Jan 16, 2008, at 10:13 PM, Michael Langford wrote: > No, but this is quite useful for getting it up and going on your PC: > http://wiki.laptop.org/go/OS_images_for_emulation > > I was looking at Metropolis (the non-TM version of SimCity) as its gui > is all written in python > > --Michael > > > > On 1/16/08, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: >> Hey, on this topic, I spent some time this afternoon googling the One >> Laptop Per Child (OLPC) project (the GUI is done with Python and >> PyGTK), to see if there were any collaborative open-source projects I >> could contribute to. Seems like a perfect opportunity to get a little >> more Python experience and actually do something useful. I found lots >> of noble exhortations to help, but very little in the way of >> specifics. Does anyone know of any ongoing projects that could use >> volunteers? Of the middling-capable range? >> >> Eric >> >> On Jan 16, 2008, at 9:29 PM, Michael Langford wrote: >> >>> There are programming contests you can enter. I don't know of any >>> more >>> still running past these two (but would love to hear of more): >>> >>> Sphere Online Judge: >>> http://www.spoj.pl/problems/classical/ >>> >>> Topcoder's Development Contests: >>> http://www.topcoder.com/tc?module=ViewActiveContests&ph=113 >>> >>> --Michael >>> >>> >>> On 1/16/08, Fiyawerx <[EMAIL PROTECTED]> wrote: >>>> I've been over google for hours now, and I'm sort of at a lull in >>>> my >>>> learning, as I don't really have a current "goal". I know I could >>>> set some >>>> easy goal like to learn a specific function or feature, but I still >>>> have a >>>> hard time with that approach also. I was wondering if anyone knows >>>> of any >>>> sites where people might request "projects" almost like rentacoder, >>>> but for >>>> free stuff and/or just for fun. Almost an 'It would be nice if I >>>> had a >>>> program that did this.. " type of thing to give me some direction. >>>> Or does >>>> anyone else have any ideas for some types of programs that might >>>> actually >>>> prove useful to people for beginners to work on? >>>> >>>> ___ >>>> Tutor maillist - Tutor@python.org >>>> http://mail.python.org/mailman/listinfo/tutor >>>> >>>> >>> >>> >>> -- >>> Michael Langford >>> Phone: 404-386-0495 >>> Consulting: http://www.RowdyLabs.com >>> ___ >>> Tutor maillist - Tutor@python.org >>> http://mail.python.org/mailman/listinfo/tutor >> >> ___ >> Tutor maillist - Tutor@python.org >> http://mail.python.org/mailman/listinfo/tutor >> > > > -- > Michael Langford > Phone: 404-386-0495 > Consulting: http://www.RowdyLabs.com > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Programming Ideas, need some focus
> Any takers? Eric on the mac side? Some other windows user on the > windows side? I guarantee OLPC will be running on your computer by the > end of this. I'll give this a shot this Saturday – I ought to be an ideal test candidate since I'm more or less an installation/configuration idjit. I'll let you know how it goes. Will it conflict with an existing pyGTK installation? Both Snakes and Ladders and the pipelines thing sound potentially interesting, I'll get back to you guys in a couple days... Thanks! Eric > > > --Michael > > On 1/16/08, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: >> I'm on a Mac, and it seems the current advice for Sugar emulation on >> the Mac is "come back next year, or the year after"... I did get >> PyGTK >> working, tho. >> >> >> On Jan 16, 2008, at 10:13 PM, Michael Langford wrote: >> >>> No, but this is quite useful for getting it up and going on your PC: >>> http://wiki.laptop.org/go/OS_images_for_emulation >>> >>> I was looking at Metropolis (the non-TM version of SimCity) as its >>> gui >>> is all written in python >>> >>> --Michael >>> >>> >>> >>> On 1/16/08, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: >>>> Hey, on this topic, I spent some time this afternoon googling the >>>> One >>>> Laptop Per Child (OLPC) project (the GUI is done with Python and >>>> PyGTK), to see if there were any collaborative open-source >>>> projects I >>>> could contribute to. Seems like a perfect opportunity to get a >>>> little >>>> more Python experience and actually do something useful. I found >>>> lots >>>> of noble exhortations to help, but very little in the way of >>>> specifics. Does anyone know of any ongoing projects that could use >>>> volunteers? Of the middling-capable range? >>>> >>>> Eric >>>> >>>> On Jan 16, 2008, at 9:29 PM, Michael Langford wrote: >>>> >>>>> There are programming contests you can enter. I don't know of any >>>>> more >>>>> still running past these two (but would love to hear of more): >>>>> >>>>> Sphere Online Judge: >>>>> http://www.spoj.pl/problems/classical/ >>>>> >>>>> Topcoder's Development Contests: >>>>> http://www.topcoder.com/tc?module=ViewActiveContests&ph=113 >>>>> >>>>> --Michael >>>>> >>>>> >>>>> On 1/16/08, Fiyawerx <[EMAIL PROTECTED]> wrote: >>>>>> I've been over google for hours now, and I'm sort of at a lull in >>>>>> my >>>>>> learning, as I don't really have a current "goal". I know I could >>>>>> set some >>>>>> easy goal like to learn a specific function or feature, but I >>>>>> still >>>>>> have a >>>>>> hard time with that approach also. I was wondering if anyone >>>>>> knows >>>>>> of any >>>>>> sites where people might request "projects" almost like >>>>>> rentacoder, >>>>>> but for >>>>>> free stuff and/or just for fun. Almost an 'It would be nice if I >>>>>> had a >>>>>> program that did this.. " type of thing to give me some >>>>>> direction. >>>>>> Or does >>>>>> anyone else have any ideas for some types of programs that might >>>>>> actually >>>>>> prove useful to people for beginners to work on? >>>>>> >>>>>> ___ >>>>>> Tutor maillist - Tutor@python.org >>>>>> http://mail.python.org/mailman/listinfo/tutor >>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> Michael Langford >>>>> Phone: 404-386-0495 >>>>> Consulting: http://www.RowdyLabs.com >>>>> ___ >>>>> Tutor maillist - Tutor@python.org >>>>> http://mail.python.org/mailman/listinfo/tutor >>>> >>>> ___ >>>> Tutor maillist - Tutor@python.org >>>> http://mail.python.org/mailman/listinfo/tutor >>>> >>> >>> >>> -- >>> Michael Langford >>> Phone: 404-386-0495 >>> Consulting: http://www.RowdyLabs.com >>> >> >> ___ >> Tutor maillist - Tutor@python.org >> http://mail.python.org/mailman/listinfo/tutor >> > > > -- > Michael Langford > Phone: 404-386-0495 > Consulting: http://www.RowdyLabs.com > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] if ... else shorthand form ?
> Hi all, > > Returning to python after a brief affair with C++, I have the > following code ... > >if (items.has_keys('snapshot_interval')): >self.snap_init[i] = items['snapshot_interval'] >else: >self.snap_init[i] = 0 > > I thought Python had a shorthand version of something like > >self.snap_init[i] = > (items.has_keys('snapshot_interval'))?items['snapshot_interval']:0 I believe the idiom here is var = value if condition else otherValue So you'd want self.snap_init[i] = items['snapshot_interval'] if items.has_keys('snapshot_interval') else 0 Yours, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] sorting objects on two attributes
I have a grisly little sorting problem to which I've hacked together a solution, but I'm hoping someone here might have a better suggestion. I have a list of objects, each of which has two attributes, object_id and submit_date. What I want is to sort them by content_type, then by submit_date within content_type, and then sort each content_type block according to which block has the newest object by submit_date. (This sequence of sorting might not be optimal, I'm not sure). I'm actually creating a list of recent comments on blog entries for a python-based web framework, and want to arrange the comments according to blog entry (content_type), by submit_date within that entry, with the entries with the newest comments showing up on top. I don't believe a single cmp function fed to list.sort() can do this, because you can't know how two objects should be compared until you know all the values for all the objects. I'd be happy to be proven wrong here. After some false starts with dictionaries, here's what I've got. Queryset is the original list of comments (I'm doing this in django), and it returns a list of lists, though I might flatten it afterwards. It works, but it's ghastly unreadable and if there were a more graceful solution I'd feel better about life in general: def make_com_list(queryset): ids = set([com.object_id for com in queryset]) xlist = [[com for com in queryset if com.object_id == i] for i in ids] for ls in xlist: ls.sort(key=lambda x: x.submit_date) xlist.sort(key=lambda x: max([com.submit_date for com in x]), reverse=True) return xlist I'd appreciate any hints! Thanks, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting objects on two attributes
Well I expected to learn a thing or two, but I didn't expect not to understand the suggestions at all! :) Thanks to everyone who responded, and sorry for the typo (it was meant to be object_id throughout, not content_type). So far Michael's solution works and is most comprehensible to me – ie I stand a fighting chance of figuring it out. I didn't realize you could make direct use of SortedDicts in django, so that's worth a try, too. Itertools.groupby is totally impenetrable to me, but works as well! Is there any consensus about which might go faster? I will go right now and google until my brain is full. Thanks again, Eric On Mar 4, 2008, at 12:56 AM, Michael H. Goldwasser wrote: > > > Hello Eric, > > Your basic outlook is fine, but you can do it much more efficiently > with a single sort. Here's the way I'd approach the task > (untested): > > # -- > # first compute the latest date for each id group; uses O(n) time > newest = {} > for q in queryset: > id,date = q.object_id, q.submit_date > if id not in newest or date > newest[id]: > newest[id] = date > > # now sort based on the following decorator as a key > data.sort(reverse=True, key=lambda x: (newest[x.object_id], > x.object_id, x.submit_date)) > # -- > > In essence, you compute the max date within each group, but your > approach (i.e., building explicit sublists and then repeatedly > calling max on those sublists) is far more time-consuming than the > above dictionary based approach. > > Note well that using a tuple as a decorator key is more efficient > than calling sort separately for each subgroup. The > lexicographical order of the following > >(newest[x.object_id], x.object_id, x.submit_date) > > should produce the order that you desire. The reason for the middle > entry is to ensure that items groups by object_id in the case that > two different groups achieve the same maximum date. It wasn't clear > to me whether you wanted elements within groups from oldest to > newest or newest to oldest. I believe that the code I give produces > the ordering that you intend, but you may adjust the sign of the > decorate elements if necessary. > > With regard, > Michael > > +--- > | Michael Goldwasser > | Associate Professor > | Dept. Mathematics and Computer Science > | Saint Louis University > | 220 North Grand Blvd. > | St. Louis, MO 63103-2007 > > > On Monday March 3, 2008, Eric Abrahamsen wrote: > >> I have a grisly little sorting problem to which I've hacked >> together a >> solution, but I'm hoping someone here might have a better >> suggestion. >> >> I have a list of objects, each of which has two attributes, >> object_id >> and submit_date. What I want is to sort them by content_type, >> then by >> submit_date within content_type, and then sort each content_type >> block >> according to which block has the newest object by submit_date. >> (This >> sequence of sorting might not be optimal, I'm not sure). I'm >> actually >> creating a list of recent comments on blog entries for a python- >> based >> web framework, and want to arrange the comments according to blog >> entry (content_type), by submit_date within that entry, with the >> entries with the newest comments showing up on top. >> >> I don't believe a single cmp function fed to list.sort() can do >> this, >> because you can't know how two objects should be compared until you >> know all the values for all the objects. I'd be happy to be proven >> wrong here. >> >> After some false starts with dictionaries, here's what I've got. >> Queryset is the original list of comments (I'm doing this in >> django), >> and it returns a list of lists, though I might flatten it >> afterwards. >> It works, but it's ghastly unreadable and if there were a more >> graceful solution I'd feel better about life in general: >> >> >> def make_com_list(queryset): >> ids = set([com.object_id for com in queryset]) >> xlist = [[com for com in queryset if com.object_id == i] for >> i in >> ids] >> for ls in xlist: >> ls.sort(key=lambda x: x.submit_date) >> xlist.sort(key=lambda x: max([com.submit_date for com in x]), >> reverse=True) >> return xlist >> >> I'd appreciate any hints! >> >> Thanks, >> Eric >> > ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting objects on two attributes
On Mar 4, 2008, at 11:04 AM, Kent Johnson wrote: > Eric Abrahamsen wrote: >> Itertools.groupby is totally impenetrable to me > > Maybe this will help: > http://personalpages.tds.net/~kent37/blog/arch_m1_2005_12.html#e69 > > Kent > It did! Thanks very much. I think I understand now what's going on in the groupby line. And then this line: t.append((sorted_part[-1].submit_date, key, sorted_part)) is basically a Decorate-Sort-Undecorate operation, sorting on sorted_part[-1].submit_date because that's guaranteed to be the latest date in each group? It's starting to come clear... ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] web programming tutorials?
On Apr 18, 2008, at 8:01 AM, Hansen, Mike wrote: > IMHO, I think before anyone jumps into using a framework, they should > understand the basics of cgi programming. Maybe do just a small > exercise with simple form processing. After that exercise, then move > on to one of the frameworks that make a lot of that grunt work easier. > Jumping into a framework right away is like trying to run before you > can crawl. There's a lot going on with the many frameworks(URL > mapping, templates, ORM, persistence...). When you have some basic > understanding of web programming, it might help you figure out why > something isn't working properly in the framework. I'm curious about > other tutor list member's thoughts on this. Am I out to lunch on this > viewpoint? I think that's exactly right, and I'd add that if you don't know the bits and bobs of the HTTP protocol, it can also make it difficult to pick up the frameworks. Django was fine for me but I found CherryPy/ Paste/other low-level frameworks very confusing until I realized I didn't really understand how they fit into and handle the mechanisms of HTTP. Doing some background reading helped me see the fundamental similarities between them. Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] syntax question
Hi all, This is a syntax that I've seen on occasion in other people's code: theme = (VALID_THEMES[0], theme) [ theme in VALID_THEMES ] I have no idea how this works, or how to go about looking it up. Can someone enlighten me as to what's happening here? Many thanks, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] get/set attributes
Hello, I'm trying to create a Dummy class of objects, something that will return an empty string for any attribute. I'm making a very simple CMS with Cherrypy/Sqlalchemy/Cheetah, and I have an HTML form template that I use for editing/creating objects to save to the database. I'm using just one form template, and I want to either pass an object from the database to the template (for editing existing objects), or a Dummy object which outputs empty strings for all the HTML form fields, creating a blank form. Additionally, I'd like to be able to pass keyword arguments to the Dummy() initialization which get turned into attributes, so I can output various default values for the form fields. What I've got so far handles non-existent attributes fine, but using keywords to create attributes isn't working (attributes thus set still output an empty string), and I'm not sure why. Here's the class: class Dummy(object): def __init__(self,**atts): for k,v in atts.items(): self.k = v def __repr__(self): return '' def __getattr__(self, attr): return '' >>> dum = Dummy(name='John') >>> dum >>> dum.nationality '' >>> dum.name '' __getattr__ says it only comes into play when an attribute is NOT found, so I must be doing something wrong in the __init__ method... Thanks in advance, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] get/set attributes
This creates an attribute named k; it does not create an attribute whose name is the *value* of k. For that you need setattr: setattr(self, k, v) There is a shortcut that replaces the entire loop: self.__dict__.update(atts) Thanks Kent, that explains a lot about how things work. return an empty string for any attribute. I'm making a very simple CMS with Cherrypy/Sqlalchemy/Cheetah, Those are the components of TurboGears. You might save a lot of bother by using TG instead of trying to write all the glue code yourself. Form handling for one would come for free, as would logins, help pages etc etc. OTOH maybe you are doing this as a learning exercise in which case have at it! :-) I am doing this as a learning exercise, though I hadn't realized those are precisely TG's components. I'm actually coming at this from Django, and wanted to approach things at a lower level (every time a friend asks me to make a website for them I use it as an excuse to learn some new framework components). I wasn't really missing Django until I got to the 'CMS backend' stage of things – forms for models, validation, etc. I'll stick through the learning exercise, but it will be *very* nice to return to a full framework package... Eric -- Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] inheritance/classmethods/metaclasses
I'm probably in over my head here, but I really want to know how this works, and I hope someone will be willing to take a moment to explain it... I'm making a few classes for a very simple ORM, where the classes reflect objects that I'm persisting via pickle. I'd like to add and delete instances via add() and delete() classmethods, so that the classes can keep track of the comings and goings of their instances. My main question is, how can I abstract this classmethod behavior for several classes, either into a metaclass, or a super class? I've done some very scary reading, and some fruitless experimentation, and am over my head. I know the answer is probably "do something else entirely", but I'd really like to know how this is supposed to work. What I'd like is a Model class, which provides an add() classmethod like this: class Model(object): @classmethod def add(cls, *args) inst = cls(args) cls.instances.append(inst) Then, say, a File class: class File(): # inherit from Model, or use Model as a metaclass? instances = [] def __init__(self, *args) self.filename = args[0] self.keyword = args[1] The desired behavior, of course, is this: File.add('somefilename','keywordforthisfile') and to be able to extend this behavior to other classes. Any pointers would be much appreciated... Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] inheritance/classmethods/metaclasses
What you have almost works. Try this: No kidding that's what I get for wild stabs in the dark, I thought I'd tried that. I'm pleased that it really is that simple (and that, whatever metaclasses are used for, I don't need to worry about them yet). Thanks! Eric (Grrr, bit by the reply-to bug. Not that this is really worth re- posting...) ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] TypeError: not enough arguments for format string
On Jul 2, 2008, at 12:36 PM, Christopher Spears wrote: I'm working on problem 13-5 in Core Python Programming (2nd Edition). I am supposed to create point class. Here is what I have so far: #!/usr/bin/python class Point(object): def __init__(self, x=0.0,y=0.0): self.x = float(x) self.y = float(y) def __repr__(self): coord = (self.x,self.y) return coord def __str__(self): point_str = "(%f,%f)" % self.x, self.y return point_str Hi Christopher, The problem's right above here – string formatting takes only one value. If you're trying format more than one string, you have to pass them in as a tuple. Try this: point_str = "(%f,%f)" % (self.x, self.y) def get_x(self): return self.x def get_y(self): return self.y if __name__ == '__main__': print "Creating a point" x = raw_input("Enter a x value: ") y = raw_input("Enter a y value: ") p = Point(x,y) print p I ran the script and got the following error message: Creating a point Enter a x value: 1 Enter a y value: 2 Traceback (most recent call last): File "point.py", line 27, in ? print p File "point.py", line 13, in __str__ point_str = "(%f,%f)" % self.x, self.y TypeError: not enough arguments for format string Does anyone know what is wrong? I'm sure it is something obvious, but I can't see it. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] character encoding
As for other resources, I recently came across this: http://farmdev.com/talks/unicode/ This was the first explanation that really made me understand the difference between Unicode and utf-8 (and realize that I'd been using the terms 'encode' and 'decode' backwards!). Anyway, just one more resource. E On Jul 9, 2008, at 9:32 AM, Kent Johnson wrote: On Tue, Jul 8, 2008 at 5:19 PM, Robert Johansson <[EMAIL PROTECTED]> wrote: Hi, I'm puzzled by the character encodings which I get when I use Python with IDLE. The string '\xf6' represents a letter in the Swedish alphabet when coded with utf8. On our computer with MacOSX this gets coded as '\xc3\xb6' which is a string of length 2. I have configured IDLE to encode utf8 but it doesn't make any difference. I think you may be a bit confused about utf-8. '\xf6' is not a utf-8 character. U00F6 is the Unicode (not utf-8) codepoint for LATIN SMALL LETTER O WITH DIAERESIS. '\xf6' is also the Latin-1 encoding of this character. The utf-8 encoding of this character is the two-byte sequence '\xc3\xb6'. Can you give some more specific details about what you do and what you see? Also you might want to do some background reading on Unicode; this is a good place to start: http://www.joelonsoftware.com/articles/Unicode.html Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] splits and pops
I have a horribly stupid text parsing problem that is driving me crazy, and making me think my Python skills have a long, long way to go... What I've got is a poorly-though-out SQL dump, in the form of a text file, where each record is separated by a newline, and each field in each record is separated by a tab. BUT, and this is what sinks me, there are also newlines within some of the fields. Newlines are not 'safe' – they could appear anywhere – but tabs are 'safe' – they only appear as field delimiters. There are nine fields per record. All I can think to do is read the file in as a string, then split on tabs. That gives me a list where every eighth item is a string like this: u'last-field\nfirst-field'. Now I want to iterate through the list of strings, taking every eighth item, splitting it on '\n', and replacing it with the two resulting strings. Then I'll have the proper flat list where every nine list items constitutes one complete record, and I'm good to go from there. I've been fooling around with variations on the following (assuming splitlist = fullstring.split('\t')): for x in xrange(8, sys.maxint, 8): try: splitlist[x:x] = splitlist.pop(x).split('\n') except IndexError: break The first line correctly steps over all the list items that need to be split, but I can't come up with a line that correctly replaces those list items with the two strings I want. Either the cycle goes off and splits the wrong strings, or I get nested list items, which is not what I want. Can someone please point me in the right direction here? Thanks, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] python environment
I've been looking around for a good tutorial or background info on how the Python runtime environment works, and haven't quite found what I'm looking for. I started fooling with having different versions of modules available to difference processes on a single server, which led me to virtualenv, and then I realized I'm way in over my head. I'm sure I can make virtualenv work, but I won't understand what's happening. Can anyone recommend any resources along these lines? Chapter 26 in the library reference is on Python Runtime Services – these are the models I want to understand, but I feel like what I need is one level _under_ these modules: I guess, how the python interpreter works as an os process, and how its environment differs from... the other environment?. The command line interpreter also has options like 'ignore environment variables' and 'don't imply "import site" on initialization' – I just don't quite get it. Thanks in advance for any and all enlightenment. Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] requests/responses from urllib2
I've got a question about the way urllib2 makes its requests. If I've got a python web framework running behind a web server, and that framework uses urllib2 to make a request to another server, how does that traffic go in and out of my server machine? The python docs say that urllib2 requires the socket library to work, so I assume it's a socket of some sort, but I don't really understand how that socket is addressed, from the point of view of the third-party server that is receiving my urllib2 request, and returning the response. Where does it appear to be coming from? If my web server (lighttpd in this case) is set to listen on a particular port, is there any way that it can 'see' that traffic and interact with it, or is it purely between the python library and the outside world? Thanks for any enlightenment! Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] requests/responses from urllib2
Thanks to you both. I'll read up on sockets, but it seems unlikely that it works the way I thought it might... On Aug 12, 2008, at 8:45 PM, Kent Johnson wrote: On Tue, Aug 12, 2008 at 7:27 AM, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: On Aug 11, 2008, at 6:54 PM, Kent Johnson wrote: I'm not sure if you want to see the traffic coming in from your users, or the traffic from your server to the third-party server. I don't know what kind of interaction you want, either. I'd like to be able to see the response coming back from the third- party server, and have lighttpd check its headers and either intercept it or allow it back into the framework. Say if it's got a text content-type then let it in to the framework, and if it's got an image content-type then ignore it or throw it away. Rephrasing it this way makes it sound pretty unlikely. I guess what I wanted was a better sense of how urllib2 uses a socket to make the request, and how the response, on its way back to my server, finds that socket. I thought that if the socket file was something that hung around between requests, I might be able to configure lighttpd to 'listen in' on that socket, and grab the response if it met certain criteria. But if that were possible then urllib2 would raise an error, right? lighttpd will not see the traffic to the third-party server; the tp server is not making a request of lighttpd; your code is making a request of it. The response comes back on the same socket that was opened by the request; if you want to know how they match up you will have to learn about TCP/IP which is the underlying network protocol. This might help: http://www.amk.ca/python/howto/sockets/ If you want to filter the response according to the headers, you can do that in your code. The response object returned by urllib2 includes an info() method that gives access to the response headers. Kent PS Please Reply All to reply to the list. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] __iter__ loops, partitioning list among children
Hi, I've got a problem that takes a bit of explaining, but it's relatively simple when you get down to it. This is another django-related thing, but the issue itself is pure python. I made a custom class, called an EventEngine, which represents a span of time. You initialize it with a queryset/list of django model instances, and the resulting EventEngine object has an 'events' attribute, which is a queryset/list of model instances that fall within that span of time, according to a datetime attribute on the django model. Next come EventEngine subclasses, representing commonly used spans of time – Month, Week, Day, etc. The EventEngine __iter__ method is overridden so that each of these subclasses, when iterated over, produces child instances of the next smallest EventEngine subclass. Iterating on a Month produces Weeks, iterating on a Week produces Days and so on. As each parent produces its children, the events in the 'events' attribute get partitioned out to the children as appropriate to their date ranges. Right now I'm doing this as stupidly as possible: for each child 'c' in the parent, I loop over all the parent events, and append them to c.events if their date attribute falls within the child's date range: for e in self.events: if c.start <= getattr(e,self.start_attr) < c.stop: c.events.append(e) This is stupid for (at least) two reasons: 1) it evaluates the entire queryset and sticks it in memory with the first child instance, obviating the whole point of an iterable, and 2) it loops over the entire event list for every child, even though the list is already properly sorted by date, and we could break from the loop with the first event that falls outside the child's date range. Performance is important, as some madman could initialize a Year with a huge queryset, and do nested iterations all the way down to Minute. So I've got a few considerations: 1. The parent's events queryset should only be evaluated as much as is needed to yield one child at a time. 2. The parent's events queryset should not be duplicated as it is distributed among the children, ie it should make references and not copies (I don't know how to make sure this happens). 3. I don't want to empty the parent's 'events' list as it is distributed among the children, as other methods depend on the list being there. 4. The events attribute of the 'top level' instance is a django queryset, but it will be a list for all descendent instances (they can be nested arbitrarily deeply). This limits the number of functions available – ie you can't pop() a django queryset. At first I thought the bisect module was the way to go, but it is too tightly tied to integer list indices, and works very awkwardly when bisecting on datetime attributes. List slices produce copies, unless I'm mistaken. Something tells me that a plain old while loop with a break might do the trick, but I can't quite see it clear. Ideally this would be something that starts iterating where the date attribute falls into the right range, and then stops iterating as soon as it passes out of that range. Probably I'll have to settle for just one or the other, but one can dream. Thanks for reading all this. I'm hoping that all the restrictions and conditions will make the solution more obvious, rather than less obvious, to those who know more than I... --Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] __iter__ loops, partitioning list among children
On Aug 24, 2008, at 7:20 PM, Kent Johnson wrote: Forwarding to the list with my reply. Please use Reply All to reply to the list. Grr, sorry, I keep forgetting... On Sun, Aug 24, 2008 at 1:02 AM, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: On Aug 23, 2008, at 11:22 PM, Kent Johnson wrote: On Sat, Aug 23, 2008 at 6:47 AM, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: At first I thought the bisect module was the way to go, but it is too tightly tied to integer list indices, and works very awkwardly when bisecting on datetime attributes. I'm not sure what the problem is with bisect (to find the starting point). Your list of model elements has integer indices. I think you have to write a __cmp__ method for your model class that compares on the datetime attribute, then it should work. You can also create a list of (key, model) and sort/search that. http://www.mail-archive.com/[EMAIL PROTECTED]/msg189443.html The __cmp__ trick is very nice, and would do it, except I won't have access to the events model classes. I could get bisect to work by feeding it a list comprehension, but making the high and low parameters work required integer indices, which seemed like one half-hack too many... I don't understand the issue. *All* lists have integer indices. If you make a list of (key, model) pairs, the keys only need to be comparable, not integers. The main problem is that I don't have any control over the list of models, and all I've got is the name of a datetime attribute to filter by. The only way I could get bisect to work was like this: index = bisect([getattr(x, attr_name) for x in model_list], sentinel_date) But that loops over the whole list, which is what I was trying to avoid. And the only way I could provide high and low parameters to bisect is by calling event_list.index(event), which doesn't work on django querysets. I also experimented with itertools.groupby to produce groups of events, but that turned out to be far slower than simply looping over the whole event list and extracting events which test true for c.start <= getattr(event, attr_name) < c.stop. Ideally I could create a kind of concurrent iterator, that steps through children's blocks of time and the object's event list in tandem, rather than going over the whole events list once for every child produced. Maybe that's not possible... I'm pasting the whole function down below, just for the hell of it. Thanks again, Eric def _iter_children(self, child, require_events=False): """ Iterate through an object's 'child' items. If require_events == True, only return children with events, otherwise return all children. """ while self.sentinel < self.stop: c = child([], self.sentinel, self.start_attr, rolling=self.rolling, counts_only=self.counts_only) for e in self.events: if c.start <= getattr(e,self.start_attr) < c.stop: c.events.append(e) self.sentinel += c.dt_range if not require_events or c.has_events(): yield c ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] __iter__ loops, partitioning list among children
Okay I think I'm onto something, more iterator-related stuff. If I can make self.events an iterator, then run a for loop on it, breaking out of the loop when the events' date attributes get too high. Then on the next run through, that same for loop should pick up where it left off, right? Here's my next version of the function. It doesn't quite work right: when I test it each child instance receives the correct events, but when it passes those events onto its children, they get consumed (or something) and are never actually output. To test I'm instantiating a Month m, filling it with events, then looping like so: for w in m: print w.event_count() for d in w: print d.events w.event_count() produces the right event count, but d.events is always empty. If anyone can see what's wrong with this function... ## def _iter_children(self, child, require_events=False): """ Iterate through an object's 'child' items. If require_events == True, only return children with events, otherwise return all children. """ iterevents = iter(self.events) while self.sentinel < self.stop: c = child([], self.sentinel, self.start_attr, rolling=self.rolling, counts_only=self.counts_only) for e in iterevents: if getattr(e, self.start_attr) < c.stop: c.events.append(e) else: break self.sentinel += c.dt_range if not require_events or c.has_events(): # if require_events == True, omit empty children. yield c On Aug 25, 2008, at 11:49 AM, Eric Abrahamsen wrote: On Aug 24, 2008, at 7:20 PM, Kent Johnson wrote: Forwarding to the list with my reply. Please use Reply All to reply to the list. Grr, sorry, I keep forgetting... On Sun, Aug 24, 2008 at 1:02 AM, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: On Aug 23, 2008, at 11:22 PM, Kent Johnson wrote: On Sat, Aug 23, 2008 at 6:47 AM, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: At first I thought the bisect module was the way to go, but it is too tightly tied to integer list indices, and works very awkwardly when bisecting on datetime attributes. I'm not sure what the problem is with bisect (to find the starting point). Your list of model elements has integer indices. I think you have to write a __cmp__ method for your model class that compares on the datetime attribute, then it should work. You can also create a list of (key, model) and sort/search that. http://www.mail-archive.com/[EMAIL PROTECTED]/msg189443.html The __cmp__ trick is very nice, and would do it, except I won't have access to the events model classes. I could get bisect to work by feeding it a list comprehension, but making the high and low parameters work required integer indices, which seemed like one half-hack too many... I don't understand the issue. *All* lists have integer indices. If you make a list of (key, model) pairs, the keys only need to be comparable, not integers. The main problem is that I don't have any control over the list of models, and all I've got is the name of a datetime attribute to filter by. The only way I could get bisect to work was like this: index = bisect([getattr(x, attr_name) for x in model_list], sentinel_date) But that loops over the whole list, which is what I was trying to avoid. And the only way I could provide high and low parameters to bisect is by calling event_list.index(event), which doesn't work on django querysets. I also experimented with itertools.groupby to produce groups of events, but that turned out to be far slower than simply looping over the whole event list and extracting events which test true for c.start <= getattr(event, attr_name) < c.stop. Ideally I could create a kind of concurrent iterator, that steps through children's blocks of time and the object's event list in tandem, rather than going over the whole events list once for every child produced. Maybe that's not possible... I'm pasting the whole function down below, just for the hell of it. Thanks again, Eric def _iter_children(self, child, require_events=False): """ Iterate through an object's 'child' items. If require_events == True, only return children with events, otherwise return all children. """ while self.sentinel < self.stop: c = child([], self.sentinel, self.start_attr, rolling=self.rolling, counts_only=self.counts_only) for e in self.events: if c.start <= getattr(e,self.start_attr) < c.stop: c.events.append(e) self.sentinel += c.dt_range if not require_events or c.has_events(): yield c _
Re: [Tutor] __iter__ loops, partitioning list among children
I do apologize for the large quantities of confusing description – articulating the problem here has helped me understand exactly what it is I'm after (though it hasn't improved my code!), and I've got a better grasp of the problem now than I did when I first asked. It isn't so much that I need to protect against crazy users, but that the pattern I'm making is very flexible, and could be used in vastly different ways. I want to make sure that it operates on efficient principles, so that people will get the best performance out of it no matter how they use it. So my test case: a Month has a 'child' attribute pointing at Week, which has a 'child' attribute pointing at Day, so they all know what kind of child instances iteration should produce. With nested loops, a Month produces one Week, that Week produces seven Days, then the next Week is produced, it makes seven more Days, etc. That much is easy. Then there's self.events. My original code looped over all of self.events for each child produced. A Month loops over its events four times, a Week seven times. This was the straightforward implementation, but it seemed inefficient. (I also, as you point out, might have been wrong about the way django QuerySets work). My thought was that only one loop over self.events should be necessary, in theory, since they're sorted by date. A for loop creates an iterator from a sequence and calls next() on it, and it creates an entirely new iterator each time you start a new for loop: each for loop starts from the beginning of the sequence. But if you create your own iterator from the sequence and run a for loop on it, then using break to jump out of the for loop should leave the iterator just where you left it, since it maintains state. Doing another for loop on it (the next time through the date-based while loop), should pick up where it left off. That's why the line "iterevents = iter(self.events)" is outside of the while loop: it is only created once, and the loops later in the function all make use of the same iterator, instead of creating a new one every time. I'm pretty sure this works in theory, because calling event_count() on the Weeks as they come out returns the correct number of events. But, for some reason, those events are not making it into the Day children. I had originally assumed that a QuerySet pulled objects out of the database in a rolling fashion – ie iterating on a Month would first draw a Week's worth of events from the database, then another Week, then two more. But if it loads them all at first access, then I might as well just call list() on the QuerySet at object instantiation, and save myself some trouble. I hope that's a little clearer. My central issue is maintaining my place in the self.events loop, and only advancing it as far as the date-based while loop advances. Whether that's possible or not... Thanks again, Eric On Aug 26, 2008, at 1:12 AM, Kent Johnson wrote: I'm not following your code very well. I don't understand the relationship between the first loop and the iter_children() function. A couple of things that might help: - Django QuerySets can be qualified with additional tests, so you could have each of your month/week/etc classes have its own correctly qualified QuerySet. This will result in one database query for each event class, and multiple copies of the actual events. - When you start iterating a QuerySet, it fetches all the model instances into a list. I think you are trying to use iterators to prevent this fetch but Django doesnt' work that way. You might as well just use the list. - Iterators can't be restarted, I think that is why your latest iter_children() doesn't work as you expect. Can you say some more about why you are doing this? Where do all the initial constraints come from? Do you really have to be so careful to protect against a 'madman' user? Perhaps you could set a limit on the number of events you will retrieve and use a count() on the QuerySet to ensure that not too many records have been fetched. Maybe you should try a straightforward implementation and when you have something working you can worry about making it better. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] __iter__ loops, partitioning list among children
On Aug 26, 2008, at 7:20 PM, Kent Johnson wrote: On Tue, Aug 26, 2008 at 1:36 AM, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: So my test case: a Month has a 'child' attribute pointing at Week, which has a 'child' attribute pointing at Day, so they all know what kind of child instances iteration should produce. With nested loops, a Month produces one Week, that Week produces seven Days, then the next Week is produced, it makes seven more Days, etc. That much is easy. If all you want to do with the nested Month, etc is to iterate the events in them, you could probably use a shared iterator. It would have to be able to push-back items so that when you hit the out-of-range item you could push it back on the iterator. Is a 'shared iterator' something special, or do you mean all the instances would draw their events from a single iterator? I'm not sure what this would look like. Then there's self.events. My original code looped over all of self.events for each child produced. A Month loops over its events four times, a Week seven times. This was the straightforward implementation, but it seemed inefficient. (I also, as you point out, might have been wrong about the way django QuerySets work). My thought was that only one loop over self.events should be necessary, in theory, since they're sorted by date. Instead of direct use of the list iterator, you could pass the list and the starting index around. Then you don't have to keep finding your place. That's a definite possibility, I'll try it out. Itertools.tee is also something I've yet to look at closely. Thanks for these hints. A for loop creates an iterator from a sequence and calls next() on it, and it creates an entirely new iterator each time you start a new for loop: I still don't understand your code but you may have another misconception. Calling iter() on an iterator returns the same iterator; it does not make a new iterator that holds the same place. You can use itertools.tee() to split an iterator if that is what you want to do. Just for the sake of argument, here's the principle I'm working from: # >>> lst = range(10) >>> iterlst = iter(lst) >>> iterlst.next() 0 >>> for x in iterlst: ... if x < 5: ... print x ... else: ... break ... 1 2 3 4 >>> for x in iterlst: ... print x ... 6 7 8 9 # So that's why I'm creating the iterator outside of the while loop in the original code, and then using a repeated for loop with a break to step through all the events only once. Of course, the fact that 5 isn't in there probably points to the source of my problems! The solution might be assigning iterlist.next() to a variable, and advancing the variable. Thanks, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] __iter__ loops, partitioning list among children
I finally got my iterator-based version working, only to discover that it's nearly four times slower than the brute-force multiple-loops version I started with! Then I tried just adding an incrementing index to the loop, so that each loop only ran through self.events[last_index:], but that was still twice as slow as without the index. I suppose it's the overhead of incrementing the variable, or maybe some optimization in Python's internals, but the take home lesson was definitely 'leave well enough alone'. Anyway, thanks again for the advice, it's been a learning experience... E On Aug 27, 2008, at 2:22 AM, Kent Johnson wrote: On Tue, Aug 26, 2008 at 1:24 PM, Eric Abrahamsen <[EMAIL PROTECTED]> wrote: On Aug 26, 2008, at 7:20 PM, Kent Johnson wrote: If all you want to do with the nested Month, etc is to iterate the events in them, you could probably use a shared iterator. It would have to be able to push-back items so that when you hit the out-of-range item you could push it back on the iterator. Is a 'shared iterator' something special, or do you mean all the instances would draw their events from a single iterator? I'm not sure what this would look like. It's nothing special, I just mean that all instances would share an iterator. You would pass the iterator to the iteration function. Just for the sake of argument, here's the principle I'm working from: # lst = range(10) iterlst = iter(lst) iterlst.next() 0 for x in iterlst: ... if x < 5: ... print x ... else: ... break ... 1 2 3 4 for x in iterlst: ... print x ... 6 7 8 9 # So that's why I'm creating the iterator outside of the while loop in the original code, and then using a repeated for loop with a break to step through all the events only once. Of course, the fact that 5 isn't in there probably points to the source of my problems! The solution might be assigning iterlist.next() to a variable, and advancing the variable. The problem is that the first loop consumes the 5 from the iterator but doesn't actually process it. That is why you need an iterator with push-back - so you can put the 5 "back in" the iterator and get it out again in the next loop. http://code.activestate.com/recipes/502304/ Though working with indices directly might be simpler. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Intermediate/advanced concepts
On Nov 7, 2008, at 12:14 PM, [EMAIL PROTECTED] wrote: Hi everyone, I've been teaching myself python for a few months and I'm becoming frustrated because I've kind of hit a wall in terms of learning new information. In an effort to continue to learn I've found some material on more intermediate/advanced topics like linked lists, nodes, trees, etc. However, it's kind of like reading a math textbook - the tutorials do a decent job of explaining the material but it's all kind of theoretical, and I'm not sure how I'd apply these concepts in real world applications, or incorporate them into my code. Does anyone have any suggestions for learning about real world application of more advanced concepts? Are you writing real-world applications and using them? My (admittedly limited) experience has taught me that the real complexities of programming don't lie in obscure data structures or rarely-used functions, but in the practical, real-world issues that arise from creating actual applications: OOP best practices, application architecture, programming paradigms, recurring patterns, even just plain-old programming gotchas (though there are fewer of these in Python than other languages, thankfully). In other words, stuff that isn't necessarily described in the manuals, but that becomes evident once you've made the same mistakes two or three times, and start thinking about modifying your approach to programming. I've never used a tree, and a heap only once, but I feel like I've dipped into some pretty mind-bending stuff in terms of how I've arranged programs. Take metaclasses, for instance: no description of metaclasses I've read ever made sense to me; it only started to come clear after I'd looked at a module I was writing, realized that there was something really fundamentally wrong with it, and then slowly realized that the answer was metaclasses. About eleven lines of metaclass programming, as it turned out, but those seven lines turned my brain inside out for a bit. Not boring in the least! Yrs, Eric Also, are there other concepts that I should focus on? Frankly, I'm a bit bored because I've hit this ceiling, and I'm not really sure where to go to next. Thanks, Ben ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] more encoding strangeness
Hi there, I'm configuring a python command to be used by emacs to filter a buffer through python markdown, and noticed something strange. If I run this command in the terminal: python -c "import sys,markdown; print markdown.markdown(sys.stdin.read().decode('utf-8'))" < markdown_source.md The file (which is encoded as utf-8 and contains Chinese characters) is converted and output correctly to the terminal. But if I do this to write the output to a file: python -c "import sys,markdown; print markdown.markdown(sys.stdin.read().decode('utf-8'))" < markdown_source.md > output.hml I get a UnicodeEncodeError, 'ascii' codec can't encode character u'\u2014'. I'm not sure where exactly this is going wrong, as print and sys.stdout.write() and whatnot don't provide encoding parameters. What's the difference between this command writing to the terminal, and writing to the file? Thanks, Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] import confusion
Hi there, I'm trying to understand how module imports work, and am seeing some behavior I don't understand: >>> import django >>> from django import forms >>> from forms import DecimalField Traceback (most recent call last): File "", line 1, in ImportError: No module named forms >>> import django.contrib >>> from django.contrib import auth >>> from auth import ImproperlyConfigured Traceback (most recent call last): File "", line 1, in ImportError: No module named auth So what I'm seeing is that you can import X, then from X import Y, but only if Y is another module and not an object. The import chains above work until I try to import a class definition. Can someone explain what it is about module imports that makes it work this way? And why the unhelpful error message? Thanks! Eric ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor