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
Masa
Jun 20, 2003
Generic Newbie

PiotrLegnica posted:

Do you know what functools.partial does? Don't use it, just bind the signal to a no-arg method and use instance variables from there.


Ah, that works perfectly. Thanks.

I was only using partial because I couldn't figure out how to use a method with arguments as a PyQT slot, and that's what Google turned up.

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Here's two rules:

  1. Given two sequences, the one with the lower starting point sorts lower.
  2. Given two sequences, the one with the higher ending point sorts higher.

And here's some specializations of those rules:

  1. Sequences that have infinite starting points sort lower than those that do not.
  2. Sequences that have infinite ending points sort higher than those that do not.

Suspicious Dish fucked around with this message at 20:54 on Sep 25, 2012

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Suspicious Dish posted:

Here's two rules:

  1. Given two sequences, the one with the lower starting point sorts lower.
  2. Given two sequences, the one with the higher ending point sorts higher.

And here's some specializations of those rules:

  1. Sequences that have infinite starting points sort lower than those that do not.
  2. Sequences that have infinite ending points sort higher than those that do not.

I think I'm broken, I can't translate it into a simple comparison. I know how I want them to end up, but even comparing two random values from my set just makes my brain stop. Ugh.

Thanks, though. Maybe if I walk away from it one more time and look again.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Carthag posted:

How would you guys go about sorting open-ended "ranges"? I have a bunch of numbers in tuples that represent ranges (start, end) and I want to sort these in a specific way.

Python code:
...

expected = [
	(None,0),
	(0,0),
	(0,2),
	(None,1),
	(1,1),
	(2,2),
	(2,None),
	(2,3),
	(3,3),
]

print sortedvals
print sortedvals == expected
I guess I'm growing old, I can't wrap my head around it.

Let me check whether I understand this. You're trying to sort open intervals, and None is a stand-in for minus infinity or infinity? And expected is the ordering you want to end up with? (I'm not sure whether this is a correct understanding. In particular, if these really are meant to be open intervals, then for example (2, 2) and (3, 3) both represent the empty set, and so given that they're equal they should surely be placed adjacent in expected.)

I can't deduce any logic behind the ordering given in expected. Is this where you are running into difficulty, or is it something else that is the problem.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



My data consists of both single values and ranges between values, so actually the original data set is more like this (in sorted order):

Python code:
values = [
    (None,0),
    0,
    (0,2),
    (None,1),
    1,
    2,
    (2,None),
    (2,3),
    3,
]
I was converting to tuples because I thought it would make comparison easier but I guess not.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Suspicious Dish posted:

Here's two rules:

  1. Given two sequences, the one with the lower starting point sorts lower.
  2. Given two sequences, the one with the higher ending point sorts higher.

And here's some specializations of those rules:

  1. Sequences that have infinite starting points sort lower than those that do not.
  2. Sequences that have infinite ending points sort higher than those that do not.

Python code:
def compare_two_sequences(a, b):
    # Sequences that are the same are sorted equally.
    if a == b:
        return 0

    # Completely open sequences should not happen
    if a == (None, None) or b == (None, None):
        raise ValueError("Completely open sequences cannot be sanely sorted")

    a_starting_point, a_ending_point = a
    b_starting_point, b_ending_point = b

    # Sequences that have infinite starting points...
    if a_starting_point is None and b_starting_point is not None:
        # sort lower than those that do not.
        return -1
    elif b_starting_point is None and a_starting_point is not None:
        return 1

    # Sequences that have infinite ending points...
    if a_ending_point is None and b_ending_point is not None:
        # sort higher than those that do not.
        return 1
    elif b_ending_point is None and a_ending_point is not None:
        return -1

    # Given two sequences, the one that has the lower
    # starting point sorts lower.
    if a_starting_point < b_starting_point:
        return -1
    elif b_starting_point < a_starting_point:
        return 1

    # Given two sequences, the one that has the higher
    # ending point sorts higher.
    if a_ending_point > b_ending_point:
        return 1
    elif b_ending_point > a_ending_point:
        return -1

    assert False, "Should not be reached"

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Thanks, but that's not my comparison; I guess I'm bad at explaining. After some fiddling, I've come up with this horror which sorts as expected, but holy moly is it ever ugly.

