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
Allie
Jan 17, 2004

outlier posted:

* Pylons: The Pylons philosophy looks good (use anything you want with our framework), but I've seen argued that this actually means that Pylons provides you with drat-all. Nonetheless, it seemed to work okay and I've been thinking about this for a dedicated web-service (as opposed to a general CMS).

Pylons being a "collection" of separate components is a load of poo poo. It's all tightly coupled together and about the only place you really get any freedom is in OR mapping. It touts being WSGI-based but it abstracts away WSGI to the point of it being irrelevant. You see other projects writing "adapters" just for Pylons compatibility.

And not to mention it's poorly documented, and just poorly designed all around. It's like they went out of their way to make their framework as complicated as possible.

Adbot
ADBOT LOVES YOU

Allie
Jan 17, 2004

FrontLine posted:

I've thrown this bit in. Effective?

code:
while True:
	iteration = raw_input('How many images do you want to download? ')
	try:
		checkInt = str(int(iteration))
		break
	except:
		print "Invalid input"

Don't do "except:", that swallows all exceptions. And I'm not sure why you need to turn it back into a string. And the convention for naming non-class variables in Python is lowercase_with_underscores:
code:
while True:
    image_count = raw_input('Blah blah blah ')
    try:
        image_count = int(image_count)
        break
    except ValueError:
        print 'Whoa man, not cool.'

Allie
Jan 17, 2004

outlier posted:

Kind of. It's more of a convention than camelCaps but the whole style issue isn't as fixed as it is in (say) Java. l lowercase_with_underscores is what they use in the Python style sheet, but several communities have quite different styles (e.g. Zope). The major styles points would be to be consistent, use lowercase (no underscores) for module Names, CapsStyle for classes and *never* mix spaces and tabs for indentation.

It's as fixed as in you always follow PEP 8, so everyone else follows it, so style conventions can be consistent and meaningful. Things like Zope are essentially legacy applications (though in this case it's the APIs that are legacy) and obviously have their own rules. That doesn't mean you should make up your own rules too for no good reason.

Allie
Jan 17, 2004

SmirkingJack posted:

First I would enter the interactive editor and type "import os" followed by "dir(os)" to print a list of methods in the os module.

That's silly, it'll a list a whole bunch of useless poo poo he doesn't need or care about and won't tell him what any of it means. help(os) is much more helpful (that's why it's called help, after all).

If you want to print out a list of strings, use ''.join():
code:
>>> import os
>>> print '\n'.join(os.listdir('/usr/local'))
bin
info
lib
man
sbin
That joins each string in the list that os.listdir returns by a newline.

Allie
Jan 17, 2004

Just FYI, you don't need those line continuation characters as new lines and whitespace have no significance inside parentheses (or brackets, or braces).

Allie
Jan 17, 2004

Bozart posted:

Doesn't tell me what table means at all. It doesn't tell me where I can get a blank table, or what. It doesn't say what other functions I might end up using with this one, and it doesn't give a simple example. I played around with it and I get it now, but it doesn't exactly compare to something like matlab's

You might find the Python-by-Example site useful in cases like this. Unfortunately, it doesn't have an example for that particular function, but it has a lot of examples for other parts of the standard library.

In the future, you might want to just do help() on the module and search for references to the function in other parts of the documentation. If you search for "translate" in the help page for string, you'll see there's a maketrans function that builds translation tables.

Allie
Jan 17, 2004

No Safe Word posted:

I've never seen that, and I don't know why you'd do that. It's kind of a useless breaking-out of a utility function. Just keeping the for and yield in-line is more readable to me and it's only marginally longer.

And in his specific example it's completely 100% useless. iter() for lists does exactly what that traverse function does.

If you need iterators for a custom type, you can implement __iter__(), which iter() calls. The method should return an iterator for the object, and if you make the method a generator, calling it will return an instance of the generator, which works as well.

Allie
Jan 17, 2004

outlier posted:

That's why I called it a "toy example". There seemed little point in confusing the issue with the details of a custom class. Try and keep up boy.

If there was little point in confusing the issue, I guess it's a good thing you gave a silly and contrived example with obvious issues that detracted from your main point, and made it seem as if you didn't know about iter() or understand how it works. That condescending tone is great stuff though. :)

Allie
Jan 17, 2004

CrusaderSean posted:

I have a quick question about splitting string into a list. Is there a better way to do this?

