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
Johnny Cache Hit
Oct 17, 2011

oiseaux morts 1994 posted:

Ah thanks, although that's more of an aside. I'm really just interested to see if my implementation of an Interface is useful/correct; it's all in the code.

You're duck typing like a champ :downsrim:

One note: avoid except Exception as it will screw up badly in non-trivial situations. Catch the exceptions that you will meaningfully handle.

Adbot
ADBOT LOVES YOU

tripwire
Nov 19, 2004

        ghost flow
Java/C++ style interfaces don't really translate cleanly to python. A lot of the benefits of coding to interfaces in java is that the compiler/your IDE will give you all sorts of feedback and autocompletion, made possible through the use of the static type system.

I think python 3 supports voluntary type annotations in function definitions, but as far as I know their semantics are not standardized. It's up to each coder to decide how they interpret whatever value they find in any annotations; and of course the use of them at all is and will remain voluntary.

But that doesn't really change how people actually get OO done in python. At the end of the day, its still up each coder to assume responsibility for ensuring that their functions are wired up correctly. This is made simpler through following some best practices, like throwing TypeError or ValueError on invalid function input, or dividing up functions to be as simple and explicable as possible.

StormyDragon
Jun 3, 2011

TasteMyHouse posted:

Awesome. This was exactly what I was looking for, thanks!

import random
random.getrandbits(32)

But yea, struct.unpack to convert raw bytes easily to python types.

StormyDragon fucked around with this message at 06:58 on Dec 6, 2011

duck monster
Dec 15, 2004

oiseaux morts 1994 posted:

I'm starting learning design patterns, and the first thing I stumble across is interfaces. Since I was learning from a Java tutorial, I kind of had to scratch my head and work out how to implement it in Python.

Would y'all be able to check my code and give any pointers / advice? (Unfortunately the output feature seems to be Python 2.x and I can't remember how to format strings in 2.x)

Hmm. I'm always nervous of any code with multiple inheretance. I mean python can kinda do it, but im not completely convinced its always a good idea.

tef
May 30, 2004

-> some l-system crap ->

oiseaux morts 1994 posted:

I'm starting learning design patterns, and the first thing I stumble across is interfaces. Since I was learning from a Java tutorial, I kind of had to scratch my head and work out how to implement it in Python.

design patterns introduce a vocabulary for systematic ways of expressing idioms in languages that don't support those idioms well.

python is not a good language to 'learn design patterns' because much of it is baked into the language - you don't need factories, builders, etc. for example:

factory in python - a function
strategy pattern - a function
prototype - just change the instance's methods at runtime.
singleton - would a global variable by any other name sound so sweet?
iterator - well, an iterator/generator.
builder - named arguments to functions

learning programming through design patterns is akin to learning object orientation from a homebrew C object system. you're focusing on the implementation details of idioms as opposed the idioms themselves.

design patterns are not tools for thinking about programming but smells in a language. it's the worst form of code reuse - boilerplate to cult into your code.

tef
May 30, 2004

-> some l-system crap ->

duck monster posted:

Hmm. I'm always nervous of any code with multiple inheretance. I mean python can kinda do it, but im not completely convinced its always a good idea.

I find when they're used as mixins it is reasonable. I think I am doing something wrong whenever I call super() though.




I really want traits

tef
May 30, 2004

-> some l-system crap ->
I would also like to mention that python suffers from being amenable to java programs to write ersatz java within. If you are a java programmer new to python I offer the following advice: Stop writing so many goddam classes. Stop writing so many goddam methods. You will thank me later :-)

To wit - a java programmer fresh from implementing a deck of cards

http://docs.oracle.com/javase/tutorial/java/javaOO/examples/Card.java
http://docs.oracle.com/javase/tutorial/java/javaOO/examples/Deck.java

Might end writing something similar in python
code:
class Deck(object):
    def __init__(self):
        ...
    def get_card(self, n):
        ...

class Card(object):
    def __init__(self):
Meanwhile if you ask someone who learned python before java or oo-style code:

code:
import collections

Card = collections.namedtuple("Card", "suit rank")
SUITS = ("Clubs", "Diamonds", "Hearts", "Spades",)

def make_deck():
    deck = []
    for suit in SUITS:
        for rank in range(1,14):
            deck.append(Card(suit, rank))
 
named_cards = {
   1 : 'Ace',
   11: 'Jack',
   12: 'Queen',
   13: 'King'
}
def card_name(c):
    suit, rank = c
    return "%s of %s"%(named_cards.get(rank, str(rank)), suit)

deck = make_deck()

import random

random.shuffle(deck)

