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
brosmike
Jun 26, 2009

zarg posted:

Awesome. Thanks for your help on the stuff above this! I was already reading the python docs stuff :) Tons of nice concise info there; it's great.

For the example I quote above, what will happen if myDictionary is a list-of-lists like I'm aiming to do? Will it create a new list with the same values, simply sorted? Or does it take advantage of the mutability of lists and just shuffle it in place? Again, dosnt matter in the least for me. I'm just a curious dude :)

edit: To clarify, I understand that tuple is a different data type from list. When I say "the same values" I just mean the same terms in a different order.

There's a few things going on here; in general, the documentation is the best place to get answers like this. dict.items() is going to give you a shallow copy of the dict's list of key-value pairs. Since it's a copy, modifying the list returned by items() (say, by appending a new (key,value) pair) will not affect the dict in any way. But since it's a shallow copy, modifying one of the values of the dict (which are also lists) through the returned value of items() (say, by appending something to the list at my_dict_items[0][1]) will affect the contents of the dict.

The sorted() call has the same effect - it generates a new shallow copy of the original list and sorts that, it doesn't sort the original list in place. If you want to sort in-place, you would want to use my_dict_items.sort() instead of sorted(my_dict_items).

Adbot
ADBOT LOVES YOU

Dren
Jan 5, 2001

Pillbug

Sailor_Spoon posted:

code:
In [6]: dict(ln.strip().split('\t') for ln in open('foo.txt'))
I believe this code does not explicitly close the file handle. I remember seeing somewhere that closing file handles by letting them go out of scope is not good practice because that behavior is a CPython implementation detail. Given that, I believe the best practice would be to do:
code:
with open('foo.txt') as f:
    dict(ln.strip().split('\t') for ln in f)
I googled a bit about it but couldn't find a reference. Anyone have a link? I think I read it when I was looking at pypi.

good jovi
Dec 11, 2000

Dren posted:

I believe this code does not explicitly close the file handle. I remember seeing somewhere that closing file handles by letting them go out of scope is not good practice because that behavior is a CPython implementation detail. Given that, I believe the best practice would be to do:
code:
with open('foo.txt') as f:
    dict(ln.strip().split('\t') for ln in f)
I googled a bit about it but couldn't find a reference. Anyone have a link? I think I read it when I was looking at pypi.

I think I was actually the one that brought this up last time. In cpython, file handles are implicitly closed when they go out of scope. Apparently, this is not necessarily true in other implementations. So if you expect your code to ever be run on anything other than cpython, then yes, using `with` is the smart thing to do.

Yay
Aug 4, 2007

Dren posted:

I googled a bit about it but couldn't find a reference. Anyone have a link? I think I read it when I was looking at pypi.
PyPy's compatability notes discuss the differences in working with files, and put it down to garbage collection. Perhaps it's that you were thinking of? Jython also has minor differences, probably for the same reason.

Tufty
May 21, 2006

The Traffic Safety Squirrel

Gothmog1065 posted:

Are there any "Programming Python for dumbshits" that is written for 3.2?

e: As far as I can tell, this one was written for 3.1, which is basically the same as 3.2, correct?

That's the book I've been using to teach myself and it's fantastic :)

Gothmog1065
May 14, 2009

Tufty posted:

That's the book I've been using to teach myself and it's fantastic :)
Fantastic. I ordered it today and it should be in in a few days. I think I'll have an easier time using this than I have been with other ways.

Tufty
May 21, 2006

The Traffic Safety Squirrel

Gothmog1065 posted:

Fantastic. I ordered it today and it should be in in a few days. I think I'll have an easier time using this than I have been with other ways.

Yeah, I tried a few other ways first but the content of the book is just sticking with me. He treats it like he's teaching you babby's first programming language but manages to not make it patronising, and the way new concepts are introduced is nice. Chapter structure is basically this: here's what we're gonna learn this chapter; here's the programs we're gonna make to introduce the new stuff; program 1 - go through it, explaining new stuff and refreshing old stuff as appropriate; program 2 etc etc; large final chapter program that combines all the new concepts, explanation of it, refreshing all the new stuff in your mind; here are some 'challenge' programs you can try to make using the concepts you've learned this chapter.

It's really fun :)

ufarn
May 30, 2009
Tuple question:

I am trying to add an integer to a tuple that, to begin with, contains only one integer, but will have more, as they are added later on.

code:
Works:
>>> primelist = (1, 2, 3)
>>> primelist = primelist + (4,)
>>> primelist
(1, 2, 3, 4)

