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
Spime Wrangler
Feb 23, 2003

Because we can.

What's the current consensus on GUI frameworks and tools? I'm looking at sticking with wxPython (having written little more with it than a hello world app) but thought I'd check if there are any new killer tools before getting too invested.

Adbot
ADBOT LOVES YOU

tripwire
Nov 19, 2004

        ghost flow
I've used pyqt and the drag/drop gui builder they have seems to work as advertised, as far as I can see. I can't say I feel really strongly about it one way or the other though; and I haven't used wxwidgets to compare it against.

Scaevolus
Apr 16, 2007

I like PyQt for the same reason. Trying to specify your user interface with pure code is painful.

Lurchington
Jan 2, 2003

Forums Dragoon

Scaevolus posted:

I like PyQt for the same reason. Trying to specify your user interface with pure code is painful.

I've used WxPython and it was doable, but certainly not great for the layout of UI elements. It's pretty obvious about its C/C++ roots as well when it came to naming conventions/etc.

No idea if any of the other toolkits/frameworks are better about that.

Lorem ipsum
Sep 25, 2007
IF I REPORT SOMETHING, BAN ME.

Scaevolus posted:

I like PyQt for the same reason. Trying to specify your user interface with pure code is painful.

Yea, PyQt is the way to go. If you just want a single button or two, the new tkinter with themed widgets actually looks ok now, and is quick to write.

UltraShame
Nov 6, 2006

Vocabulum.

tef posted:

Use PEP8

This is super helpful, and I can't believe I glossed over it/missed it.

thanks man, and thanks for the other tips.

e: In regards to not worrying about OOP, in hindsight you're right. I'm happy I was able to write a working program that, if I read it a week ago, would have been gibberish. Cart doesn't go before horse. Thanks for pointing that out.

UltraShame fucked around with this message at 20:17 on Dec 6, 2010

Spime Wrangler
Feb 23, 2003

Because we can.

Alright, giving PyQt a shot. A graphical layout editor will certainly be nice.

The verbosity of doing really simple stuff manually was a real turn-off last time around. I guess the ease of using python for most other things has spoiled me a bit.

tef
May 30, 2004

-> some l-system crap ->

UltraShame posted:

This is super helpful, and I can't believe I glossed over it/missed it.

thanks man, and thanks for the other tips.

e: In regards to not worrying about OOP, in hindsight you're right. I'm happy I was able to write a working program that, if I read it a week ago, would have been gibberish. Cart doesn't go before horse. Thanks for pointing that out.

basically, use as little complexity to solve your problem.

sometimes oop can introduce more complexity than it removes.

solving them in a more procedural way is a nice way to move onto oop. You can see your basic data type
and the operations it supports. if you want to jam everything into objects you should use java :)


there is an old saying 'debugging code is twice as hard as writing it, so if you write to the best of your ability you're no longer qualified to debug it'.

UltraShame
Nov 6, 2006

Vocabulum.

tef posted:

basically, use as little complexity to solve your problem.

sometimes oop can introduce more complexity than it removes.

After I read the "you should use OOP" hint, I went and attempted to re-write the program that way, thinking I had done something fundamentally wrong. After a few minutes I just stopped and said "this is stupid, I already solved the problem." I figure when I run into a situation where OOP is truly appropriate, it'll be more obvious.

Going to burn through Google's python lessons, and in the meantime, write some more increasingly complex programs. Thanks for taking the time to respond, tef.

DirtyDiaperMask
Aug 11, 2003

by Ozmaugh

UltraShame posted:

After I read the "you should use OOP" hint, I went and attempted to re-write the program that way, thinking I had done something fundamentally wrong. After a few minutes I just stopped and said "this is stupid, I already solved the problem." I figure when I run into a situation where OOP is truly appropriate, it'll be more obvious.

Going to burn through Google's python lessons, and in the meantime, write some more increasingly complex programs. Thanks for taking the time to respond, tef.

The exercise is a simple one and there's not really much a reason to diverge from a simpler procedural approach for that sort of short script, but the exercise was probably also intended to get the programmer to approach the problem in an OOP fashion. In that example, note that you're applying various functions to the address book, so it could make sense to create an AddressBook class and transform those functions into its methods.