card_a = deck.pop()
card_b = deck.pop()
I'm not advocating one over the other but if you want to learn python please understand there is more to it than just being a java without braces.

(note: I haven't tested the above code)

tef fucked around with this message at 13:28 on Dec 6, 2011

o.m. 94
Nov 23, 2009

Thanks, a lot to think about. Immediately, my research into design patterns brings up repeated warnings about mindlessly copying patterns and cargo cult programming so I am aware of this; but my desire to understand patterns is motivated by a genuine desire to structure my programs.

I'm at the point now where the Python syntax is fairly familiar to me. I can write cute algorithms, functions and scripts with relative ease, and try and make them Pythonic. But now I'm starting to write larger programs, mostly text-based games, my code becomes complicated. A simple text-based GUI gets entangled with game logic; suddenly I find myself passing objects through a line of different functions and classes, and I can't work out how to effectively communicate between the different parts of a program. It all becomes a bit, ugly mess that is hard to read and debug.

So then I hears about a solution to the problem in the form of MVC. "What's MVC?" I ask, and when I find out it's a way to coordinate your data/logic, GUI and user input I cannot help but think "Great! That sounds like just the thing I should learn about, maybe it would show me the way from writing babby scripts to actually strucutring my programs."

So that's kind of why I'm interested in design patterns. I don't really want to read any more tutorials on the various component parts of the language, I want to learn how to build programs.

o.m. 94 fucked around with this message at 14:54 on Dec 6, 2011

tef
May 30, 2004

-> some l-system crap ->

oiseaux morts 1994 posted:

Thanks, a lot to think about. Immediately, my research into design patterns brings up repeated warnings about mindlessly copying patterns and cargo cult programming so I am aware of this; but my desire to understand patterns is motivated by a genuine desire to structure my programs.

Design patterns are a vocabulary of boilerplate. In verbose and chunky languages, having names for the oft-repeated boilerplate sections is useful. Learning the intent of a design pattern is harder than learning the implementation - the latter is what leads to unnecessary boilerplate and cruft.

quote:

I'm at the point now where the Python syntax is fairly familiar to me. I can write cute algorithms, functions and scripts with relative ease, and try and make them Pythonic.

The easiest measure of pythonic is a code review - how easy is it to explain to another programmer. The zen of python is a nice read but hard to apply.

quote:

But now I'm starting to write larger programs, mostly text-based games, my code becomes complicated. A simple text-based GUI gets entangled with game logic; suddenly I find myself passing objects through a line of different functions and classes, and I can't work out how to effectively communicate between the different parts of a program. It all becomes a bit, ugly mess that is hard to read and debug.

This is because you're designing your program as you write it. The problem with learning to program is that you are frequently exploring the problem as you are coding.

You will often find it easier to rewrite the code from scratch - as the mistakes you make early on lead to heavy maintenance costs later.


quote:

So that's kind of why I'm interested in design patterns. I don't really want to read any more tutorials on the various component parts of the language, I want to learn how to build programs.

if you want to learn how to design programs you should study programs to see how they were designed. design patterns are a terrible substitute for actual design.

mvc, patterns and the ilk are no more a magic wand than if statements, for/while loops and functions. they can make somethings easier to express but it won't stop you from writing a rats nest of code.

if you're looking to improve your skill as a programmer I would heartily recommend "The Practice of Programming" by Kernighan and Pike.

tef
May 30, 2004

-> some l-system crap ->
I guess I am saying you will learn to make good programs by making lots of poo poo ones and learning from your mistakes. It is hard to short cut this. You just have to write a whole load of bad code before you start writing good code. Don't try and write your magnum opus yet. Hack up fun poo poo and move on.

Once you've solved enough problems it is fairly easy to replicate things, with hopefully newer and interesting mistakes over the old and tired ones.

I'm still a terrible developer. I rush, I cut corners. I trade off things in the hope they won't bite in future. I write code that is too clever for its own good. My code is still far better than it used to be. Although looking at things I rushed out at the beginning of the year there is still an overwhelming amount to improve. I still gently caress up many years on and so will you. Coding inevitably involves making mistakes and learning from them.

As for your actual problem of structuring code - some rules of thumb I often go by:

Write one to throw it away
Software should be written top down except the first time
Debugging is twice as hard as programming. If you write to the best of your ability you are no longer qualified to debug your code.
Write simple dumb code that gets the job done and revisit it when it becomes a problem.
A program is something to explain something to a human, as well as a machine. Don't patronise one on the behalf of the other.
Tests, like types are useful contracts - but they don't have an intrinsic value. Both carry a maintenance overhead.


Really: Don't be smart, don't be afraid to explore a problem, and don't be afraid to get it wrong. That is how you will learn to program. Read more programs than you write and you will be able to learn from other peoples mistakes, too.

tef fucked around with this message at 15:35 on Dec 6, 2011

o.m. 94
Nov 23, 2009

tef posted:

I guess I am saying you will learn to make good programs by making lots of poo poo ones and learning from your mistakes. It is hard to short cut this. You just have to write a whole load of bad code before you start writing good code. Don't try and write your magnum opus yet. Hack up fun poo poo and move on.

This is definitely what I've noticed is happening. Thanks, all your advice is greatly appreciated. There is an economy of this kind of information online, and it seems to be the most important.

tripwire
Nov 19, 2004

        ghost flow
I agree with tef, both on the assessment of design patterns, and on the advice. I have a similar problem going the other way; I'm having to invest more and more time in learning these twisted obtuse implementations of design patterns in various java frameworks, and am struggling at how much more work is required to accomplish what would be trivial and immediately intuitive when I'm thinking in python.

Design patterns are really just euphemisms for cumbersome code constructs whose sole purpose is to paper over some deficiency in the language.

Dependency injection/inversion of control, the "strategy" and "command" patterns and others are so trivial as to not even need (pretentious) names in python. Things like the dynamic type system, first class functions and the richness of the standard library make such burdens unnecessary.

Stabby McDamage
Dec 11, 2005

Doctor Rope
Can anyone recommend a neat-Python-thing-a-day blog? I picked up Python a year or so ago, and I've been following this thread ever since, but I've gotten to the point where I'm familiar with most stuff posted here. I'd like to add something Pythonic to my idle morning reading list.

tef
May 30, 2004

-> some l-system crap ->
raymondh on twitter does some interesting bits and pieces

notMordecai
Mar 4, 2007

Gay Boy Suicide Pact?
Sucking Dick For Satan??

Not a question for me but a friend has seen me on this board and wants to know if you helpful gentleman can help him. I have no idea what he is doing and if you'd rather not answer his question I can easily tell him to piss off.

He states this is his problem: "It freaks out at 13 (print "</div>"). If delete that line it works fine but when I add it just stops working. I'm just trying to print outside of the for loop."

code:
printDocHeading("exmaple1.css", "Assignment 9","")
cgitb.enable()
form = cgi.FieldStorage()
if(not(form.has_key('name'))):
    result = cursor.fetchall()
    print "<div class='content'><table id='contacts'><tr>"
for data in result:
        print "<td>Name: ", data[0], "</td>\n"
        print "<td>Phone: ", data[1],  "</td>\n"
        print "<td>Email: ", data[2],  "</td>\n"
        print "<td>Edit/Delete</td></tr>\n"
 
print "</div>"
 
else:
    print "<div class='content'><h3> Add Contact</h3>\n"
    print "<form method='post' action='./asg9.cgi'>\n"
    print "<p>Enter your name: <input type='text' name='name' /></p>\n"
    print "<p>Enter your phone number: <input type='text' name='phone' /></p>\n"
    print "<p>Address: <input type='text' name='address' /></p>\n"
    print "<p>Email: <input type='text' name='email' /></p>\n"
    print "<p><input type='submit' value='Submit' /></p></div>\n"
print "<div class='footer'><a href='./asg9.cgi'>Refresh page</a></div>\n"
print "</body></html>"

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I have no idea what he's doing either. I feel he forgot to properly indent the for loop and the print statement, or he doesn't know what a for...else loop does.

Comrade Gritty
Sep 19, 2011

This Machine Kills Fascists

notMordecai posted:

Not a question for me but a friend has seen me on this board and wants to know if you helpful gentleman can help him. I have no idea what he is doing and if you'd rather not answer his question I can easily tell him to piss off.

He states this is his problem: "It freaks out at 13 (print "</div>"). If delete that line it works fine but when I add it just stops working. I'm just trying to print outside of the for loop."

code:
printDocHeading("exmaple1.css", "Assignment 9","")
cgitb.enable()
form = cgi.FieldStorage()
if(not(form.has_key('name'))):
    result = cursor.fetchall()
    print "<div class='content'><table id='contacts'><tr>"
for data in result:
        print "<td>Name: ", data[0], "</td>\n"
        print "<td>Phone: ", data[1],  "</td>\n"
        print "<td>Email: ", data[2],  "</td>\n"
        print "<td>Edit/Delete</td></tr>\n"
 
print "</div>"
 
else:
    print "<div class='content'><h3> Add Contact</h3>\n"
    print "<form method='post' action='./asg9.cgi'>\n"
    print "<p>Enter your name: <input type='text' name='name' /></p>\n"
    print "<p>Enter your phone number: <input type='text' name='phone' /></p>\n"
    print "<p>Address: <input type='text' name='address' /></p>\n"
    print "<p>Email: <input type='text' name='email' /></p>\n"
    print "<p><input type='submit' value='Submit' /></p></div>\n"
print "<div class='footer'><a href='./asg9.cgi'>Refresh page</a></div>\n"
print "</body></html>"

the else doesn't have a parent.

StormyDragon
Jun 3, 2011

notMordecai posted:

Not a question for me but a friend has seen me on this board and wants to know if you helpful gentleman can help him. I have no idea what he is doing and if you'd rather not answer his question I can easily tell him to piss off.

He states this is his problem: "It freaks out at 13 (print "</div>"). If delete that line it works fine but when I add it just stops working. I'm just trying to print outside of the for loop."

In Python for loops can have an else clause, this block is run when the loop completed successfully without a break, which is why the program does not complain when it is run without the print, this is probably still in error. The real intention is most likely to indent the for loop and the print line such that they are properly inside the if block.

Being homework though, this kind of syntax should really have been taught when for loops were introduced, and the friend should be aware of this.

StormyDragon fucked around with this message at 04:26 on Dec 11, 2011

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"

notMordecai posted:

Not a question for me but a friend has seen me on this board and wants to know if you helpful gentleman can help him. I have no idea what he is doing and if you'd rather not answer his question I can easily tell him to piss off.

He states this is his problem: "It freaks out at 13 (print "</div>"). If delete that line it works fine but when I add it just stops working. I'm just trying to print outside of the for loop."
Your friend screwed up his indentation.

His code is:
code:
if:
for:
else:
It should be:
code:
if:
    for:
else:
When there's nothing in between the 'for' and 'else', it'll still compile and run due to an obscure quirk of Python's loop syntax, but it still won't do what he wants.

FoiledAgain
May 6, 2007

StormyDragon posted:

In Python for loops can have an else clause, this block is run when the loop completed successfully without a break

Interesting. I didn't know this. Under what circumstances would for...else be useful? Isn't the most common situation that you do complete the entire loop without breaking? I'd think I'd want to catch the breaks more often than the "successful" loops.

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"

FoiledAgain posted:

Interesting. I didn't know this. Under what circumstances would for...else be useful? Isn't the most common situation that you do complete the entire loop without breaking? I'd think I'd want to catch the breaks more often than the "successful" loops.
code:
for item in items:
    if valid(item):
        break
else:
    raise NoValidItemsError()

print item
IMO it's bad style, but this is the original use case

StormyDragon
Jun 3, 2011

FoiledAgain posted:

Interesting. I didn't know this. Under what circumstances would for...else be useful? Isn't the most common situation that you do complete the entire loop without breaking? I'd think I'd want to catch the breaks more often than the "successful" loops.

As Janin suggests, the use case is testing a list for valid items, and if none are valid, you do something else.
Even though you could use if not all(valid(item) for item in list): to accomplish the same thing.

Whether it is bad style, i can't say yet, the syntax looks clean, but it is correct that it only applies to a few specific cases, the use of the else keyword might not have been the wisest decision though.

(while..else and try..except..else..finally is possible too.)

tef
May 30, 2004

-> some l-system crap ->

Janin posted:

IMO it's bad style, but this is the original use case

I don't like the for/else statement either. I find it is backwards from what I would expect - and my brain refuses to deal with it.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
for...else has always seemed overly clever and unpythonic to me.

Lurchington
Jan 2, 2003

Forums Dragoon
edit: I guess according to: http://docs.python.org/reference/compound_stmts.html#the-for-statement
I was wrong.

I assumed it was similar to:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for-empty

Lurchington fucked around with this message at 22:27 on Dec 12, 2011

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Except that's not what the for...else loop does. It's what it should do, though.

leterip
Aug 25, 2004

Suspicious Dish posted:

Except that's not what the for...else loop does. It's what it should do, though.
code:
>>> for x in []:
...     print "foo"
... else:
...     print "empty"
... 
empty
edit: Oops. If there is data it still does the else! So you're right.

duck monster
Dec 15, 2004

tef posted:

raymondh on twitter does some interesting bits and pieces

Every time I hear the name "raymond" in association with "python" I keep thinking some hosed up american gun nuts going to jump out the bushes and force me to use some wierd python based linux configurator at gunpoint whilst shouting IM AN ANTHROPOLOGIST GOD drat IT

e: (granted ESR is actually "eric".... still, trauma or something I dunno)

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"

leterip posted:

edit: Oops. If there is data it still does the else! So you're right.
and this is why overloading 'else' to mean 'if-loop-finished' is a bad idea

Grandmaster.flv
Jun 24, 2011
If I am using os.system to call a script under a directory with "/b" in the path how would I refer to it without having the /b evaluate itself?

For instance:

os.system("d:\program\bin\file.exe") evaluates to $d:\programin\file.exe

Met48
Mar 15, 2009
There's two options for that. The simplest is to use a raw string:

os.system(r"d:\program\bin\file.exe")

As long as the string doesn't end with a backslash, just adding an r before the string will disable escape sequences entirely.

The other main option is to use forward slashes, since Windows is fine with either.

Grandmaster.flv
Jun 24, 2011

Metroid48 posted:

There's two options for that. The simplest is to use a raw string:

os.system(r"d:\program\bin\file.exe")

As long as the string doesn't end with a backslash, just adding an r before the string will disable escape sequences entirely.

The other main option is to use forward slashes, since Windows is fine with either.

Thank you.

brosmike
Jun 26, 2009

Metroid48 posted:

The other main option is to use forward slashes, since Windows is fine with either.

Don't do this if you can avoid it - some windows programs (cmd.exe among them) will try to deal with forward slashes sometimes, but the behavior is inconsistent between programs, difficult to predict, and subject to change between versions.

Johnny Cache Hit
Oct 17, 2011

brosmike posted:

Don't do this if you can avoid it - some windows programs (cmd.exe among them) will try to deal with forward slashes sometimes, but the behavior is inconsistent between programs, difficult to predict, and subject to change between versions.

Why would forward slashes in the path specification even be seen by individual programs? I didn't think those even went into argv, just the binary.

Of course if you're trying to give a path to another program this caveat may well come up, but if you're just calling a program...

Thermopyle
Jul 1, 2003

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

I've never done any python GUI programming. What's the "best" framework for a Windows 7 only utility? Looking for ease-of-use and native widgets/best looking interfaces.

Suspicious Dish
Sep 24, 2011

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

Metroid48 posted:

There's two options for that. The simplest is to use a raw string:

os.system(r"d:\program\bin\file.exe")

As long as the string doesn't end with a backslash, just adding an r before the string will disable escape sequences entirely.

The other main option is to use forward slashes, since Windows is fine with either.

Please don't use os.system. It's deprecated for a reason. The replacement is the new subprocess module:

code:
import subprocess

subprocess.Popen([r'd:\program\bin\file.exe'])

Thermopyle posted:

I've never done any python GUI programming. What's the "best" framework for a Windows 7 only utility? Looking for ease-of-use and native widgets/best looking interfaces.

One of the native APIs on Windows is Win32, which is supported in Python by the Python for Windows Extensions. I have no experience with how awesome or cool it is.

Other widget toolkits include GTK+ (use PyGObject for bindings, not the outdated PyGTK+) (which isn't out for Windows yet, but will be pretty soon. It looks fairly native) and [url="http:///www.pyside.org"]Qt (use PySide for bindings, not PyQt)[/url]. I'm most familiar with GTK+, so I can help with problems involving that.

Thermopyle
Jul 1, 2003

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

Suspicious Dish posted:


One of the native APIs on Windows is Win32, which is supported in Python by the Python for Windows Extensions. I have no experience with how awesome or cool it is.

Other widget toolkits include GTK+ (use PyGObject for bindings, not the outdated PyGTK+) (which isn't out for Windows yet, but will be pretty soon. It looks fairly native) and [url="http:///www.pyside.org"]Qt (use PySide for bindings, not PyQt)[/url]. I'm most familiar with GTK+, so I can help with problems involving that.

Am I wrong in thinking that this is PyGObject for Windows?

Suspicious Dish
Sep 24, 2011

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

Thermopyle posted:

Am I wrong in thinking that this is PyGObject for Windows?

It's 2.28, and thus doesn't have introspection.

Modern Pragmatist
Aug 20, 2008
So I want to subclass list, but I want to ensure that the elements of the list are tuples. What is the best way to go about doing this? My first idea would be to overload all modification methods, but that seems pretty inelegant. Any ideas?

Adbot
ADBOT LOVES YOU

posting smiling
Jun 22, 2008

Modern Pragmatist posted:

So I want to subclass list, but I want to ensure that the elements of the list are tuples. What is the best way to go about doing this? My first idea would be to overload all modification methods, but that seems pretty inelegant. Any ideas?

Why is it so important for you to ensure that it only holds tuples? It's kind of counter to Python's type system. If you need to do it, there's not really any way to get around overloading the relevant methods. There shouldn't be so many as to be impractical.

  • Locked thread