Python code:
expected = [
    (None,0), # less than 0
    0,
    (0,1), # between 0 and 1
    (0,2), # between 0 and 2
    (0,3), # between 0 and 3
    (None,1), # less than 1
    1,
    (1,None), # greater than 1
    (1,2),
    (1,3),
    (None,2), # less than 2
    2,
    (2,None), # greater than 2
    (2,3), # between 2 and 3
    (None,3), # less than 3
    3,
]

def compare(a, b):
	if type(a) == int and type(b) == int:
		res = cmp(a,b)
	elif type(a) == int and type(b) == tuple:
		if b[0] == None:
			res = cmp(a+1,b[1]) # x <> (None, y)
		elif b[1] == None:
			res = cmp(a-1,b[0]) # x <> (y, None)
		else:
			# x <> (y, z)
			if a <= b[0]:
				res = -1
			elif a >= b[1]:
				res = 1
			else:
				return 0
	elif type(a) == tuple and type(b) == int:
		res = -compare(b,a) # do the reverse comparison
	elif type(a) == tuple and type(b) == tuple:
		if a[0] == None and b[0] == None:
			res = cmp(a[1], b[1])
		elif a[0] == None and b[0] != None:
			res = cmp(a[1],b[0])
		elif a[0] != None and b[0] == None:
			res = cmp(a[0],b[1])
		else:
			res = cmp(a,b)
	
	return res

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Try just using the tuples like (3, 3). It should work.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Yeah but the comparison shouldn't put the unbounded ranges on the outside, they need to hug the numbers, like in my previous post, (None,3) means "less than 3" and should sort right before 3, not at the beginning of the list.

Also the one I just posted doesn't work either, argh.

Carthag Tuek fucked around with this message at 00:57 on Sep 26, 2012

M31
Jun 12, 2012
The usage of cmp is deprecated (and removed in Python 3), so I would suggest using a class for this:

Python code:
from functools import total_ordering

@total_ordering
class Range(tuple):
	def __new__(cls, value):
		if type(value) == int:
			start = end = value
		else:
			start, end = value
		return tuple.__new__(cls, (start, end))

	def __lt__(self, other):
		if self[0] == None:
			if other[0] == None:
				return self[1] < other[1]
			return self[1] <= other[0]
				
		elif self[1] == None:
			if other[0] == None:
				return self[0] < other[1]
			if other[1] == None:
				return self[0] < other[0]
			return self[0] <= other[0] and self[0] < other[1]

		else:
			if other[0] == None or other[1] == None:
				return not (other < self) # Reverse comparison
			if self[0] == other[0]:
				return self[1] < other[1]
			return self[0] < other[0]

print(sorted(Range(x) for x in expected))
This also saves you from remembering what 1 and -1 mean.
Edit: bonuspoints if you derive from namedtuple and replace None with infinity.

M31 fucked around with this message at 13:44 on Sep 26, 2012

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Thanks that sorts like I wanted :)

Dren
Jan 5, 2001

Pillbug
I was going to suggest implementing a class with a comparison operator and using @total_ordering but M31 already did. So I am seconding his suggestion.

davebees
Feb 18, 2009
Very basic question that I can't work out.

Python code:
list = 10*[0]

for x in list:
	x = 1

print list
This gives
code:
[0,0,0,0,0,0,0,0,0,0]
where I would have expected a bunch of 1s.

Is it not OK to modify a list by iterating over it like that?

davebees fucked around with this message at 22:22 on Sep 26, 2012

Emacs Headroom
Aug 2, 2003

Starno posted:

Very basic question that I can't work out.

Python code:
list = 10*[0]

for x in list:
	x = 1

print list
This gives
code:
[0,0,0,0,0,0,0,0,0,0]
where I would have expected a bunch of 1s.

Is it not OK to modify a list by iterating over it like that?

Yeah, you have to put objects into the list directly. What you're doing now is looping over the list, and saying let 'x' be the name of this element. Now let 'x' be the name for the number '1'.

Python assignment works a lot like "naming" things, rather than being a reference or pointer like in java or c.

davebees
Feb 18, 2009

Emacs Headroom posted:

Yeah, you have to put objects into the list directly. What you're doing now is looping over the list, and saying let 'x' be the name of this element. Now let 'x' be the name for the number '1'.

Python assignment works a lot like "naming" things, rather than being a reference or pointer like in java or c.

Cool OK. So what would be the typical method for doing something to every item in a list? Something like this?

Python code:
list = 10*[0]

for i in range(len(list)):
	list[i] = 1

print list

OnceIWasAnOstrich
Jul 22, 2006

Starno posted:

Cool OK. So what would be the typical method for doing something to every item in a list? Something like this?

Python code:
list = 10*[0]

for i in range(len(list)):
	list[i] = 1

print list

You can use something like

Python code:
mylist = [0 for _ in xrange(10)]

for i, item in enumerate(mylist)::
	mylist[i] = 1

print list
vvvv: Damnit I was going to edit those things into my post but the forums right before I tried to submit.

OnceIWasAnOstrich fucked around with this message at 00:45 on Sep 27, 2012

Cat Plus Plus
Apr 8, 2011

:frogc00l:

Starno posted:

Cool OK. So what would be the typical method for doing something to every item in a list? Something like this?

Create a new one with a list comprehension (or map/filter). And be careful with using [something] * n — you get n references to that object, so if it's mutable, modifying one is visible in the entire list (which usually surprises people). And try not to overshadow built-in names (list).

Python code:
lst = [x * 2 for x in lst]
lst = map(lambda x: x * 2, lst)
# list comprehensions are more general
As for why your earlier loop didn't work: assignment in Python rebinds the name, it never mutates the object. You can mutate the object only using its methods. That's why assigning a list item works (because it translates to __setitem__ call).

Emacs Headroom
Aug 2, 2003

Starno posted:

Cool OK. So what would be the typical method for doing something to every item in a list? Something like this?

Python code:
list = 10*[0]

for i in range(len(list)):
	list[i] = 1

print list

Yeah that's a normal thing to do. Couple of quick notes:

1) You should in general not name things "list", since that's already in the default namespace and you never know when you might have to call it -- e.g., getting only the unique elements in a list l can be accomplished easily by calling
Python code:
l = list(set(l))
2) You can just make a new list for simple stuff like this. It won't cost you memory or anything, the old one will get garbage collected when it falls out of scope or loses its name -- all these are logically equivalent:
Python code:
for i in range(len(l)):
    l[i] = 1
l = [1]*len(l)
l = [1 for i in l]

Sylink
Apr 17, 2004

How does one write a python module in C?

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug
Well, step 1 is reading this. The detailed API reference is here.

Emacs Headroom
Aug 2, 2003
And if you're just wrapping some C code, swig is extremely easy and straightforward.


edit: vvvvv
worksforme :mad:

Emacs Headroom fucked around with this message at 15:31 on Sep 28, 2012

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Emacs Headroom posted:

swig is extremely easy and straightforward.

Might want to double check your facts there, buddy.

spankweasel
Jan 4, 2006

I've found ctypes works great for the system programming I do (I work on an OS installer and have to do a ton with C libraries)

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I've decided that 79 characters per line is too restrictive for me on the project I'm working on, and that 89 characters per line is more appropriate. But I'm loath to make an exception for docstrings, so I'm most likely just going to wrap them at the 89 character line as well. So some of the lines in the docstrings are going to end up longer than 79 characters after being treated by the automatic formatter. I think it is reasonable enough just to dismiss this as NMFP, but does the idea make anyone froth with rage?