code:
>>> aString = 'WORD----ANOTHERWORD-------SOMETHING'
>>> wordList = aString.split('-')
>>> wordList.sort()
['', '', '', '', '', '', '', '', '', 'ANOTHERWORD', 'SOMETHING', 'WORD']
>>> del wordList[0:wordList.count('')]
>>> wordList
['ANOTHERWORD', 'SOMETHING', 'WORD']

code:
>>> [w for w in 'WORD----ANOTHERWORD-------SOMETHING'.split('-') if w]
['WORD', 'ANOTHERWORD', 'SOMETHING']

Allie
Jan 17, 2004

Bonus posted:

Yeah it's good practice to maximize generator use and minimize lists. Of course it's cool to use lists for stuff you know will be small, but it doesn't cost you anything to use generators and generator expressions, but you will save on memory space when the data sets get big.

Generator expressions were only added in Python 2.4, so if you're developing for 2.3 or earlier you pretty much can't use them at all - they'll cause SyntaxErrors.

I guess if you're developing for such an old version of Python, you should probably already be aware of that, but Python 2.3 is unfortunately still pretty widely deployed.

Allie
Jan 17, 2004

king_kilr posted:

'h' + 'e' is perfectly valid, the problem is sum appears to do
code:
total = 0
for i in iterable
    total += i
