Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
madey
Sep 17, 2007

I saved the Olympics singlehandedly

sund posted:

Just as the message says, you're trying to multiply single character strings together. Use the int() function to interpret the value of the string.

There are other things you should try before moving on to another problem. First, try to get rid of some variables -- you could use a single variable as the index in the array and then add an offset when accessing the array: string[a], string[a+1], string[a+2], etc. 'f' and on aren't used except to temporarily hold values before multiplying. Why not start by checking out the *= operator?

I realize you're just learning the language, but there's a couple really awesome python features that you should know about. Really, you ought to check out the section of your tutorial on the for loop, slicing and list comprehensions.

This is exactly the sort of advice I needed.
I can see where I was going wrong and now also know how to improve it.
Thanks very much. :cheers:

Adbot
ADBOT LOVES YOU

MasterShakeIsJesus
Oct 31, 2008

I'll tell ya what, if I have any desires to murder you in the middle of the night, you'll be the first to know, okay?
Yo--

I'm trying to learn Python and do some simple probabilistic modelling at the same time. Let's say that I want to make a function that returns "1" with a probability of 1/5, "2" with a probability of 1/4 and "3" with a probability of 11/20. How do I do it? I'd be able to work out the rest I need if you could show me how to make a function like this.

Tin Gang
Sep 27, 2007

Tin Gang posted:

showering has no effect on germs and is terrible for your skin. there is no good reason to do it
You'd want to look up the random module, although it may not be random enough depending on what you're doing. This line of code will do exactly what you asked for:

random.choice([1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3])

You could also do it a bunch of other ways.

edit: drat, I knew I was forgetting something to make that list look better. v

Tin Gang fucked around with this message at 08:52 on Oct 19, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Aardlof posted:

random.choice([1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3])

If you're going to do this, at least do random.choice([1]*4 + [2]*5 + [3]*11)

MasterShakeIsJesus
Oct 31, 2008

I'll tell ya what, if I have any desires to murder you in the middle of the night, you'll be the first to know, okay?
Thank you both. Much appreciated.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

From the python docs:
code:
class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message
Ok, so I'm new and still evolving my understanding of classes and error handling. What I don't understand here is what the point of the Error class is...it doesn't do anything.

Allie
Jan 17, 2004

Error doesn't have any attributes or methods but it does inherit all of the attributes and methods from the Exception class. The other two classes have their own __init__ methods because they apparently need to deviate from their base classes.

I would imagine Exception itself doesn't do much of anything itself either. One important aspect of exceptions is they have a name - otherwise, how would you raise and catch them? They also have a hierarchy (through subclassing) that lets you be less specific or more specific about the kinds of exceptions you want to catch.

So, the classes themselves don't necessarily do a whole lot; it's the raise/try/except functionality that handles the interruption of code flow. If that still doesn't make sense, I'd try looking for some examples of how to use exceptions, maybe from a tutorial or some existing code.

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo
Django protip:

Make sure Debug is set to False in settings.py before trying to run a script that inserts 200,000 objects into the database! I just spent last night debugging why my code was running out of memory after ~13k records no matter what I did, and learning a lot about garbage collection in python.

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

Baruch Obamawitz posted:

Django protip:

Make sure Debug is set to False in settings.py before trying to run a script that inserts 200,000 objects into the database! I just spent last night debugging why my code was running out of memory after ~13k records no matter what I did, and learning a lot about garbage collection in python.

Django protip:

Use manage.py's loaddata for bulk inserts.

No Safe Word
Feb 26, 2005

deimos posted:

Django protip:

Use manage.py's loaddata for bulk inserts.

This, fixtures rock.

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo

deimos posted:

Django protip:

Use manage.py's loaddata for bulk inserts.

Gotta generate the data first! I'm still working on that galaxy thing, and I'm dealing with 200,000 randomly generated stars + ~2,000,000 randomly generated planets, and gently caress if I'm figuring that all out by hand.

WhiskeyJuvenile fucked around with this message at 21:30 on Oct 20, 2009

Scaevolus
Apr 16, 2007

Baruch Obamawitz posted:

Gotta generate the data first! I'm still working on that galaxy thing, and I'm dealing with 200,000 randomly generated stars + ~2,000,000 randomly generated planets, and gently caress if I'm figuring that all out by hand.
Have fun living in your fantasy galaxy where every star has 10 planets. :colbert:

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Milde posted:

Error doesn't have any attributes or methods but it does inherit all of the attributes and methods from the Exception class. The other two classes have their own __init__ methods because they apparently need to deviate from their base classes.

I would imagine Exception itself doesn't do much of anything itself either. One important aspect of exceptions is they have a name - otherwise, how would you raise and catch them? They also have a hierarchy (through subclassing) that lets you be less specific or more specific about the kinds of exceptions you want to catch.

So, the classes themselves don't necessarily do a whole lot; it's the raise/try/except functionality that handles the interruption of code flow. If that still doesn't make sense, I'd try looking for some examples of how to use exceptions, maybe from a tutorial or some existing code.

Right, but I mean why create the Error class at all? Why not just have the InputError and TransitionError inherit directly from Exception?

BeefofAges
Jun 5, 2004

Cry 'Havoc!', and let slip the cows of war.

Thermopyle posted:

Right, but I mean why create the Error class at all? Why not just have the InputError and TransitionError inherit directly from Exception?

What would you do when you decide that all of your errors should have some common property? Would you go and edit each one individually?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Thermopyle posted:

Right, but I mean why create the Error class at all? Why not just have the InputError and TransitionError inherit directly from Exception?

So you can catch all of your exceptions at once, but let others' exceptions move up the call stack.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

BeefofAges posted:

What would you do when you decide that all of your errors should have some common property? Would you go and edit each one individually?

I thought of that, but if that was the point of the example, it seems like the docs should havve actually included a common property instead of "pass". So I assumed that wasn't the point.