Doesn't:
>>> primelist = (1)
>>> primelist = primelist + (2,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
Why is it that the latter doesn't work, and what can I do about it?

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug

ufarn posted:

Tuple question:

I am trying to add an integer to a tuple that, to begin with, contains only one integer, but will have more, as they are added later on.

code:
Works:
>>> primelist = (1, 2, 3)
>>> primelist = primelist + (4,)
>>> primelist
(1, 2, 3, 4)

Doesn't:
>>> primelist = (1)
>>> primelist = primelist + (2,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
Why is it that the latter doesn't work, and what can I do about it?

Short answer: because (1) isn't a tuple. The error message is telling you exactly what's happening.

code:
In [1]: p = (1)

In [2]: type(p)
Out[2]: <type 'int'>

In [3]: q = (1,)

In [4]: type(q)
Out[4]: <type 'tuple'>
Longer answer: why aren't you using a list (i.e. something designed to be dynamically expanded) for this?

ufarn
May 30, 2009

Lysidas posted:

Short answer: because (1) isn't a tuple. The error message is telling you exactly what's happening.

code:
In [1]: p = (1)

In [2]: type(p)
Out[2]: <type 'int'>

In [3]: q = (1,)

In [4]: type(q)
Out[4]: <type 'tuple'>
Longer answer: why aren't you using a list (i.e. something designed to be dynamically expanded) for this?
I thought as much, thanks.

I am doing the MIT OCW, and they haven't made it to lists yet, so I wanted to do it without any future keywords and data structures.

xtal
Jan 9, 2011

by Fluffdaddy
If you're curious what's up with that: tuples aren't defined by parentheses, but by the comma. A one-tuple has to have a trailing comma to be a tuple; otherwise, it's a string, integer or whatever.

You probably already know this, considering the additions do have the trailing comma, but you missed it when you assigned first `primelist` in the latter example, and it was therefore made to be an integer.

xtal fucked around with this message at 22:56 on Mar 20, 2011

ufarn
May 30, 2009

NOISIA posted:

If you're curious what's up with that: tuples aren't defined by parentheses, but by the comma. A one-tuple has to have a trailing comma to be a tuple; otherwise, it's a string, integer or whatever.

You probably already know this, considering the additions do have the trailing comma, but you missed it when you assigned first `primelist` in the latter example, and it was therefore made to be an integer.
I see. I didn't have the syntax down, but I have a decent idea of tuples from some functional programming.

I went ahead and solved it using a list (:effort:), but I just replaced them with your tuple. :eng101:

Bonus question! I am trying to render an integer as a decimal, but failing utterly:

code:
print "%i divided by the sum is %d" % (n, (1.0*n)/pSum)
This produces a round 0. Bah. The computation works fine, when I am not producing a string, so there's something pertinent to the string behaviour that bites me in the rear end. What is it?

ufarn fucked around with this message at 23:36 on Mar 20, 2011

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug

NOISIA posted:

tuples aren't defined by parentheses, but by the comma.

:ssh: Except for the empty tuple, of course:

code:
In [1]: e = ()

In [2]: type(e)
Out[2]: <type 'tuple'>

YardKGnome
Jan 18, 2003
Grimey Drawer

ufarn posted:

Bonus question! I am trying to render an integer as a decimal, but failing utterly:

code:
print "%i divided by the sum is %d" % (n, (1.0*n)/pSum)
This produces a round 0. Bah. The computation works fine, when I am not producing a string, so there's something pertinent to the string behaviour that bites me in the rear end. What is it?

You want %f or %g

ufarn
May 30, 2009

YardKGnome posted:

You want %f or %g
I see. Cheers.

SpaceReflex
May 4, 2010
Let's say I want to create an app that keeps track of third-party game content, downloads it from the internet, installs it and handles dependencies. Basically, an apt-get for a specific antique game's mod community. They are in a poorly documented zip file hell at the moment, with nearly 20,000 pieces of legacy content.

What Python libraries, or feature-complete projects, should I be looking at using? I know about WUU, and am considering pruning it down for my needs. I did search the hell out of PyPI but couldn't find anything like a generic package manager. Thanks in advance.

tef
May 30, 2004

-> some l-system crap ->
Might be some code worth saving in yum; http://en.wikipedia.org/wiki/Yellowdog_Updater,_Modified

or you could just use mercurial :v:

tef fucked around with this message at 12:32 on Mar 21, 2011

Dren
Jan 5, 2001

Pillbug

SpaceReflex posted:

Let's say I want to create an app that keeps track of third-party game content, downloads it from the internet, installs it and handles dependencies. Basically, an apt-get for a specific antique game's mod community. They are in a poorly documented zip file hell at the moment, with nearly 20,000 pieces of legacy content.

What Python libraries, or feature-complete projects, should I be looking at using? I know about WUU, and am considering pruning it down for my needs. I did search the hell out of PyPI but couldn't find anything like a generic package manager. Thanks in advance.

I think you could make Ivy work for this. http://ant.apache.org/ivy/

I have written a custom dependency manager before. I strongly recommend you find a dependency tool and make it work for you instead of rolling your own. Using an existing tool will cut your work down from creating and parsing your own xml format, coding up a dependency tree parser, and organizing a dependency repository to just organizing the dependency repository.

You could probably even build a yum or apt-get compatible repository.

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


I have a list whose length is divisible by 5, and I want to apply a function to each sublist of 5 elements. Here's an example to make it clearer:
code:
input = range(10)
output = [f(input[0:5]), f(input[5:10])]
It's pretty easy to do this with a loop, but is there some clever application of map(), reduce() and filter() that I can use instead? I'll probably just leave the loop in for clarity, but I'm curious about this.

Dren
Jan 5, 2001

Pillbug

ultrafilter posted:

I have a list whose length is divisible by 5, and I want to apply a function to each sublist of 5 elements. Here's an example to make it clearer:
code:
input = range(10)
output = [f(input[0:5]), f(input[5:10])]
It's pretty easy to do this with a loop, but is there some clever application of map(), reduce() and filter() that I can use instead? I'll probably just leave the loop in for clarity, but I'm curious about this.

code:
input = range(10)
output = map(f, [input[x:x+5] for x in xrange(0, len(input), 5)])

good jovi
Dec 11, 2000

ultrafilter posted:

I have a list whose length is divisible by 5, and I want to apply a function to each sublist of 5 elements. Here's an example to make it clearer:
code:
input = range(10)
output = [f(input[0:5]), f(input[5:10])]
It's pretty easy to do this with a loop, but is there some clever application of map(), reduce() and filter() that I can use instead? I'll probably just leave the loop in for clarity, but I'm curious about this.

code:
map(f, zip(*[input[n::5] for n in range(5)]))
code:
In [18]: zip(*[range(25)[n::5] for n in range(5)])
Out[18]: 
[(0, 1, 2, 3, 4),
 (5, 6, 7, 8, 9),
 (10, 11, 12, 13, 14),
 (15, 16, 17, 18, 19),
 (20, 21, 22, 23, 24)]

In [19]: map(sum, zip(*[range(25)[n::5] for n in range(5)]))
Out[19]: [10, 35, 60, 85, 110]

good jovi fucked around with this message at 20:51 on Mar 21, 2011

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


Thank you.

SpaceReflex
May 4, 2010
Hmm, with two mentions, plus existing familiarity with rpm packaging, I might just try to yum it up. Yum has a nice front end too which is something else I'd like to avoid reinventing. Trying to find evidence of win32 yum standalone builds at the moment - it's gotta be a py2exe situation with no extra deps. Since yum talks to rpm libs that might be extra fun.

I looked at Ivy and I like the graphical dependency chart, but it's all Java and I dun know Java outside of "ant start" "ant stop". :doh:

Thanks and keep the suggestions coming guys, I will have all the content mirrored in a couple of days and be ready for repo building.

tripwire
Nov 19, 2004

        ghost flow
PIL Question.

Everybody knows PIL's support for multilayer images kind of sucks, so it may be that what I'm asking for is hopeless. But has anyone ever found a fix/workaround for the way PIL doesn't respect heterogeneous layer sizes?


Typically, animated gifs are optimized by taking blocks of color which don't change between frames and turning them transparent, and resizing the layers to be as small as possible.
That is to say, if a new layer only adds a change to a small region of the image, that new layer should only be as big as the changed region. When rendering the GIF, that layer will be painted at an offset to the original image (some programs like irfanview gently caress up and you see gifs rendered with regions popping around the image).


PIL lets you access all of the frames in a GIF image (although you have to grab the palette from the first frame and chuck it back into the image on later frames for some reason).

But PIL refuses to play nice when the layers in your gif are different sizes: if you seek to a new frame which is smaller than the image size, and save that frame, youll get a bizarre effect: the transparent regions within the boundaries of that frame are correctly saved, but rest of the image bounding it gets set to a random other color in the palette, leaving a gross border around each new frame.

Heres an animated GIF I'm working with:


Heres my script for dumping a series of gifs into one big image:
code:
import Image
size = 112,208
big = Image.new("RGBA",(size[0]*8,size[1]*16),(255,0,255,0) )

for x in xrange(8):
    #I have 8 images called pyron1.gif thorugh pyron8.gif
    tile = Image.open(r'pyron%d.gif'%(x+1))
    palette = tile.getpalette()
    for y in xrange(16):
        #each image has 16 frames
        pos = x*112,y*208
        tile.seek(y)
        #we have to throw the palette in again on each new frame
        tile.putpalette(palette)
        #convert to the format of the target image.
        converted = tile.convert("RGBA")
        #vain attempt to try and blast the target area with transparency
        big.paste((0,0,0,0),pos+size)
        #the image is passed again as an optional mask; in this case its alpha channel is used.
        big.paste(converted,pos,converted)

big.save('fuckfail.png')
And the big image resulting:
http://i.imgur.com/tObJJ.png
(it may help to save it and open it up in some program where the transparency is more apparent)

So what the gently caress!

Dren
Jan 5, 2001

Pillbug

SpaceReflex posted:

Hmm, with two mentions, plus existing familiarity with rpm packaging, I might just try to yum it up. Yum has a nice front end too which is something else I'd like to avoid reinventing. Trying to find evidence of win32 yum standalone builds at the moment - it's gotta be a py2exe situation with no extra deps. Since yum talks to rpm libs that might be extra fun.

I looked at Ivy and I like the graphical dependency chart, but it's all Java and I dun know Java outside of "ant start" "ant stop". :doh:

Thanks and keep the suggestions coming guys, I will have all the content mirrored in a couple of days and be ready for repo building.
I got this when I searched for yum on windows.

http://www.nabber.org/projects/appupdater/

SpaceReflex
May 4, 2010

Dren posted:

I got this when I searched for yum on windows.

http://www.nabber.org/projects/appupdater/

good suggestion! appupdater is on my short list already due to its cross platform capability and flexibility.

HIERARCHY OF WEEDZ
Aug 1, 2005

Since bool('') == False, how come (False or '') == ''? Shouldn't it be equal to False?

Sneftel
Jan 28, 2009
bool('') needs to evaluate to something, and that something has to be a bool, so it evaluates to False (because empty containers evaluate to false, to make certain idioms work). But it is not, itself, False. "(a or b)" evaluates the first argument, and then sees what that argument looks like as a bool; it returns a (NOT cast to bool) if it evaluates to True, and returns b (NOT cast to bool) otherwise. That enables other idioms.

For instance:

code:
user_name = get_user_name()
print(user_name or "No name provided")

Sneftel fucked around with this message at 19:07 on Mar 22, 2011

FoiledAgain
May 6, 2007

I've been running a python script with no problem for weeks now, and all of a sudden it has started giving me error messages: no module named blah. For every single module it used to import with no problem. Why would this happen and how can I fix it?

The only difference I can think of is that when it broke I ran it by double clicking from Explorer, rather than within IDLE.

Gothmog1065
May 14, 2009
Okay, just got my "You don't know poo poo about programming" book. Been doing good so far. I'll read through the chapter, and when he comes to the game at the beginning, I try to program it before he shows how he does it. It's worked good so far, except the program I'm doing now is closing as soon as I open it. I can't figure it out. Here is the code:

code:
#Guess my number!

import random

number = random.randint(1, 100)
number += 1
count = 1

print("""
    Guess my number, try to get it in as few tries as possible!
    Please enter a number between 1 and 100!
    """)

guess = int(input("Guess:"))

while guess != number:
    if guess > number:
        print("Lower")
    elif guess < number:
        print("Higher")
    else
        print("That isn't supposed to happen...")
        
    guess = int(input("Incorrect! Please enter another number (1-100):"))
    count += 1

if count > 1:
    print("You guessed the number correctly after", count, "tries!")
else
    print("Awesome! you got it on the first try!")
    

input("Hit Enter to exit")
Is there something I'm doing wrong? It's not hitting any of the breaks, even the "enter to exit" one.

e: I found it. I forgot the colons after "else". I find it odd that it will just not work right even before you should be getting to those areas.

Gothmog1065 fucked around with this message at 19:23 on Mar 23, 2011

Dren
Jan 5, 2001

Pillbug

FoiledAgain posted:

I've been running a python script with no problem for weeks now, and all of a sudden it has started giving me error messages: no module named blah. For every single module it used to import with no problem. Why would this happen and how can I fix it?

The only difference I can think of is that when it broke I ran it by double clicking from Explorer, rather than within IDLE.

Something is wrong with your path. You can see your path by doing:
code:
import sys
print sys.path
at the beginning of your program. Your path should include the directory that your imports are in.

If you have more than one python interpreter or version installed on your system you may want to investigate which one is called when you run a script through explorer in order to be sure it is the one you expect.

Dren
Jan 5, 2001

Pillbug

Gothmog1065 posted:

Okay, just got my "You don't know poo poo about programming" book. Been doing good so far. I'll read through the chapter, and when he comes to the game at the beginning, I try to program it before he shows how he does it. It's worked good so far, except the program I'm doing now is closing as soon as I open it.

Open a command prompt (Start -> Run... -> cmd) and run your program from there.

The problem you had generated an error message that you never saw because windows closed your terminal as soon as the program exited.

DeciusMagnus
Mar 16, 2004

Seven times five
They were livin' creatures
Watch 'em come to life
Right before your eyes

Gothmog1065 posted:

code:
number = random.randint(1, 100)
number += 1

Won't this generate a number between 2 and 101?

Gothmog1065
May 14, 2009

DeciusMagnus posted:

Won't this generate a number between 2 and 101?

No, I just double checked this (Added a print("Random number:", number) line at the bottom). The randint(1,100) creates numbers 0 - 99, not 1 - 100.

FoiledAgain
May 6, 2007

quote:

If you have more than one python interpreter or version installed on your system you may want to investigate which one is called when you run a script through explorer in order to be sure it is the one you expect.

Multiple versions might be the problem. I have 2.6 and 2.7 installed, although I almost never use 2.6 anymore, so I wonder if that's what got called when I ran it from explorer. I'll go dig. Thanks!

Dren
Jan 5, 2001

Pillbug

DeciusMagnus posted:

Won't this generate a number between 2 and 101?

Unless this was changed in 3.0, yes.

code:
>>> import random
>>> print random.randint.__doc__
Return random integer in range [a, b], including both end points.

DeciusMagnus
Mar 16, 2004

Seven times five
They were livin' creatures
Watch 'em come to life
Right before your eyes

Gothmog1065 posted:

No, I just double checked this (Added a print("Random number:", number) line at the bottom). The randint(1,100) creates numbers 0 - 99, not 1 - 100.

The documentation says otherwise. Also this was run in python 2.6 and 3.1:
pre:
Python 3.1.3 (r313:86834, Dec 15 2010, 17:14:42) 
[GCC 4.2.1 20070719  [FreeBSD]] on freebsd8
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> [random.randint(1,5) for i in range(20)]
[5, 1, 2, 5, 2, 3, 1, 4, 3, 3, 5, 3, 1, 2, 3, 1, 2, 4, 2, 2]

Python 2.6.6 (r266:84292, Mar  7 2011, 15:21:33) 
[GCC 4.2.1 20070719  [FreeBSD]] on freebsd8
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> [random.randint(1,5) for i in range(20)]
[1, 5, 3, 2, 3, 1, 1, 3, 5, 4, 1, 4, 4, 1, 5, 5, 3, 2, 1, 2]

Gothmog1065
May 14, 2009

DeciusMagnus posted:

The documentation says otherwise. Also this was run in python 2.6 and 3.1:
I guess you're right then, I must have been using the range() counter as a base for what random does. Thanks for the heads up.

Gothmog1065
May 14, 2009
Okay, another day and another bit of code that's loving me up:

pre:
#Word Jumble game

import random

WORDLIST = ("jumble", "python", "word", "programming", "stephen", "computer", "plus",
         "game", "book", "chapter", "inventory", "programmer")

print("""

Word Jumble game

Try and guess the jumbled word!
""")

true = 1 #Set loop to infinite while the user wants to play
while true:
    jumble = ""
    word = random.choice(WORDLIST)
    correct = word

    while word:
        position = random.randrange(len(word))
        jumble += word[position]
        word = word[:position] + word[(position + 1):]

    print("\n\nThe jumble you want to guess is", jumble, ".")
    guess = input("Your guess: ")

    while guess.lower() != correct and guess.lower != "":
        print("\n\nSorry, that isn't right!")
        guess = input("\nGuess again: ")

    if guess == correct:
        end = input("You got it! Do you want to play again? (Y/N): ")

    if end.lower() == "n" or end.lower() == "no" or end == "":
        break
e: error fixed:
When I run this in IDLE, it gives the error:
pre:
Traceback (most recent call last):
  File "C:/Users/Jason/Desktop/Python/word jumble", line 26, in <module>
    print("\n\nThe jumble you want to guess is", jumble)
TypeError: 'str' object is not callable
Again, I'm not following the book exactly and I might be doing something stupid. I know there's probably a better way to do the user choice to end, but off what little I know, it'll have to do.

Gothmog1065 fucked around with this message at 14:10 on Mar 25, 2011

Adbot
ADBOT LOVES YOU

Sneftel
Jan 28, 2009
You've got a wayward = which is redefining "print" up near the top.

  • Locked thread