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
Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.
Man you might as well make a useful decorator, like one that adds TCO to functions.

It was pretty fun to write.

Adbot
ADBOT LOVES YOU

tripwire
Nov 19, 2004

        ghost flow

Habnabit posted:

Man you might as well make a useful decorator, like one that adds TCO to functions.

It was pretty fun to write.

Wow, this is really cool! Do you think people would get pissed off if I used this decorator freely in projects like it was a built-in?

tef
May 30, 2004

-> some l-system crap ->
Yes. And you can re-write most code to not depend on tco quite easily.

tripwire
Nov 19, 2004

        ghost flow
Aw :(
Quit ruining my fun.

m0nk3yz
Mar 13, 2002

Behold the power of cheese!

tripwire posted:

Wow, this is really cool! Do you think people would get pissed off if I used this decorator freely in projects like it was a built-in?

Yes, people would get pissed. Oh god it burnses us.

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.
Well, the resulting bytecode really isn't that bad! The hack itself isn't too pretty, and it has a few restrictions on how the function has to be defined and called, but I like it. :(

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:19 on Mar 13, 2017

tripwire
Nov 19, 2004

        ghost flow

Habnabit posted:

Well, the resulting bytecode really isn't that bad! The hack itself isn't too pretty, and it has a few restrictions on how the function has to be defined and called, but I like it. :(

I thought it was cool too. While python is a breath of fresh air compared to many lower level languages, I don't know whether I agree 100% with every aspect the python ideology, specifically in the case of tail call recursion. I agree that python's legibility and ease of use are among its strongest points and as Guido van Rossum says, adding in tail call optimization at the very least complicates backtraces, but even if that were fixed it would still be unacceptable to Guido: ideologically it prioritizes extended functionality over legibility and ease of use. His words on multi-line lambdas indicated he felt pretty strongly about this principle:

Guido van Rossum posted:

And there's the rub: there's no way to make a Rube Goldberg language feature appear simple. Features of a programming language, whether syntactic or semantic, are all part of the language's user interface. And a user interface can handle only so much complexity or it becomes unusable. This is also the reason why Python will never have continuations, and even why I'm uninterested in optimizing tail recursion. But that's for another installment.

I still think though that if you are going to call the language multi-paradigm, you still provide some minor facilities to ease the use of things people might want to experiment with, regardless of whether or not that paradigm is deemed "unpythonic". I admit there might be a risk of the language becoming a bit more like perl, in that there would be multiple ways of accomplishing the same thing with similar efficiency as opposed to the pythonic maxim of only having one obvious best way to do things. So what though? If it increases the number of people using python by making it more accommodating to a wide variety of styles and backgrounds its better for everyone, as far as I can see.

Scaevolus
Apr 16, 2007

GregNorc posted:

code:
lovemachine:python gregnorc$ python hackjack.py 
Traceback (most recent call last):
  File "hackjack.py", line 8, in <module>
    create_deck();
  File "hackjack.py", line 4, in create_deck
    for value in xrange(1, 14): #ace (1) --> King(13)
NameError: global name 'xrange' is not defined

You're using py3k, right? Use range(), not xrange().

Previously, range() returned a list and xrange() returned an iterator, but they simplified it to just having range() which returns an iterator.

tef
May 30, 2004

-> some l-system crap ->

Habnabit posted:

Well, the resulting bytecode really isn't that bad! The hack itself isn't too pretty, and it has a few restrictions on how the function has to be defined and called, but I like it. :(

I think it's awesome, but I wouldn't use bytecode hacking in production code :v:

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:19 on Mar 13, 2017

Avenging Dentist
Oct 1, 2005

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

GregNorc posted:

that solved it but printing the list gives me an error

You do realize that one of the most visible changes in py3k is that print is a function, right?

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:19 on Mar 13, 2017

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

GregNorc posted:

Oops, no I didn't.

I put it in as a function but now it tells me "NameError: name 'deck' is not defined". Which seems odd since I just called the create_deck function so it should exist.

create_deck() just returns the deck, but you have to assign it to something in the module namespace. So instead of just calling create_deck(), you should say something like:
code:
deck = create_deck()
The 'deck' variable that you created is inside the namespace of the create_deck function, so that print call has no knowledge of it.

tef
May 30, 2004

-> some l-system crap ->

tripwire posted:

... and as Guido van Rossum says, adding in tail call optimization at the very least complicates backtraces, but even if that were fixed it would still be unacceptable to Guido: ideologically it prioritizes extended functionality over legibility and ease of use.

If it didn't have that ideology it would be a remarkably different language. Accepting a feature like (automatic) TCO sets a precedent for more complex language features, as well as bloating the cpython interpreter.

quote:

I still think though that if you are going to call the language multi-paradigm, you still provide some minor facilities to ease the use of things people might want to experiment with, regardless of whether or not that paradigm is deemed "unpythonic".

At this point it stops being python though. Python isn't about experimentation with language facilities but being able to write and maintain simple readable code.

quote:

I admit there might be a risk of the language becoming a bit more like perl, in that there would be multiple ways of accomplishing the same thing with similar efficiency as opposed to the pythonic maxim of only having one obvious best way to do things.

So what though? If it increases the number of people using python by making it more accommodating to a wide variety of styles and backgrounds its better for everyone, as far as I can see.

Except maintenance programmers. Software is frequently read and maintained, and so having a small feature set ensures alleviates the burden. By adding spurious features replicating existing functionality you dramatically increase the amount of knowledge required to maintain existing programs.

I'm not saying I agree with the choices python has made, but python is not the sort of language to bloat for the sake of expressiveness at the cost of complexity.

Thermopyle
Jul 1, 2003

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

As a fairly novice programmer who's beginning to write more complex pieces of code, I'd like more advanced programmers to look at my code and tell me how badly I've hosed up.

I've currently got a class I'm writing that takes a filename of a downloaded TV show and tries to parse out the episode and season number. It's about 100 lines long so far.

Is there a good site out there focusing on hooking up programmers who are willing to look at other people's code? Would someone here like to look at it and make some comments for me?

edit: Hell, i'll throw it up on pastebin and if someone wants to look they can just do it....

http://pastebin.com/ma24c43

sample use:

code:
file = r"Doctor Who 070 - 11x01-04 - The Time Warrior (complete).avi"

show = TV_Show(file)
print show.parse_name()

Thermopyle fucked around with this message at 22:13 on Sep 7, 2009

nbv4
Aug 21, 2002

by Duchess Gummybuns
Recently I discovered the wonderfilness of "import pdb; pdb.set_trace()" to help debug my code. The only problem is that, for some reason it always screws up my terminal. If I exit the debug prompt with "exit", it'll be OK, but if I use ctrl+c or if I save a file in my django folder (and thus triggering a development server restart), it renders my terminal unusable. When I type something, the text doesn't show up on the screen. The text is there, I just can't see it. This is very annoying. The only way to fix it is to crtl+d, then relaunch gnome-terminal. This happens with urxvt as well as gnome-terminal. Is this a known issue, and if so are there work arounds?

No Safe Word
Feb 26, 2005

I've found pdb's postmortem pm() to be pretty handy as well, and you don't even have to instrument your code ahead of time necessarily.

fischtick
Jul 9, 2001

CORGO, THE DESTROYER

Fun Shoe

nbv4 posted:

When I type something, the text doesn't show up on the screen. The text is there, I just can't see it. This is very annoying. The only way to fix it is to crtl+d, then relaunch gnome-terminal. This happens with urxvt as well as gnome-terminal. Is this a known issue, and if so are there work arounds?

I can't help with the particulars of pdb, but you can type 'reset' and the terminal should... reset.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

Thermopyle posted:

As a fairly novice programmer who's beginning to write more complex pieces of code, I'd like more advanced programmers to look at my code and tell me how badly I've hosed up.

I've currently got a class I'm writing that takes a filename of a downloaded TV show and tries to parse out the episode and season number. It's about 100 lines long so far.

Woah.

Actually, given the number of datums you're trying to parse out of the string, 100 lines may not be unreasonable. Your code isn't too bad. A few general comments:

* Take the regexes out of the class and express them as constants. This will make your class leaner and easier to read. They could be written more simply as:

code:
TITLE_PATTERNS= [
   r'^(.+?)[ \._\-]\[[Ss]([0-9]+?)\]_\[[Ee]([0-9]+?)\]?[^\\/]*$',,
   r'^(.+?)[ \._\-]\[?([0-9]+)x([0-9]+)[^\\/]*$',,
   r'^(.+?)[ \._\-][Ss]([0-9]+)[\.\- ]?[Ee]([0-9]+)[^\\/]*$',,
   r'^(.+)[ \._\-]([0-9]{1})([0-9]{2})[\._ -][^\\/]*$',,
   r'^(.+)[ \._\-]([0-9]{2})([0-9]{2,3})[\._ -][^\\/]*$',,
]

TITLE_REGEXS = [re.compile (x) for x in TITLE_PATTERNS]
* There's a dictum in OOP that classes should never be in an illegal state. Currently you have to create the object and then call the parse function to set it up. Call parse from __init__.

* Maybe break out code blocks like the one that tests for a valid show name or the bit that parses episodes numbers into separate methods or functions. Again, it makes things more readable.

* You're using a few magic numbers in there, i.e. naked constants like '2' and '3'. These would be better phrased as (say) 'removal_cutoff' and 'max_ep_index' for readability (again).

* You're not catching the problem that occurs when no regex is matched. Not necessarily bad - maybe you want a TVShow object with no fields filled in - but alternatively throwing an exception might be called for.

tef
May 30, 2004

-> some l-system crap ->
That and there is almost no reason to make it a class over a function that returns a string

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

tef posted:

That and there is almost no reason to make it a class over a function that returns a string

I'd assumed the developer may have wanted to keep the class around, to query specific fields and so on, but yes. If the only necessary return value is the generated name, then a class is overkill.

Lurchington
Jan 2, 2003

Forums Dragoon

Thermopyle posted:

As a fairly novice programmer who's beginning to write more complex pieces of code, I'd like more advanced programmers to look at my code and tell me how badly I've hosed up.

I've currently got a class I'm writing that takes a filename of a downloaded TV show and tries to parse out the episode and season number. It's about 100 lines long so far.

Is there a good site out there focusing on hooking up programmers who are willing to look at other people's code? Would someone here like to look at it and make some comments for me?

edit: Hell, i'll throw it up on pastebin and if someone wants to look they can just do it....

http://pastebin.com/ma24c43

sample use:

code:
file = r"Doctor Who 070 - 11x01-04 - The Time Warrior (complete).avi"

show = TV_Show(file)
print show.parse_name()

I've been fooling around with TV Show name parsing for a LONG time, and depending on how much you delve into it, you can see all my work at Keasby's google code repo.

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:19 on Mar 13, 2017

supster
Sep 26, 2003

I'M TOO FUCKING STUPID
TO READ A SIMPLE GRAPH
You really need to step back and read about some fundamental programming concepts such as how subroutines and variable scopes work.

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:19 on Mar 13, 2017

AzraelNewtype
Nov 9, 2004

「ブレストバーン!!」

GregNorc posted:

Everything I've seen either assumes no prior knowledge and spends page after page explaining really simple things like the difference between int and float, or assume I'm an expert at programming who's just never used python before.

If you have any suggestions on what to read I'll definitely check them out before moving any further on this project. :)

No offense, but looking at what you pasted in there, I'm not sure you actually have any prior knowledge to speak of. Read the tutorial listed in the OP.

Let's go through the problem bits to illustrate exactly why we're being so harsh.

code:
    
 11 def shuffle_deck(deck):
 12         deck = create_deck # this is setting a variable named deck equal to the function create_deck, it is not creating it
 13         shuffle(deck) # since you're passing it a function rather than a collection
 14         return deck_r # there is no deck_r, there is only deck
 15         
 16 deck_r = shuffle() # you're calling random.shuffle here with no arguments instead of your own shuffle_deck(), which doesn't actually need the deck argument so you'd be better off changing it in line 11
 17 print(deck_r);
Seriously. You're a complete beginner. There's no shame in that at all, but there is shame in pretending otherwise. Start from the very beginning.

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

GregNorc posted:

ATLbeer's solution was pretty cool but I seperated creating the deck and shuffling it into two functions so it's a bit easier to read (right now I wanna work on the basics before I try anything too complex)

However when I run this code:

code:
1 #!/usr/bin/python
  2 from random import * #loads built in shuffle function
  3 
  4 def create_deck():
  5         deck = []
  6         for suit in ('Hearts', 'Clubs','Spades','Diamonds'):
  7                 for value in range(1, 14): #ace (1) --> King(13)
  8                         deck.append((suit, value))
  9         return deck;    
 10         
 11 def shuffle_deck(deck):
 12         deck = create_deck
 13         shuffle(deck)
 14         return deck_r
 15         
 16 deck_r = shuffle() #deck_r = deck random 17 print(deck_r);
I get the following error:
code:
Traceback (most recent call last):
  File "hackjack.py", line 17, in <module>
    deck_r = shuffle() #deck_r = deck random
TypeError: shuffle() takes at least 2 positional arguments (1 given)
Which doesn't really make sense to me, I went to the python documentation and it says that only one argument is required to shuffle, and that the other is optional:

http://docs.python.org/3.1/library/random.html:

You are correct, shuffle only requires one argument. But on line 16, you are calling it without any arguments. There is no introspection done into the names of functions or variables by the compiler. Calling a function "shuffle_deck" does not link it in any way to objects or concepts that may be named "shuffle" or "deck".

Have you read through the standard tutorial? If there are parts of it that feel too remedial, then by all means at least skim them, but it sounds like there is still going to be some useful stuff in there. And as mentioned earlier, Dive Into Python is a great resource. It does bill itself as a "Python book for experienced programmers", but I think that's a bit of an exaggeration.

maskenfreiheit
Dec 30, 2004
Edit: doublepost

maskenfreiheit fucked around with this message at 01:19 on Mar 13, 2017

Scaevolus
Apr 16, 2007

GregNorc posted:

Reading error messages closely is always helpful:

File "hackjack.py", line 17, in <module>

Rat Supremacy
Jul 15, 2007

The custom title is an image and/or line of text that appears below your name in the forums
How exactly would I implement ping in 2.6? I've found this example:
http://code.activestate.com/recipes/409689/

But it doesn't actually work (I get a socket.error: [Errno 10013] An attempt was made to access a socket in a way forbidden by its access
permissions
). I was going to read through that example and try to understand it, but if it doesn't work, I'm not sure what to do.

A bit more googling suggests that the socket I was trying to use was already bound, but surely I don't need to do this for PING??

ctz
Feb 6, 2003
You need to be at least in the local admins group on NT to use raw sockets.

tef
May 30, 2004

-> some l-system crap ->
And root on unix.

Thermopyle
Jul 1, 2003

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

outlier posted:

Woah.

...lots of really useful feedback...

Thank you! Exactly the sort of information I was hoping for.

tef posted:

That and there is almost no reason to make it a class over a function that returns a string

You know, I started to write a function and then I decided I'm going to stop dicking around and make myself learn how the hell classes work. Besides, in the future I may expand this into a more full-featured program where I'd like to be able to query each bit of info. I was under the impression that a class would would facilitate that better.

Lurchington posted:

I've been fooling around with TV Show name parsing for a LONG time, and depending on how much you delve into it, you can see all my work at Keasby's google code repo.

Thanks, I'll look it over.

BeefofAges
Jun 5, 2004

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

What's a good way to learn GUI programming?

For the last little app I wrote (a disk benchmark - http://sourceforge.net/apps/mediawiki/copytest/), I used TkInter, and managed to get an ugly but functional GUI working. However, it had some issues, like the fact that the GUI froze every time the program was actually doing anything. Does this just mean that I should have created new threads for things besides the GUI, or was I doing something else wrong?

I want to learn how to use PyQt, because it actually has a utility for building GUIs instead of having to hand-code them. However, there don't seem to be any good PyQt tutorials out there, and the documentation I can find is a confusing mix of Python and C++.

BeefofAges fucked around with this message at 20:33 on Sep 9, 2009

Modern Pragmatist
Aug 20, 2008

BeefofAges posted:

However, it had some issues, like the fact that the GUI froze every time the program was actually doing anything. Does this just mean that I should have created new threads for things besides the GUI, or was I doing something else wrong?

Yes. You should spawn new threads to handle any processing that takes any decent amount of time. This separates your CPU-crushing calculations from hogging the resources required to render the GUI properly.

BeefofAges posted:

I want to learn how to use PyQt, because it actually has a utility for building GUIs instead of having to hand-code them. However, there don't seem to be any good PyQt tutorials out there, and the documentation I can find is a confusing mix of Python and C++.

I personally like to build a GUI by hand just because I feel like I have a lot more control over it's behavior, also it allows for better understanding of the GUI library that you are using.

I am preferential to wxPython because it has great cross-platform performance, uses native widgets, and is documented very well. It also has a demo available that demonstrates the usage of all widgets.

Modern Pragmatist fucked around with this message at 22:02 on Sep 9, 2009

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"

BeefofAges posted:

I want to learn how to use PyQt, because it actually has a utility for building GUIs instead of having to hand-code them. However, there don't seem to be any good PyQt tutorials out there, and the documentation I can find is a confusing mix of Python and C++.

Unfortunately, the tutorials are that way because PyQt is a confusing mix of Python and C++. For example, to connect a slot, you have to declare the slot's signature in C++ syntax as a string literal.

You might try PyGTK, using Glade through the gtk.glade package.

Lonely Wolf
Jan 20, 2003

Will hawk false idols for heaps and heaps of dough.
With any luck Nokia's PySide, a recreation of PyQT, will ameliorate those horrors, as QT itself is fantastic and it would be nice to use in Python without dumb poo poo like that, but PySide is new and it's going to be a while before they even start to make the interface pythonic. :(

BeefofAges
Jun 5, 2004

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

Thanks for the comments and suggestions, I'll check out those other toolkits. :)

Adbot
ADBOT LOVES YOU

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!
Hey guys, I've been working on parsing (tailing) a named pipe. Essentially it's the haproxy traffic logs for a pair of servers that I have configured syslog to output to a named pipe.

Obviously it's a fair bit of traffic (upto 3k hits/s per server), but I am finding that simply tailing the file, without any processing, is taking up 15% of a core. In contrast HAProxy takes 25% and syslogd takes 5% with the same load.

Is this normal and am I gonna have to go get my WD-40 and K&R? Or am I just stupid and doing things horribly wrong.

Here is my code (this is what I tested to get the above CPU percents, there's more code that barely raises the CPU which runs some regexes using coroutines but this bit of code consumes 10-15% CPU):
code:
from collections import deque
import io, sys

WATCHED_PIPE = '/var/log/haproxy.pipe'

if __name__ == '__main__':
    try:
        log_pool = deque([],10000)
        fd = io.open(WATCHED_PIPE)
        for line in fd:
            log_pool.append(line)
    except KeyboardInterrupt:
        sys.exit()
Deque appends are O(1) so that's not it. And I am using 2.6's io module because it's supposed to handle named pipes better.

deimos fucked around with this message at 22:02 on Sep 10, 2009

  • Locked thread