return total
(the error it raises says that int can't be added to str), except for the fact that it is hyper optimized and written in C.

I guess you're right, but I meant in a mathematical sense it doesn't make sense to add two characters together*, I wasn't really thinking about the addition operator being used for concatenation. I guess if the function were more generic, you'd expect to get the same string back you passed in, but I think that error is more useful than it actually working, since you'd probably never want to call sum on a string.

* Yes, I know that characters can correspond to code points which you could add together if you wanted to.

Allie
Jan 17, 2004

JoeNotCharles posted:

Well, it's not a huge deal, but I have often wished to be able to write

That first example would be the equivalent of int(locals()['i + 1']), which doesn't make any sense to me. What exactly are you trying to point out?

I think you might be expecting a little too much out of string formatting operations. They're just for formatting, after all.

Allie
Jan 17, 2004

Lord Uffenham posted:

Unfortunately __doc__ is immutable. There seem to be a number of messy ways around this.

Have you tried using __new__?

code:
>>> class MetaFoo(type):
...     def __new__(cls, name, bases, dct):
...         dct['__doc__'] = 'foo'
...         return type.__new__(cls, name, bases, dct)
... 
>>> class Foo(object):
...     __metaclass__ = MetaFoo
... 
>>> Foo.__doc__
'foo'

Allie
Jan 17, 2004

Set cls.__init__.im_func.__doc__. You're trying to assign a doc string to the instance method, which is just a wrapper around the function.

Allie
Jan 17, 2004

It's not a pretty doc, but this page lists most of this kind of info: http://docs.python.org/ref/types.html. That same manual also has information on special methods.

Allie
Jan 17, 2004

Those are lists, not arrays (an array is a specialized data type in Python). You use tuples when you want to return or hold on to multiple values. They're like structs in C, but without named elements.

Lists on the other hand are mutable, unlike tuples. They're meant for being grown and shrunk, filtered, sorted, etc. When you append to a list, it doesn't create a new list. You can't append to tuples, only make new tuples.

Allie
Jan 17, 2004

A tuple is immutable, it isn't an issue there. And you want @classmethod:
code:
>>> class Foo(object):
...     @classmethod
...     def bar(cls, baz):
...         print baz
... 
>>> Foo.bar(5)
5
Also I'm not sure what you're referring to with unit testing there. Python has several testing libraries, like doctest, which tests code examples of interactive interpreter output in doc strings, and unittest, which is a huge Java-like piece of poo poo.

nose is nice too. With nose you can just write functions starting with test_ and use assert.

Allie
Jan 17, 2004

What are you trying to accomplish? Why can't you have an instance method that returns a new instance? You can't have a class method that accesses an instance if it doesn't have an instance to access. I think you're trying to make whatever you're doing more complicated than it needs to be.

Maybe you mean something like this?

code:
>>> class Foo(object):
...     pass
... 
>>> def create_or_modify_foo(someval, foo=None):
...     if foo is None:
...         foo = Foo()
...     foo.bar = someval
...     return foo
... 
>>> create_or_modify_foo(5).bar
5
>>> create_or_modify_foo(5, Foo()).bar
5
Also, if seq and if len(seq) are the same thing. You should generally always use the former.

Allie
Jan 17, 2004

has_key is apparently technically slower than in, but I personally don't use it for style reasons. It's easier to read the operator than the method call, at least in my opinion, and it matches up with membership tests for sequences.

It's also slated for removal in Python 3.0.

Allie
Jan 17, 2004

I still have no idea what you're trying to accomplish, but it looks like you're making things more complicated than they need to be.

And while we're talking about style, you should be using new-style classes (e.g. class TestClass(object):) and you should just assign the attribute directly, instead of using __dict__.

Allie
Jan 17, 2004

In Python simplicity is elegance. Nothing is more inelegant than code you have to spend extra time reading and comprehending in order to figure out what it's doing. Jumping back and forth and back and forth through different classes and different modules in order to get a general idea of how a library works is incredibly annoying, and I've had to do that with some Python libraries before.

It's even more depressing when you realize there was no reason for the code to do what it does the way it does, and that the entire thing could've been greatly simplified.

Allie
Jan 17, 2004

JoeNotCharles posted:

API simplicity != implementation simplicity

There are a lot of cases in Python where it isn't this simple. When I wrote that post I was specifically thinking of FormEncode, which does such absolutely mind-bogglingly ridiculous things with metaclasses that you can't even do simple things like instantiate a field without it being inside a form class. And in this case, this doesn't simplify the API at all. I've never ever seen anyone use a pattern like this in Python. I'd probably be scratching my head if I saw it, and honestly I'm still not sure what doing any of this would accomplish.

If you find yourself saying, "that's a cool hack," you should probably step back and think for a moment before you decide to soup up that hack even more.

Allie
Jan 17, 2004

Wulfeh posted:

The packets are being sent from a TF2 Steam server, they are log messages.

Are you talking about the remote logging client in the HL2 server? That isn't enabled by default, and port 27015 is for game traffic, not logging. You have to add your logging server (the recipient) with logaddress_add.

If that's what you're actually trying to do, you might find this useful: http://bitheap.org/hg/hl2utils/. It has a very basic remote logging listener.

Allie
Jan 17, 2004

Wulfeh posted:

Yea the server has my ip:port setup, and is sending my machine UDP packets, I can see them with Wireshark, and I can decode them and look at the log messages, the problem I am having is with Python picking up these packets as they are incoming

edit: I looked at that logging listener, and it's neat, i'll probably use it when I can figure out how to properly grab the packets

According to the docs, an empty host string is equivalent to localhost. You probably meant to listen on 0.0.0.0.

Allie
Jan 17, 2004

When you iterate over an object in a for loop, it calls iter(obj), which in turn calls obj.__iter__(). In your example, the object is itself the iterator, so it just returns itself. There are a lot of cases where classes have separate iterator classes though, which is why it's a method like that.

Then for each iteration in the for loop, it calls .next() on the object returned by iter() and assigns it i. When calling the method raises StopIteration, the loop exits.

Basically, it's an implicit protocol with for loops. It's all done behind the scenes.

Allie
Jan 17, 2004

JoeNotCharles posted:

- Like the guy said, don't use "dict" as a variable name - use something like "msgDict"

The official style guide for Python suggests using lowercase with underscores for variable names. Camel case is usually reserved for class names.

Allie
Jan 17, 2004

Well if you're going to lecture someone on style you should probably give them correct advice. :confused: There's no good reason to go against PEP 8, unless you're dealing with legacy APIs. Recommending a bad habit like that to a beginner isn't really a good idea.

Allie
Jan 17, 2004

such a nice boy posted:

Following the PEP is a great idea, but I code in so many languages and switch between them so often that I can't remember what the convention is in each. I wish we could just declare a "one true style" that applies to every language and stick to it.

The whole point of the PEP is that there should be "one true style" for Python code. It's really not that hard to remember the most obvious points in the guide, and if you're dealing with code from other projects, chances are you'll see the same styles pop up again and again as well.

Sticking to that style guide makes it easier for others to read and edit your code. I think spending some time going over the guide and making it habit when you write Python code is definitely worth the effort.

Allie
Jan 17, 2004

Bonus posted:

Yeah. Also watch that you don't fall into an infinite loop within the __getattr__ or __setattr__ methods. Manipulate the __dict__ directly.

I can't imagine getting an infinite loop with __getattr__ - it's only called when you try to access the value of an undefined attribute.

For setting an attribute in __setattr__ I would use super().__setattr__(). I think it'd even fix the issue with __getattribute__ being called when accessing __dict__, since __getattribute__ is called for all attribute access.

Allie
Jan 17, 2004

code:
>>> k = range(1, 8)
>>> k
[1, 2, 3, 4, 5, 6, 7]
>>> for i, n in enumerate(k):
...     k[i] = 0
... 
>>> k
[0, 0, 0, 0, 0, 0, 0]
When you assign to i it just changes the variable to point to a different object. You have to assign to the list directly, and enumerate() will conveniently give you a counter to do that.

Allie
Jan 17, 2004

I think Python's standard library surprises me the most when it comes to discovering new things. PyMOTW is great for learning about parts of the library you've never even noticed.

I also like using my browser's search on the standard library's index. Just search for whatever you're dealing with, you'll probably find something relevant.

Allie
Jan 17, 2004

HatfulOfHollow posted:

Recommending Django for writing simple cgi scripts is a bit overkill don't you think? I've used a variety of methods for writing web applications and I like mod_python the most. web.py and other cgi modules feel clunky to me. I guess it's personal preference, but mod_python makes writing cgi in python feel more like python.

I would personally never ever ever use mod_python if I could avoid it. Its poorly documented code caching (which can be inconsistent across the processes it loads) is probably the most frustrating thing I've ever had to deal with when testing code. And to make matters worse you can't really test applications developed for mod_python outside of mod_python. It's a loving framework too.

I absolutely love mod_wsgi, and for quick one-off development I just write WSGI apps directly and use wsgiref.simple_server. :)