xtal
Jan 9, 2011

by Fluffdaddy

Hammerite posted:

I've decided that 79 characters per line is too restrictive for me on the project I'm working on, and that 89 characters per line is more appropriate.

Special cases aren't special enough to break the rules. :)

Thermopyle
Jul 1, 2003

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

Hammerite posted:

I've decided that 79 characters per line is too restrictive for me on the project I'm working on, and that 89 characters per line is more appropriate. But I'm loath to make an exception for docstrings, so I'm most likely just going to wrap them at the 89 character line as well. So some of the lines in the docstrings are going to end up longer than 79 characters after being treated by the automatic formatter. I think it is reasonable enough just to dismiss this as NMFP, but does the idea make anyone froth with rage?

I stick to PEP8 on almost everything except line length. I've got a ton of monitor resolution to work with and sometimes longer lines just work better. (Almost always 79 is enough, though)

Plus, I get a lot of enjoyment out of thinking about someone in several years working on my code and ranting about the line length.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Yeah, what is that 10 characters buying you that you need so much? Is it because you're nesting too heavily?

Are you not breaking up long line statements to make them more readable, such as chained methods?

Nippashish
Nov 2, 2005

Let me see you dance!

Sylink posted:

How does one write a python module in C?

If you're willing to use C++, boost::python is actually pretty awesome for this once you figure out how to set it up properly (which is needlessly hard).

BigRedDot
Mar 6, 2008

Sylink posted:

How does one write a python module in C?

People have mentioned SWIG, but even the original author Dave Beazely does not advocate SWIG anymore. Boost::Python is fine if you don't mind depending on Boost. Rolling your own with the Python C API is also fine, if you don't mind tons of boilerplate and explicit refcount management. Some other options to consider are cython and Numba.

The Gripper
Sep 14, 2004
i am winner

BigRedDot posted:

Boost::Python is fine if you don't mind depending on Boost.
Boost::Python is fine if you don't mind spending a week troubleshooting why it isn't working/tests are all failing/whatever other trash happens <:mad:>

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Cython is cool. Writing a C module "from scratch" isn't that hard.

There's also gobject-introspection, but that's a whole other can of worms that I shall not go into.

Captain Capacitor
Jan 21, 2008

The code you say?
Depending on what you want to do, can't ctypes work as well?

And speaking of boost::python, does anyone have a good guide to it? All the documentation I've ever found has been old or incredibly confusing. Or both.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Maluco Marinero posted:

Yeah, what is that 10 characters buying you that you need so much? Is it because you're nesting too heavily?

Are you not breaking up long line statements to make them more readable, such as chained methods?

That is difficult for me to answer because I don't know what "nesting too heavily" means (to you or to anyone else). I am breaking up long statements into multiple lines, but I was finding that I had to do so a bit more frequently than I was entirely happy with. However, I have concluded that I quite like the width and readability of my code at 89 characters, so I am going to stick to it.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.

Hammerite posted:

That is difficult for me to answer because I don't know what "nesting too heavily" means (to you or to anyone else). I am breaking up long statements into multiple lines, but I was finding that I had to do so a bit more frequently than I was entirely happy with. However, I have concluded that I quite like the width and readability of my code at 89 characters, so I am going to stick to it.

By nesting I just mean nested for and if loops, so you end up a long way across the screen before you even have a character on the line. Usually in these cases you can greatly improve the readability of your code by extracting a few methods or using something from itertools to better handle the iteration.

Up to you of course, if you only have yourself to look after then go for it, but personally I prefer to do my best to stick to the standard.

Cat Plus Plus
Apr 8, 2011

:frogc00l:
Last time I used Boost.Python I just ended up using handle/object for automatic refcounting and CPython API directly. The documentation really is terrible. Cython is much better.