theshadowhost
May 16, 2008

Congratulations on not getting fit in 2011!
I'm trying to optimise this code to compute the ego betweenness of nodes in a network (click here for source paper if you are interested: http://www.analytictech.com/borgatti/papers/egobet.pdf ). The following snippet is to calculate the paths of length two in the network.

code:
pathlengthcounts = [(1 + (sum(1 
                              for z in self.edgelist[x]
                              if y in self.edgelist[z])))
                     for x in self.socialnetwork
                     for y in self.socialnetwork
                     if  (not (y == x)) and (x<y) and (not(y in self.edgelist[x]))]
self.socialnetwork is a set, and self.edgelist is a defaultdict(set). Essentially you want to calculate the number of paths of length two in the edgelist, so you dont need to worry about the node that is calling this function, as it doesnt have any paths of length two. You dont want any check connections to themselves and you dont need to check if you are connected to the other node hence (not (y == x)) and (x<y) and (not(y in self.edgelist[x]) respectively.

You only need to calculate values when there is not a direct connection and you only need to calculate for half the "matrix" as links are assumed to be symmetrical.

I am running python 2.5 though I have access to 2.6.

The code works, but I need it to be as fast as possible, is there something I am missing? Maybe I could try to pre-calculate the elements in the matrix i need to check rather than looping?

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"
If you need it to be as fast as possible, why the gently caress are you writing it in Python?

Write it in C, drop it into an extension module, then call it from your main library.

Rohaq
Aug 11, 2006
So, I've got a file I need to parse some details out of.

There are sets of results, separated by '--------------------', I need to parse each of these in order, is there any easy way to do this in Python? In Perl, all I had to do was change the separator variable $/ to whatever I needed, then do a standard for loop on the string containing them. Seems a bit odd if Python doesn't have a built in method or module available to simplify this.

Thermopyle
Jul 1, 2003

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

Rohaq posted:

So, I've got a file I need to parse some details out of.

There are sets of results, separated by '--------------------', I need to parse each of these in order, is there any easy way to do this in Python? In Perl, all I had to do was change the separator variable $/ to whatever I needed, then do a standard for loop on the string containing them. Seems a bit odd if Python doesn't have a built in method or module available to simplify this.

str.split('--------------------')

Rohaq
Aug 11, 2006

Thermopyle posted:

str.split('--------------------')
I was thinking more of a method to iterate through a file splitting over each instance of that string, without loading the file's content into memory.

Here's a Perl example:

code:
#!/usr/bin/perl

$/ = "--------------------\n";

open(my $file,'file.txt');

while(<$file>) {
  print $_,"\n";
}

close($file);

exit;

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
While translating from one language to another is rarely a 1:1 affair, I will say that the Perl you're translating from has a few superfluous elements and a few headscratch-inducing statements. I'm also curious if the output is intended to be double-spaced.

Nb. that your [mis]statement that you were looping over the "string containing them" is probably what caused Thermopyle to think you had the whole thing slurped into memory such that a split() would be appropriate.

Lurchington
Jan 2, 2003

Forums Dragoon
well, to make it sane, if you restrict your marker to something that's on it's own line (which is a fair assumption) then there's this:

code:
>>> def readlines_marker(fobj, marker):
...     accrued_lines = []
...     for line in fobj:
...             if line != marker:
...                     accrued_lines.append(line)
...             else:
...                     yield accrued_lines
...                     accrued_lines = []
print "here's your stuff: %r" % ', '.join(str(content) for content in readlines_marker(open('test_txt', 'rb'), '--------------------\n'))
pre:
here's your stuff: "[], ['what\\n'], ['up\\n', 'in\\n'], ['this thread\\n'], ['1\\n', '2\\n', '3\\n', 'for real?\\n']"
pre:
more test_txt
--------------------
what
--------------------
up
in
--------------------
this thread
--------------------
1
2
3
for real?
--------------------
short version: generators (notice the yield) are awesome

(if you don't want the trailing \n, slice the line as you append it)

PraxxisParadoX
Jan 24, 2004
bittah.com
Pillbug
Please critique my first Python "library", which I forked from some other guy and "improved": https://github.com/praxxis/turbine

One thing that bugs me is documentation. I'm used to PHPDoc, which has a pretty simple syntax IMO - from what I've seen of Python class documentation, its all reStructured text, which I find kinda... loose? I like putting in my @param's and whatnot, but I cant see if there's a "standard" way of documenting in Python. What does everyone else do for documentation?

UltraShame
Nov 6, 2006

Vocabulum.
Otto: The only programming experience I have beyond GWBASIC and dabbling is when I worked on a job in a small business where the technical guy quit, so he showed me how to keep the ugliest records system ever (computers and manila folders notwithstanding) running with his perl stuff and change and add to it in the most rudimentary way possible. I should have explained that. regexps made sense to me, perl itself kind of didn't.

After reading again through 'A Byte of Python', it really made me pick up quite a few badHabits.

quote:

One thing that bugs me is documentation.
I'm totally guilty of this. It's kind of hard when you don't have any expert instruction. There is so much to it, and it's very technically written, so it can be hard to know where to look to solve a seemingly very obvious or specific problem. I had no idea how much the example code in 'A Byte' contradicted the proper way of doing things. I did go back, and made sure everything conformed to what tef posted, and what he did post is obviously useful. The python notation in PE8 that he showed is pretty ingenious.

quote:

Please critique my first Python "library", which I forked from some other guy and "improved":
don't be a dick, I wrote my entire horrid program by myself. Sure, I want to see how the code does its thing, but don't be a dick.

Lurchington
Jan 2, 2003

Forums Dragoon

PraxxisParadoX posted:

One thing that bugs me is documentation. I'm used to PHPDoc, which has a pretty simple syntax IMO - from what I've seen of Python class documentation, its all reStructured text, which I find kinda... loose? I like putting in my @param's and whatnot, but I cant see if there's a "standard" way of documenting in Python. What does everyone else do for documentation?

Sounds like you're describing epydoc's fields. The only real 'standard' in python I know of is use docstrings instead of comment blocks, and make sure it generates a nice helpful html version.

Rohaq
Aug 11, 2006

Otto Skorzeny posted:

While translating from one language to another is rarely a 1:1 affair, I will say that the Perl you're translating from has a few superfluous elements and a few headscratch-inducing statements. I'm also curious if the output is intended to be double-spaced.

Nb. that your [mis]statement that you were looping over the "string containing them" is probably what caused Thermopyle to think you had the whole thing slurped into memory such that a split() would be appropriate.

That was purely an example to show what I meant; I altered the termination point so that it would load everything between two sets of dashes. In my actual script, I'm likely going to use regular expressions to parse information out of each record. I don't want to load it all into memory, and then split it, because I may be working with large files.

Lurchington posted:

well, to make it sane, if you restrict your marker to something that's on it's own line (which is a fair assumption) then there's this:

code:
>>> def readlines_marker(fobj, marker):
...     accrued_lines = []
...     for line in fobj:
...             if line != marker:
...                     accrued_lines.append(line)
...             else:
...                     yield accrued_lines
...                     accrued_lines = []
print "here's your stuff: %r" % ', '.join(str(content) for content in readlines_marker(open('test_txt', 'rb'), '--------------------\n'))
pre:
here's your stuff: "[], ['what\\n'], ['up\\n', 'in\\n'], ['this thread\\n'], ['1\\n', '2\\n', '3\\n', 'for real?\\n']"
pre:
more test_txt
--------------------
what
--------------------
up
in
--------------------
this thread
--------------------
1
2
3
for real?
--------------------
short version: generators (notice the yield) are awesome

(if you don't want the trailing \n, slice the line as you append it)
This looks interesting, thanks!

Captain Capacitor
Jan 21, 2008

The code you say?

PraxxisParadoX posted:

Please critique my first Python "library", which I forked from some other guy and "improved": https://github.com/praxxis/turbine

One thing that bugs me is documentation. I'm used to PHPDoc, which has a pretty simple syntax IMO - from what I've seen of Python class documentation, its all reStructured text, which I find kinda... loose? I like putting in my @param's and whatnot, but I cant see if there's a "standard" way of documenting in Python. What does everyone else do for documentation?

I'm a big fan of Sphinx. It does a decent job of scanning modules and picking up certain details. It's meant more as a separate documentation system, but once you get it set up to your liking it produces a number of formats really quickly.

Edit:
And it may be pedantic, but I personally wouldn't have gone with the "_coerce_list" method. I would have just done the following:

code:
def filter_usernames(self, usernames):
		"""Track a list of usernames.
		"""
		self.usernames += list(usernames)

Captain Capacitor fucked around with this message at 17:43 on Dec 8, 2010

PraxxisParadoX
Jan 24, 2004
bittah.com
Pillbug

Captain Capacitor posted:

I'm a big fan of Sphinx. It does a decent job of scanning modules and picking up certain details. It's meant more as a separate documentation system, but once you get it set up to your liking it produces a number of formats really quickly.
Yea, I looked at Sphinx. It just seems far less obvious than say, JavaDoc or PHPDoc.

Captain Capacitor posted:

Edit:
And it may be pedantic, but I personally wouldn't have gone with the "_coerce_list" method. I would have just done the following:

code:
def filter_usernames(self, usernames):
		"""Track a list of usernames.
		"""
		self.usernames += list(usernames)

code:
>>> username = "praxxis"
>>> list(username)
['p', 'r', 'a', 'x', 'x', 'i', 's']
:bang:

leterip
Aug 25, 2004
Why not just use append?

>>> usernames = []
>>> usernames.append("praxxis")
>>> usernames
['praxxis']
>>>

UltraShame
Nov 6, 2006

Vocabulum.
Ok, I'll stop my programming 101 poo poo, resume your productive discussion. Sorry, fellas.

PraxxisParadoX
Jan 24, 2004
bittah.com
Pillbug

leterip posted:

Why not just use append?

>>> usernames = []
>>> usernames.append("praxxis")
>>> usernames
['praxxis']
>>>

Would you believe that such a simple solution never occurred to me. Well played :(

nbv4
Aug 21, 2002

by Duchess Gummybuns
A while ago a coworker of mine mentioned that the PEP-8 requirement to keep your code under 79 characters wide was made obsolete by a later PEP which increases the limit to 120 characters. I have searched and searched but can not find this magical newer line-extending PEP. Does anybody know what my coworker may be thinking about?

king_kilr
May 25, 2007

nbv4 posted:

A while ago a coworker of mine mentioned that the PEP-8 requirement to keep your code under 79 characters wide was made obsolete by a later PEP which increases the limit to 120 characters. I have searched and searched but can not find this magical newer line-extending PEP. Does anybody know what my coworker may be thinking about?

Cocaine.

nbv4
Aug 21, 2002

by Duchess Gummybuns

king_kilr posted:

Cocaine.

Figured as much.

Anyways, I have another question. I have a module that looks like this:

code:
module_name
   __init__.py (empty)
   some_file.py
   utils.py
   exceptions.py
In some_file.py I want to import stuff from exceptions. I try doing "from exceptions import MyException", but that doesn't work because there is a builtin module called "exceptions" which contains all built-in exceptions. I don't really want to rename my exceptions.py file to something like my_exceptions.py because that sucks. How should I name this file so it can be imported?

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

nbv4 posted:

Figured as much.

Anyways, I have another question. I have a module that looks like this:

code:
module_name
   __init__.py (empty)
   some_file.py
   utils.py
   exceptions.py
In some_file.py I want to import stuff from exceptions. I try doing "from exceptions import MyException", but that doesn't work because there is a builtin module called "exceptions" which contains all built-in exceptions. I don't really want to rename my exceptions.py file to something like my_exceptions.py because that sucks. How should I name this file so it can be imported?

from .exceptions import MyException

nbv4
Aug 21, 2002

by Duchess Gummybuns

Janin posted:

from .exceptions import MyException

ValueError: Attempted relative import in non-package

Lurchington
Jan 2, 2003

Forums Dragoon
Which version of python is this? I think there were some relevant changes between versions

you could also try:
from module_name.exceptions import MyException
this is the kind of thing that always bugs me though, so, meh.

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

nbv4 posted:

ValueError: Attempted relative import in non-package
How are you importing some_file ?

The correct way to handle imports is either absolute (import module_name.some_file) or relative (import .some_file , import ..other_module.foo). Relying on old behavior like semi-absolute imports will cause unpredictable failures during imports.

in some_file, do something like this to see how it's being imported:

code:
# in some_file.py
# should print "module_name.some_file"
print "__name__ = %r" % (__name__,)
from .exceptions import MyException

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Yet another 'critique my code' post. I needed to read a file backwards for some reason and mashed some horrible script out of Google snippets, so I figured it would be a nice exercise to make it look nice(r).

http://pastebin.com/npK2YzDc

The main questions are asked in inline comments, but I'm looking at overall Pythonicity, as well.

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

Munkeymon posted:

Yet another 'critique my code' post. I needed to read a file backwards for some reason and mashed some horrible script out of Google snippets, so I figured it would be a nice exercise to make it look nice(r).

http://pastebin.com/npK2YzDc

The main questions are asked in inline comments, but I'm looking at overall Pythonicity, as well.

code:
def ReadFile(file, buffer_size = 4096):
Function names are traditionally written all lowercase, with underscores. CamelCase is used for class names. Also, `file` is a builtin type, so you don't want to clobber that.

code:
	import re, os
	from types import StringType, FileType
imports should generally be at the top of the file, not inside of functions. There are times you want to conditionally import, but this isn't one of them. Also, the types module is mostly obsolete, and in this case you could just use `str` and `file`

code:
	opened_file = isinstance(file, StringType)
	if opened_file:
		file = open(file, 'rb')
	elif not isinstance(file, FileType):
		raise TypeError('file argument was not a String or a File')
Type checking is usually the wrong way to do things. Here, I would probably do something like this:

code:
try:
    file.seek(0, os.SEEK_END)
except AttributeError:
    f = open(file, 'rb')
    f.seek(0, os.SEEK_END)
and let either file mode errors or IOErrors bubble up

code:
	
	if opened_file:
		#it's our responsibility to clean up
		file.close()
the file will get closed when it goes out of scope

code:
	return
no need to explicitly return at the end of a function. A bare return returns None, and so does no return.

I'll play with the meat of the function a little more, it does feel like there should be a better way, but I don't really do a whole lot of file handling.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Sailor_Spoon posted:

the file will get closed when it goes out of scope
This is a cpython implementation detail.

Lurchington
Jan 2, 2003

Forums Dragoon
Closing the file with either a with statement or a try-finally is usually better.


itertools.islice(open('your_file', 'rb'), -1, 0, -1)
:toot:
Just kidding. It'd be neat though

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Lurchington posted:

Closing the file with either a with statement or a try-finally is usually better.


itertools.islice(open('your_file', 'rb'), -1, 0, -1)
:toot:
Just kidding. It'd be neat though

Yeah, don't think I didn't check itertools first.

Sailor_Spoon posted:

stuff

It started life as a class before I realized I could just write a generator and skip all the manual state management bullshit, thus TheName. Also, I should have mentioned it was supposed to be used like a module, so that's why I did my importing inside the function - I guess I'll move that to an __init__ block?

Edit: hmm, looks like I was misunderstanding the format requirements of a module - this is easier than I thought

Sailor_Spoon posted:

Type checking is usually the wrong way to do things. Here, I would probably do something like ... and let either file mode errors or IOErrors bubble up

Wouldn't that be a lot less useful to an end user? Consider what happens when the user (hopefully accidentally) passes in a file that happens to not be seekable: "Why is that stupid module trying to call open on the file I sent in?!" Then they have to read and understand the code to know why something is failing.

Munkeymon fucked around with this message at 17:57 on Dec 14, 2010

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

Munkeymon posted:

Wouldn't that be a lot less useful to an end user? Consider what happens when the user (hopefully accidentally) passes in a file that happens to not be seekable: "Why is that stupid module trying to call open on the file I sent in?!" Then they have to read and understand the code to know why something is failing.

Depends on your user, I guess. I'd much rather get an error then have the function return None, which could mean a lot of things.

Also, does a file that's not seekable still have the seek method? I assumed it does, so an error on seek would presumably not get caught by that except.

Adbot
ADBOT LOVES YOU

tef
May 30, 2004

-> some l-system crap ->
code:
with open(...) as fh:
     lines = reversed(fh.readlines())
:v:

  • Locked thread