Allie
Jan 17, 2004

ATLbeer posted:

Didn't make a difference

You're using the class level variable midmenu. When you access an attribute on an instance and Python doesn't find the attribute on the instance, it looks for it in its class too before it raises AttributeError. What you need to do is instantiate all of those variables inside __init__ - they don't belong inside the class.

Allie
Jan 17, 2004

Python's lambdas are perfectly capable. They're meant for quick one statement functions that you pass to other functions. If you need more than one statement, you just make a function and pass the function. :)

I honestly don't understand why there's been so much whining over them, and I'm not really sure why Guido even considered removing them in the first place.

Allie
Jan 17, 2004

bitprophet posted:

In his defense, doing from math import sqrt is perfectly Pythonic; the "lulz PHP's approach is awsum!" attitude would be closer to from math import * :)

import * isn't inherently bad, but you generally shouldn't use it for modules that aren't designed for it (i.e. they don't have __all__ set). It can also confuse some lint tools like PyLint and Pyflakes and make it harder to statically find undefined names.

Allie
Jan 17, 2004

If you have to resort to that, you might want to do eval(x, {'__builtins__': ''}). That gets a little more complicated if you have objects that don't have literal representations, of course.

Allie
Jan 17, 2004

Default arguments are initialized only once. Every time you call Square.__init__() it adds to the list in the _conflicts parameter. Set its default value to None and instantiate it inside the function:

code:
def foo(stuff=None):
    if stuff is None:
        stuff = []
You should generally only use immutable types for default values.

Allie
Jan 17, 2004

The two print forms aren't compatible with each other. If you want to target both 2.x and 3.x, you should write code for 2.x and use the upcoming 2to3 script to translate it to 3.x code.

The beta schedule for 2.6 and 3.0 is nearing to a close. As far as I know, the releases are still on track for October.

Allie
Jan 17, 2004

The only reason it works is because the parentheses have no meaning your example. They make tuples when you insert a comma, and you probably don't mean to print a tuple if you're using the print statement with multiple arguments. The print statement also has special syntax for printing to specific file objects, using the >> operator. This is gone in 3.0.

There are more changes than just that. Look at the what's new page for Python 3.0. Try running the 3.0 print examples in your 2.5 prompt - most won't work. When writing code for 2.x you should write 2.x code. If you're trying to target both platforms, the 2to3 script will take care of this, making the whole effort pointless.

Adbot
ADBOT LOVES YOU

Allie
Jan 17, 2004

Chin Strap posted:

Wait, could someone explain this? Are 2.6 and 3.0 set for the same release times? I'm confused :(

Yes. They're two branches of Python, each with their own ongoing development. They're being released in tandem because 2.6 has a lot of features backported from 3.0. It's sort of a stepping stone to 3.0, making it easier to write code that can be automatically translated for 3.0 with 2to3.

I wouldn't worry about either of them right now for day-to-day development. Wait until you have a reason to upgrade, and be sure whatever tools or libraries you use are available for the version you want to move to.

If you develop libraries or software that other people use, then you might want to pay attention and see if porting code is a good idea. :)

Allie fucked around with this message at 03:12 on Aug 21, 2008

  • Locked thread