Kire
Aug 25, 2006
I come back to Python frequently after a short hiatus, only to find I've forgotten everything. Here's a quick newb question: I want to print a sentence that lists objects in a list, without doing "There is a ['first item', 'second item'] and a third item." How can I make it get rid of the [ and ' for the first items?

code:
room_inventory = ['first item', 'second item', 'third item']

print 'There is a %s' % room_inventory[:len(room_inventory)-1]\
+ ' and a %s'% room_inventory[len(room_inventory)-1] + '.'
Also, this is for a list of variable length, anywhere from 0 to many objects.

Ferg
May 6, 2007

Lipstick Apathy
So I'm trying to build out and draw a directed acyclic graph with PyCairo (on top of PyGTK). Eventually this is intended to be a git graph representation, but I'm just working out the kinks right now. I've come across two issues that I could use some help on:

First, no line is drawn back to a second parent node (if it exists). It only draws the first line. This is fairly obvious considering how I skip over nodes that have already been drawn, but I'm not seeing how to get around that.

Second, if we are in an elevated node, meaning it was forked off, the second child node is bumped graphically higher as well. Also an obvious cause, not sure how to get around it though.

Code is available in a Github gist here: http://gist.github.com/215471

It's still very incomplete mind you, I'm just trying to iron out issues along the way and take baby steps to getting it finished.

Also if anybody has tips on how to improve the overall code, feel free. This is a small part of my first big Python project, so I've been on one helluva learning streak lately.

hlfrk414
Dec 31, 2008
code:
room_inventory = ['first item', 'second item', 'third item']
if not room_inventory:
    print 'There is nothing here.'
elif len(room_inventory) == 1:
    print 'There is a', room_inventory[0] + '.'
else:
    print 'There is a', ", ".join(item for item in room_inventory[:-1]),
    print ' and a', room_inventory[-1] + '.'

hlfrk414 fucked around with this message at 22:50 on Oct 21, 2009

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

Kire posted:

I come back to Python frequently after a short hiatus, only to find I've forgotten everything. Here's a quick newb question: I want to print a sentence that lists objects in a list, without doing "There is a ['first item', 'second item'] and a third item." How can I make it get rid of the [ and ' for the first items?

code:
room_inventory = ['first item', 'second item', 'third item']

print 'There is a %s' % room_inventory[:len(room_inventory)-1]\
+ ' and a %s'% room_inventory[len(room_inventory)-1] + '.'
Also, this is for a list of variable length, anywhere from 0 to many objects.
code:
', '.join(room_inventory[:-1])

No Safe Word
Feb 26, 2005

Kire posted:

I come back to Python frequently after a short hiatus, only to find I've forgotten everything. Here's a quick newb question: I want to print a sentence that lists objects in a list, without doing "There is a ['first item', 'second item'] and a third item." How can I make it get rid of the [ and ' for the first items?

code:
room_inventory = ['first item', 'second item', 'third item']

print 'There is a %s' % room_inventory[:len(room_inventory)-1]\
+ ' and a %s'% room_inventory[len(room_inventory)-1] + '.'
Also, this is for a list of variable length, anywhere from 0 to many objects.

Two things, you don't need to put the len call in there, [:-1] and [-1] do the same thing to what you want. But the reason it's printing out like that is because you're passing it a list to interpolate and lists that are made into strings look like ['foo', 'bar']. What you want is something more like:

code:
print 'There is a %s and a %s.' % (', '.join(room_inventory[:-1]), room_inventory[-1])
The ', '.join(L) bit basically joins all of the strings in the list with ', ' between each one.

Or if you want to steal a utility we wrote for supybot, we wrote the most terribly named function ever, commaAndify:
code:
def commaAndify(seq, comma=',', And='and'):
    """Given a a sequence, returns an English clause for that sequence.

    I.e., given [1, 2, 3], returns '1, 2, and 3'
    """
    L = list(seq)
    if len(L) == 0:
        return ''
    elif len(L) == 1:
        return ''.join(L) # We need this because it raises TypeError.
    elif len(L) == 2:
        L.insert(1, And)
        return ' '.join(L)
    else:
        L[-1] = '%s %s' % (And, L[-1])
        sep = '%s ' % comma
        return sep.join(L)
And then you can use that:

code:
print 'There is a %s.' % commaAndify(room_inventory)

Kire
Aug 25, 2006
Thanks for your help, I hadn't thought about the join function. That works great.

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo

Scaevolus posted:

Have fun living in your fantasy galaxy where every star has 10 planets. :colbert:

an average of 10 planets :coolfish:

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo
This might help inserting hundreds of thousands of records

code:
from django.db import transaction

@transaction.commit_manually
def viewfunc(request):
    ...
    for item in items:
        entry = Entry(a1=item.a1, a2=item.a2)
        entry.save()
    transaction.commit()
I'm going to try this out later, but who knows!

Kire
Aug 25, 2006
I have a question about passing (or pulling?) information from a class object into another function. I'm trying to make a text-adventure game ala Zork, but I'm realizing that even though I can set up a class for each room, and give it an __init__(self) which sets its self.room_inventory to have items, I can't reference those items in a function that lets the player choose which ones to pick up.

code:
def Items(location):
    '''List the items in a room.'''
    if len(location.room_inventory) == 0:
        print 'There are no items you can take.'
    elif len(location.room_inventory) == 1:
        print 'There is a %s here.' % location.room_inventory[0]
    else: 
        print 'There is a', ", ".join(item for item in location.room_inventory[:-1]),
        print 'and a', location.room_inventory[-1] + '.'

        
class Outside:
    '''Where the player starts.'''
    def __init__(self):
        self.room_inventory = ['first item', 'second item', 'third item']
    def description(self):
        print '''You are standing on a red, windswept plain.'''
        print Items(Outside)
The crux of my problem is that I still don't understand the voodoo around classes, objects, and the self.stuff syntax and how to reference that in other functions outside the class.

I looked on Google for some pseudo code relating to structuring a text adventure (what should I put in a class vs. put in a function vs. in the main loop?), but all I found was a broken link to the original Zork source code.

MagneticWombats
Aug 19, 2004
JUMP!

Kire posted:

I have a question about passing (or pulling?) information from a class object into another function. I'm trying to make a text-adventure game ala Zork, but I'm realizing that even though I can set up a class for each room, and give it an __init__(self) which sets its self.room_inventory to have items, I can't reference those items in a function that lets the player choose which ones to pick up.

code:
def Items(location):
    '''List the items in a room.'''
    if len(location.room_inventory) == 0:
        print 'There are no items you can take.'
    elif len(location.room_inventory) == 1:
        print 'There is a %s here.' % location.room_inventory[0]
    else: 
        print 'There is a', ", ".join(item for item in location.room_inventory[:-1]),
        print 'and a', location.room_inventory[-1] + '.'

        
class Outside:
    '''Where the player starts.'''
    def __init__(self):
        self.room_inventory = ['first item', 'second item', 'third item']
    def description(self):
        print '''You are standing on a red, windswept plain.'''
        print Items(Outside)
The crux of my problem is that I still don't understand the voodoo around classes, objects, and the self.stuff syntax and how to reference that in other functions outside the class.

I looked on Google for some pseudo code relating to structuring a text adventure (what should I put in a class vs. put in a function vs. in the main loop?), but all I found was a broken link to the original Zork source code.

Ignoring your misunderstanding of classes, what do you mean? You're alreadying doing

code:
location.room_inventory[0]

Modern Pragmatist
Aug 20, 2008

Kire posted:

I have a question about passing (or pulling?) information from a class object into another function.

Here is a version that does what i believe you intended:

code:
def Items(location):
    '''List the items in a room.'''
    if len(location.room_inventory) == 0:
        print 'There are no items you can take.'
    elif len(location.room_inventory) == 1:
        print 'There is a %s here.' % location.room_inventory[0]
    else: 
        print 'There is a', ", ".join(item for item in location.room_inventory[:-1]),
        print 'and a', location.room_inventory[-1] + '.'

        
class Outside:
    '''Where the player starts.'''
    def __init__(self):
        self.room_inventory = ['first item', 'second item', 'third item']
    def description(self):
        print '''You are standing on a red, windswept plain.'''
        Items(self)
Check out the call to "Items" in the "description" method. You should pass it the specific instance of the class (self). This specific instance of the class has the attribute (room_inventory) that is typically different for each instance of Outside, and is the attribute that you are trying to access in the "Items" function.

e: Just because I am OCD, here is how I would develop your class to make it a little more universal for all potential locations (and you can derive classes for any locations that may differ)

code:
class Location:
    def __init__(self,name,description):
        self.name = name
        self.room_inventory = list()
        self.description = description
    
    def add_item(self,item):
        if isinstance(item,list):
            self.room_inventory.extend(item)
        else:
            self.room_inventory.append(item)
        
    def print_info(self):
        print self.description
        self.print_items()
        
    def print_items(self):
        '''List the items in a room.'''
        if len(self.room_inventory) == 0:
            print 'There are no items you can take.'
        elif len(self.room_inventory) == 1:
            print 'There is a %s here.' % self.room_inventory[0]
        else: 
            print 'There is a', ", ".join(item for item in self.room_inventory[:-1]),
            print 'and a', self.room_inventory[-1] + '.'
       
# Create the "outside" instance using the following:     
outside = Location('Outside','You are standing on a red, windswept plain.')

Modern Pragmatist fucked around with this message at 22:43 on Oct 22, 2009

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo

Baruch Obamawitz posted:

This might help inserting hundreds of thousands of records

code:
from django.db import transaction

@transaction.commit_manually
def viewfunc(request):
    ...
    for item in items:
        entry = Entry(a1=item.a1, a2=item.a2)
        entry.save()
    transaction.commit()
I'm going to try this out later, but who knows!

This plus removing a .objects.all() inside the for loop to a .objects.all().values_list() outside the for loop made it from 5 seconds per 1000 records to 5 seconds per 5000 records

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo
Okay, so I'm making a browser-based game powered by a django backend (ho ho ho) with a cronjob/tick-based update running every 15 minutes. I've managed to, by a whole lot of plyer-action-initiated processing stored in the database, to have only one non-.all().update() loop like

code:
slicesize = 5000
tickset = Player.objects.filter(finishTime__lte=datetime.utcnow())
for i in xrange(0, tickset.count(), slicesize):
    for player in tickset[i, i + slicesize - 1]:
        player.data = Class2.objects.filter(refers_to=object).aggregate(Count('other_data'))
        player.time = None
        player.save()
in the tick, so that I'm worst-case limiting the number of queries needed to process the tick by the lowest possible quantity, namely the number of players (as each player has at least one if not more of an object in every other class), and even further limiting it by looking only at those players that actually have something to do that tick by the time field, and I figure that based on a test run of it taking 10 minutes to process a tick on a test case of 200,000 players with events firing, I should be able to get by on a 15 minute tick time. Does this sound reasonable?

(No, I can't just Player.objects.all().update(), because the update would need to refer to a F() object on a field outside the Player table)

edit: edited code sample to reflect that trying to iterate over .all() gave out-of-memory errors trying to load 200,000 records into memory, and fixed __gte to __lte.

edit: And the transaction commit stuff from last post won't work due to the aggregate call within the for loop; can't read after writing without committing.

WhiskeyJuvenile fucked around with this message at 05:53 on Oct 23, 2009

king_kilr
May 25, 2007
You can do Model.objects.all().iterator(), then it won't use much memory. Also, make sure your QuerySet has an ordering, otherwise you aren't guarnteed to get every result.

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo
Using iterators, would multithreading that loop by splitting it in 10 by spawning 10 threads each to iterate over 1/10th of the count speed it up? I'm not sure how mysql works in this regard.

king_kilr
May 25, 2007

Baruch Obamawitz posted:

Using iterators, would multithreading that loop by splitting it in 10 by spawning 10 threads each to iterate over 1/10th of the count speed it up? I'm not sure how mysql works in this regard.

mysql is pretty lovely at using multiple cores (compared to pgsql anyways...), plus in Python you can only really use threads for IO bound ops, I'm not sure how much mysqldb drops the GIL, or whether the time it does it for is significant, if you really want to parallelize it you'd need to use multiprocessing.

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo

king_kilr posted:

mysql is pretty lovely at using multiple cores (compared to pgsql anyways...), plus in Python you can only really use threads for IO bound ops, I'm not sure how much mysqldb drops the GIL, or whether the time it does it for is significant, if you really want to parallelize it you'd need to use multiprocessing.

I don't want to, I just want to be able to speed this fucker up somehow.

king_kilr
May 25, 2007
I'd bulk load the Class2 data using an annotation.

WhiskeyJuvenile
Feb 15, 2002

by Nyc_Tattoo

king_kilr posted:

I'd bulk load the Class2 data using an annotation.

Python annotation or django annotation?

edit: using a test case of 200,000 players, that would be on the order of 2,000,000 integers in memory...

edit2: and using it seems like the values_list() method is what I'd be looking for instead of annotation w/r/t django, yes?

edit3: Just for testing, I tried this:
code:
@transaction.commit_manually
def foo():
  print datetime.now()
  for x in Player.objects.iterator():
    x.money = x.money + x.id
    x.save()
  print datetime.now()
  transaction.commit()
and hit 42 seconds for 10,000 players. (yes, I can Player.objects.all().update() here, but I can't in the code I'm trying to optimize)

That's still too long, and I'm really banging my head about trying to figure out a way to optimize this...

WhiskeyJuvenile fucked around with this message at 00:38 on Oct 24, 2009

king_kilr
May 25, 2007
Django annotation. Who cares about 2 million integers in memory, that's under 25 MB of RAM.

m0nk3yz
Mar 13, 2002

Behold the power of cheese!

king_kilr posted:

mysql is pretty lovely at using multiple cores (compared to pgsql anyways...), plus in Python you can only really use threads for IO bound ops, I'm not sure how much mysqldb drops the GIL, or whether the time it does it for is significant, if you really want to parallelize it you'd need to use multiprocessing.

I assume he's talking to mysql over a local socket; socket code releases the GIL as it's I/O bound. On the other hand, I've heard nasty things about mysqldb. Thinking about it, since you're doing a massive alter on every object in the db for this, you are going to want to farm it off someplace. You can try threads, watch out for mysqldb though. Otherwise, spawn the jobs off to a process pool (using multiprocessing) or other dedicated job-server with multiple workers.

m0nk3yz fucked around with this message at 03:27 on Oct 24, 2009

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Objects with attributes composed of standard data types along with attributes that are other objects, how do I handle persistent storage?

hlfrk414
Dec 31, 2008

Thermopyle posted:

Objects with attributes composed of standard data types along with attributes that are other objects, how do I handle persistent storage?

Use shelve?

Adbot
ADBOT LOVES YOU

king_kilr
May 25, 2007

Thermopyle posted:

Objects with attributes composed of standard data types along with attributes that are other objects, how do I handle persistent storage?

Depending on your primitives either pickle or json.

  • Locked thread