Thermopyle posted:

I stick to PEP8 on almost everything except line length. I've got a ton of monitor resolution to work with and sometimes longer lines just work better. (Almost always 79 is enough, though)

I use PEP8 very selectively. I don't like its advice on several things (no one-line imports, no spaces around = in keyword arguments, weird aligning rules and probably some other things I don't remember right now).

I can fit at least 120 characters on my smallest screen, and I don't care. :colbert:

TURTLE SLUT
Dec 12, 2005

This might not be exactly Python related, but - I just installed EasyEclipse for Python after a reformat and sure enough it was easy to configure for Python.

Today I discovered something super annoying though - using raw_input() in the Console appears to append an extra linebreak at the end of each input. I suppose it simply thinks the linebreak that is used to send whatever is typed into the Console should also be appended to the return value. Running the programs from Windows's command line works as expected, without no extra linebreaks.

Sure strip() or something works, but that's dumb as it might cause some problems when I don't really want to use it. Does anyone have any clue how to unfuck EasyEclipse? Or any other IDE recommendations for Windows?

Hed
Mar 31, 2004

Fun Shoe
Python 3.3.0 is out :toot:

python.org posted:

New syntax features:

New yield from expression for generator delegation.
The u'unicode' syntax is accepted again for str objects.

New library modules:

faulthandler (helps debugging low-level crashes)
ipaddress (high-level objects representing IP addresses and masks)
lzma (compress data using the XZ / LZMA algorithm)
unittest.mock (replace parts of your system under test with mock objects)
venv (Python virtual environments, as in the popular virtualenv package)

New built-in features:

Reworked I/O exception hierarchy.

Implementation improvements:

Rewritten import machinery based on importlib.
More compact unicode strings.
More compact attribute dictionaries.

Significantly Improved Library Modules:

C Accelerator for the decimal module.
Better unicode handling in the email module (provisional).

Security improvements:

Hash randomization is switched on by default.

Lysidas
Jul 26, 2002

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

:toot: indeed. It looks like almost everything I use is compatible with 3.3, with the notable exception of SciPy. I'm using development versions of a lot of packages, but I'm okay with that for the moment.

It also looks like Pygments was finally updated for the new yield from syntax; this section of the docs didn't have any syntax highlighting when I downloaded a copy of the documentation on Saturday :v:


EDIT: Damnit, there's a package that doesn't work with 3.3 for this reason and I'm the one who did the 3.x compatibility changes. I'm not looking forward to fixing this.

Lysidas fucked around with this message at 18:59 on Oct 1, 2012

pliable
Sep 26, 2003

this is what u get for "180 x 180 avatars"

this is what u fucking get u bithc
Fun Shoe

JOHN SKELETON posted:

Or any other IDE recommendations for Windows?

I've got a huge boner for PyCharm + vim plugin, personally. However, it's a pretty steep price at $99 :(. I use it for work though, and I've had nothing but positive things to say about it. You can do horizontal or vertical splits, the IDE tries to autodetect your calls and resolve them for you, you can autooptimize code with one button...list goes on and on :).

Otherwise, if you want to go the free route, I'd go Vim + good 'ol Python command line interpreter.

Adbot
ADBOT LOVES YOU

OnceIWasAnOstrich
Jul 22, 2006

pliable posted:

I've got a huge boner for PyCharm + vim plugin, personally. However, it's a pretty steep price at $99 :(. I use it for work though, and I've had nothing but positive things to say about it. You can do horizontal or vertical splits, the IDE tries to autodetect your calls and resolve them for you, you can autooptimize code with one button...list goes on and on :).

Otherwise, if you want to go the free route, I'd go Vim + good 'ol Python command line interpreter.

I bought the student version of PyCharm for $29 and love it, although I mostly use it on OSX. I'm assuming its pretty similar for Windows since its all Java-based, and if you are using it for some open-source project you can get a free license.

  • Locked thread