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
deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

clayburn posted:

What would be the most efficient way to print through a list of tuples? I'm new to python, coming from java and love how simple some things are to do, so I'm thinking there is an elegant way to do this. In my mind it would require something like:
code:
for i in list:
   print list[i][0] + '\t' + list[i][1]
This doesn't seem that bad, but I thought I remembered reading something that said to never iterate through a list to print it's elements like that and to use string.join instead.

print '\n'.join('\t'.join((str(i[0]),str(i[1]))) for i in x) is the only way I can think of.

Adbot
ADBOT LOVES YOU

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

clayburn posted:

code:
print '\n'.join('%s\t%s' % el[:2] for el in list)

This works on 2.4+, and the el[:2] can be changed to just el if it's all two-element tuples.

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

Habnabit posted:

This works on 2.4+, and the el[:2] can be changed to just el if it's all two-element tuples.

That's better than mine. It still has the issue of loading the whole string into memory though.

Dr-NiKoN
Jan 17, 2004
foo
You guys are still iterating the list :)

The problem is as such:
code:
for i in list:
  string = string + i

print string
This is for some reason quadratic time in Python. I have no idea why. The reason
is not because of the simple list iteration(which is O(n)), it's because of the + operator on the string.
Again, I have no idea why, because it doesn't make sense. It should be O(n) because the + operator should
be constant time.

code:
print ''.join(list)
Is a string-operation, might even be less than O(n).

But, it only applies(and works) on simple lists of strings.

Maybe someone could shed some more light on this, I'm interested in hearing why.

Dr-NiKoN fucked around with this message at 00:37 on Jun 13, 2008

Scaevolus
Apr 16, 2007

Dr-NiKoN posted:

The problem is as such:
code:
for i in list:
  string = string + i

print string
This is for some reason quadratic time in Python. I have no idea why. The reason
is not because of the simple list iteration(which is O(n)), it's because of the + operator on the string.
Again, I have no idea why, because it doesn't make sense. It should be O(n) because the + operator should
be constant time.
Python's strings are immutable (and, as a result, hashable). String concatenation can't run in constant time, because it must allocate storage for a new string, and then copy the other two. You can't concatenate strings by just doing a few pointer reassignments.

Dr-NiKoN posted:

code:
print ''.join(list)
Is a string-operation, might even be less than O(n).

But, it only applies(and works) on simple lists of strings.
Wrong. It works on any sequence (anything that's iterable) of strings. Thus, Habnabit's code is about as efficient as possible. Also, it's O(n).

Scaevolus fucked around with this message at 01:52 on Jun 13, 2008

tef
May 30, 2004

-> some l-system crap ->

Scaevolus posted:

You can't concatenate strings by just doing a few pointer reassignments.

When you are concatenating strings a lot, Ropes make a good alternative. It seems to be in pypy too.

Although it makes concatenating cheap, I am curious as to how the hashing could be done equally fast.

Zombywuf
Mar 29, 2008

tef posted:

When you are concatenating strings a lot, Ropes make a good alternative. It seems to be in pypy too.

Although it makes concatenating cheap, I am curious as to how the hashing could be done equally fast.

Assuming the hashing is linear, you can take the hash from the first string and run the algorithm from there over the second string and store it with the rope handle.

tef
May 30, 2004

-> some l-system crap ->
I was hoping you could derive some hash such that

hash(concat(a,b)) = f(hash(a),hash(b))

for some magical f.

Zombywuf
Mar 29, 2008

A hash with that property would be likely to have all kinds of other unsightly properties like hashing to the same value when characters are transposed.

Dr-NiKoN
Jan 17, 2004
foo

Scaevolus posted:

Python's strings are immutable (and, as a result, hashable). String concatenation can't run in constant time, because it must allocate storage for a new string, and then copy the other two. You can't concatenate strings by just doing a few pointer reassignments.
Hm, shouldn't it still be constant time? I don't understand how they can talk about this in order of magnitudes.

Zombywuf
Mar 29, 2008

Dr-NiKoN posted:

Hm, shouldn't it still be constant time? I don't understand how they can talk about this in order of magnitudes.

Copying a string takes an amount of time proportional to it's length. In essence (it's actually a lot more complex underneath), the string is copied one char at a time.

heeen
May 14, 2005

CAT NEVER STOPS
Here's a google app engine question for y'all:
I'd like to use the key name as a unique identifier as described in the datastore api:

quote:

Every entity has an identifier. An application can assign its own identifier for use in the key by giving the instance constructor a key_name argument (a str value):

s = Story(key_name="xzy123")

A key_name is stored as a Unicode string (with str values converted as ASCII text). A key_name must not start with a number, and must not be of the form __*__. If your application uses user-submitted data as datastore entity key names (such as an email address), the application should sanitize the value first, such as by prefixing it with a known string, to meet these requirements.

If a key_name is not specified, the entity is assigned a numeric ID when it is first stored in the datastore.
but when I create an object like this:
code:
vote = Vote(key_name = "p"+str(self.request.get('postid'))+"a"+str(self.request.get('author')))
this
code:
str(vote.put().id())+ " "+ str(vote.key().id())
returns
code:
None None
what gives?

heeen
May 14, 2005

CAT NEVER STOPS
anyone?

Anode
Dec 24, 2005

Nail me to my car and I'll tell you who you are
You have to store an entity to the datastore before it gets an ID, if I understand your question correctly.

EDIT: Just noticed you do store it, but

App Engine Key Class Docs posted:

id()

Returns the numeric ID of the data entity, as an integer, or None if the entity does not have a numeric ID.

Anode fucked around with this message at 20:22 on Jun 14, 2008

heeen
May 14, 2005

CAT NEVER STOPS

Anode posted:

You have to store an entity to the datastore before it gets an ID, if I understand your question correctly.

EDIT: Just noticed you do store it, but

So how do I get the string ID described in the API?

lilbean
Oct 2, 2003

Is there any decent page or book outlining how to organize a growing Python project? Right now I've got a src, docs, data and build directory off of the root of my project. In src I've got the base .py files, with a sub-folders named things like gui and so forth. In Java, I'm used to things in the same package not having to be imported. With this project there's a GUI framework that's getting fairly large so at the top of one type of window there'll be this import:
code:
from GUI.TabbedWindow import TabbedWindow
Now I don't know if that's specifically bad, but is explicitly importing everything needed the best way to do it? I can always "import *" but that really doesn't buy me much since one .py file contains one class.

So yeah, nothing is inherently broken with the project as it stands, it's just that I'm not sure of the sort of "standard layout" of Python programs.

inorpo
Oct 27, 2003

heeen posted:

So how do I get the string ID described in the API?

This is what I'm using. It may not be the right or best way but it is what I came up with while changing the normal django polls app to run on App Engine.

models.py posted:

def get_absolute_url(self):
return '/polls/poll/%s/' % self.key()

That ends up returning
code:
/polls/poll/agptcGd0cmFja2VycgoLEgRQb2xsGAEM/

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

lilbean posted:

code:
from GUI.TabbedWindow import TabbedWindow
Now I don't know if that's specifically bad, but is explicitly importing everything needed the best way to do it? I can always "import *" but that really doesn't buy me much since one .py file contains one class.

Explicitly importing what you need is indeed the Python way, but ideally you'd want your class to be named "GUI.TabbedWindow", not "GUI.TabbedWindow.TabbedWindow", so you can just "import GUI" or "from GUI import TabbedWindow".

Consider putting something like the following in GUI/__init__.py:

code:
from TabbedWindow import TabbedWindow
That way the class TabbedWindow from the TabbedWindow submodule (GUI/TabbedWindow.py) is put in the GUI namespace.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I've really got to stop using the "back" button and then switching to another window.

Flea110
Apr 3, 2006
I'm trying to learn how classes work, and while I think i understand a lot of the ideas, this doesn't make sense to me.

code:
>>> class Squares:
... 	def __init__(self, start, stop):
... 		self.value = start - 1
... 		self.stop = stop
... 	def __iter__(self):
... 		return self
... 	def next(self):
... 		if self.value == self.stop:
... 			raise StopIteration
... 		self.value += 1
... 		return self.value ** 2


>>> for i in Squares(1, 5):
... 	print i
... 	
1
4
9
16
25
I understand how __init__ is called, but __iter__ seems to be pretty useless. I don't see how next() is called.

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.

bitprophet
Jul 22, 2004
Taco Defender
I don't work with handmade iterators much, but I believe what's happening is this:

1. You execute the expression for i in <a Squares object>:.
2. for loops perform iteration on the object following the in keyword.
3. An object can be iterated over if it defines the __iter__() method (__foo__() methods are generally used to implement language behaviors; for example you can have your class implement __lt__() (less than) in order for them to be used with the < operator).
4. Python sees your Squares object being used in a for loop and tries iterating over it, which means calling your Squares object's __iter__() method.
5. The output of that __iter__() method needs to be an iterator, which in Python is defined as anything that implements next(). In your case, since Squares implements next() itself, your __iter__() just returns self.
6. Finally, the for loop keeps calling your Squares object's next() method until it raises StopIteration (essentially using the exception as a signal that the iterator's all used up) and then exits.

The reason it's a bit confusing is because Python wants to give objects the option to return something else as "the iterator" when their __iter__() method is called. For example, your class might implement an internal data object which is the real iterator, like a list or something, and you would then return that. In your case, there's no need for that, so Squares just implements the iterator API itself and returns self.

This happens fairly often in Python; for really simple cases things seem to have an extra step or two, but it's set up that way to make things much more flexible overall.

bitprophet fucked around with this message at 05:19 on Jun 17, 2008

Karate Bastard
Jul 31, 2007

Soiled Meat
My apologies if this has already been discussed, but search is still down and google has failed me despite feeding it hours of my life.

I think I may have found a bug in pygtk, namely in gtk.gdk.Pixbuf.scale().

I'm developing a pygtk application where I need to show images zoomed in so that the user can see individual pixels. gtk.gdk.Pixbuf.scale() seemed ideal for this, but if I set offset_x and offset_y to anything other than 0, the resulting image is heavily distorted and the offset is wrong. I think this may be a bug, but since it seems so fundamental I think it's way more likely that I've misunderstood something. Any help is greatly appreciated.

I wrote a test program to show off this behavior (show_hasselhoff.py). Please find attached an image of David Hasselhoff with some puppies to help facilitate this demonstration. (feel free to use any image, but who doesn't like Hasselhoff and puppies?)

When you run this, you should see 4 images in a window. From left to right: original, nice, ugly and expected. nice, ugly and expected are scaled/cropped copies of original, but ugly and expected are offset to show less mullet and more face. expected is what I expected ugly to turn out like judging from the pygtk docs.

Things to note about ugly:
* The topleft pixel of original has been stretched to the area of offset_x * offset_y.
* The first offset_x - 1 top pixels of original have been scaled by a factor 2 horizontally and then stretched vertically to the height of offset_y.
* Vice versa for the first offset_y - 1 leftmost pixels of original.
* The remaining area of ugly is a scaled version of original(1,1,width/2-1,height/2-1).

Things to note about the methods:
* This behavior is constant for all interpolation methods.
* This behavior is identical in gtk.gdk.Pixbuf.compose().

This can't possibly be how this is supposed to work! Have I misunderstood something, or is this a bug?

show_hasselhoff.py:
code:
import gtk

original = gtk.gdk.pixbuf_new_from_file('hasselhoff.jpeg')
w = original.get_width()
h = original.get_height()
interp = gtk.gdk.INTERP_NEAREST

nice = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h)
ugly = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h)
original.scale(nice, 0, 0, w, h, 0, 0, 2, 2, interp)
original.scale(ugly, 0, 0, w, h, w/2, h/2, 2, 2, interp)

outtake = original.subpixbuf(w/4, h/4, w/2, w/2)
expected = outtake.scale_simple(w, h, interp)

w = gtk.Window()
hbox = gtk.HBox()
hbox.add(gtk.image_new_from_pixbuf(original))
hbox.add(gtk.image_new_from_pixbuf(nice))
hbox.add(gtk.image_new_from_pixbuf(ugly))
hbox.add(gtk.image_new_from_pixbuf(expected))
w.add(hbox)
w.show_all()
w.connect('destroy', gtk.main_quit)
gtk.main()

Only registered members can see post attachments!

trutch
Feb 12, 2005
I'm a System Administrator Intern and have been assigned the task of implementing a Central Logging Server. I am using Splunk to collect the logs, but the reporting feature is not sufficient for our sox auditors. I need to produce a hard copy of the log which is difficult with the current version of Splunk. I am able to export a text file and would like to write a python script that parses through the exported file and generates a report.

In the report I would like to split it up based on days and suppress duplicate entries into a counter integer.

This is what I currently have. (Forgive my sloppiness)

Sample Input File
Desired Output

If anyone has any suggestions on how to tackle this I'd appreciate it. I don't have too much background in coding other than some C++, but I'm really enjoying python and would like to learn it more in depth.

hey mom its 420
May 12, 2007

What qualifies a duplicate entry? What's that column where it's mostly zeroes but one 36 and a 3? Is that the counter?

trutch
Feb 12, 2005

Bonus posted:

What qualifies a duplicate entry? What's that column where it's mostly zeroes but one 36 and a 3? Is that the counter?

No those numbers are just part of the log. By duplicate entry I mean the same message on the same day based on their IP.

For example, I would consider this a duplicate entry:
09:35:59 10.1.0.146/10.1.0.146 squid[12651]: 1213713360.076 0 10.12.32.51 TCP_DENIED/407 1816 GET http://ahost.company.com:7778/dev60cgi/f60cgi - NONE/- text/html
09:35:37 10.1.0.146/10.1.0.146 squid[12651]: 1213713337.286 0 10.12.32.51 TCP_DENIED/407 1816 GET http://ahost.company.com:7778/dev60cgi/f60cgi - NONE/- text/html

such a nice boy
Mar 22, 2002

I'd start off by making a dictionary whose key is a tuple:

(date, message, ip) -> {count: 2, text:"full text of log line"}

Then increment count every time you get a match. Just store the text the first time you populate the entry.

trutch
Feb 12, 2005
Thanks for the help. I've created a dictionary with key (DATE,MESSAGE) and values (1#count integer,MESSAGE). If the DATE and MESSAGE match a key that is currently in the dictionary, I add 1 to the count integer. Otherwise it creates a new key and value.

I am having problems getting the integer count to work. It seems to be filtering out duplicate entries but the count isn't updating.

code:
rxinput = re.compile(rawstr)
for line in InputFile:
         for input in rxinput.finditer(line):
                 DATE = (input.group(1))
                 MESSAGE = (input.group(2))
                 if (DATE,MESSAGE) in dict.keys():
                         dict[(DATE,MESSAGE)][0]+=1
                         print dict[(DATE,MESSAGE)][0]
                         break
                 else:
                         dict[(DATE,MESSAGE)]=[1,MESSAGE]
Full Source here

tehk
Mar 10, 2006

[-4] Flaw: Heart Broken - Tehk is extremely lonely. The Gay Empire's ultimate weapon finds it hard to have time for love.

Karate Bastard posted:

I'm developing a pygtk application where I need to show images zoomed in so that the user can see individual pixels. gtk.gdk.Pixbuf.scale() seemed ideal for this

I would use cairo for what you are trying to do. A project I work on converted all its Pixbuf based animations/displaycode and it has been heaven ever since. It is worlds more flexible and the python bindings are pretty straight forward.

bitprophet
Jul 22, 2004
Taco Defender

trutch posted:

Thanks for the help. I've created a dictionary with key (DATE,MESSAGE) and values (1#count integer,MESSAGE). If the DATE and MESSAGE match a key that is currently in the dictionary, I add 1 to the count integer. Otherwise it creates a new key and value.

I am having problems getting the integer count to work. It seems to be filtering out duplicate entries but the count isn't updating.

code:
rxinput = re.compile(rawstr)
for line in InputFile:
         for input in rxinput.finditer(line):
                 DATE = (input.group(1))
                 MESSAGE = (input.group(2))
                 if (DATE,MESSAGE) in dict.keys():
                         dict[(DATE,MESSAGE)][0]+=1
                         print dict[(DATE,MESSAGE)][0]
                         break
                 else:
                         dict[(DATE,MESSAGE)]=[1,MESSAGE]
Full Source here

Don't call your dict "dict", call it something else, as "dict" is the builtin word for the dictionary type. It's probably not what's causing your problem, but it could definitely cause issues, so don't do it :) same for "str" and so on.

Otherwise I don't see anything obviously wrong, but I haven't gone over it with a fine-toothed comb or anything.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

trutch posted:

Thanks for the help. I've created a dictionary with key (DATE,MESSAGE) and values (1#count integer,MESSAGE). If the DATE and MESSAGE match a key that is currently in the dictionary, I add 1 to the count integer. Otherwise it creates a new key and value.

I am having problems getting the integer count to work. It seems to be filtering out duplicate entries but the count isn't updating.

code:
rxinput = re.compile(rawstr)
for line in InputFile:
         for input in rxinput.finditer(line):
                 DATE = (input.group(1))
                 MESSAGE = (input.group(2))
                 if (DATE,MESSAGE) in dict.keys():
                         dict[(DATE,MESSAGE)][0]+=1
                         print dict[(DATE,MESSAGE)][0]
                         break
                 else:
                         dict[(DATE,MESSAGE)]=[1,MESSAGE]
Full Source here

I don't see anything obviously broken, but some points of style. Only the first one is really important:

- There's no reason to store your message in the value, because it's already in the key. You'll be iterating through the dict with something like "for (msgDate, message) in msgDict: count = msgDict[msgDate, message][0]" and you'll notice that you never need to look at msgDict[msgDate, message][1] because you'll just get the same message.
- ALLCAPS usually means a constant. To avoid confusion, just use "date" and "message". ("date" is also the name of a fairly important module, so you might want to use "msgDate", meaning "the date of the message", or something instead. That's definitely not a problem if you never actually import the date module, but it's better to plan ahead in case you ever want to.)
- Like the guy said, don't use "dict" as a variable name - use something like "msgDict"
- Minor, but you can just use "msgDict[msgDate, message]" - Python automatically knows that a dictionary key with more than one part is a tuple. That saves some brackets and makes things more readable.
- You don't actually need to use ".keys()" with the "in" keyword - it automatically looks for a key in the dictionary, not a value

So that leads to:

code:
rxinput = re.compile(rawstr)
for line in InputFile:
    for input in rxinput.finditer(line):
        msgDate = input.group(1)
        message = input.group(2)
        if msgDate, message in msgDict:
            msgDict[msgDate, message] += 1
            print msgDict[msgDate, message]
            break
        else:
            msgDict[msgDate, message] = 1

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

JoeNotCharles posted:

code:
rxinput = re.compile(rawstr)
for line in InputFile:
    for input in rxinput.finditer(line):
        msgDate = input.group(1)
        message = input.group(2)
        if msgDate, message in msgDict:
            msgDict[msgDate, message] += 1
            print msgDict[msgDate, message]
            break
        else:
            msgDict[msgDate, message] = 1

If using 2.5 you can make it be this:
code:
from collections import defaultdict
msgDict = defaultdict(int)
rxinput = re.compile(rawstr)
for line in InputFile:
    for input in rxinput.finditer(line):
        msgDate = input.group(1)
        message = input.group(2)
        msgDict[msgDate, message] += 1
        #I assumed the print was a debugging statement
        #also I don't get why you're breaking.
I think I like defaultdicts a bit too much.

deimos fucked around with this message at 20:11 on Jun 18, 2008

trutch
Feb 12, 2005

JoeNotCharles posted:

There's no reason to store your message in the value, because it's already in the key. You'll be iterating through the dict with something like "for (msgDate, message) in msgDict: count = msgDict[msgDate, message][0]" and you'll notice that you never need to look at msgDict[msgDate, message][1] because you'll just get the same message.
My intent was to use the message in the key for comparison purposes. I'm not sure where I was going with it, but thought it would be easier to work through the loop.

deimos posted:

code:
#I assumed the print was a debugging statement
#also I don't get why you're breaking.
I was indeed using the print for debugging and I used break because I'm inexperienced and may have gotten a little over my head with this project.

I've taken your guidance and applied it to my code. The problem I had earlier with the count not working had to do with the regex. I'd now like to attempt a report like this:
code:
Jun 13 
	10.222.124.57 TCP_DENIED/407 1816 GET http://ahost.company.com:7778/dev60cgi/f60cgi? - NONE/- text/html 1 time(s)
	10.12.32.125 TCP_DENIED/407 1816 GET http://ahost.company.com:7778/dev60cgi/f60cgi? - NONE/- text/html 2 time(s)
	10.12.32.60 TCP_DENIED/407 1816 GET http://ahost.company.com:7778/dev60cgi/f60cgi? - NONE/- text/html 1 time(s)
Jun 12 
	10.1.0.232 TCP_DENIED/407 1816 GET http://ahost.company.com:7778/dev60cgi/f60cgi? - NONE/- text/html 1 time(s)
	10.30.11.125 TCP_DENIED/407 1816 GET http://ahost.company.com:7778/dev60cgi/f60cgi? - NONE/- text/html 1 time(s)
I've created a separate list with dates to use as a comparison for the loop. My current problem is that I'm not sure how to compare the list with the key msgDate in the dict since it is inside the tuple.

I appreciate all the help and have been working on learning as much as possible about python and this script for the last couple days. Thanks to you all I feel like I'm making some progress.

Karate Bastard
Jul 31, 2007

Soiled Meat

tehk posted:

I would use cairo for what you are trying to do. A project I work on converted all its Pixbuf based animations/displaycode and it has been heaven ever since. It is worlds more flexible and the python bindings are pretty straight forward.

So cairo can do that, huh? It seems obvious now that you mention it... Do you know of any good python docs for cairo? The C API docs were all right I guess, but all that C felt a bit alien after half a decade immersed in python...

Edit: spellng

Karate Bastard fucked around with this message at 22:45 on Jun 18, 2008

tehk
Mar 10, 2006

[-4] Flaw: Heart Broken - Tehk is extremely lonely. The Gay Empire's ultimate weapon finds it hard to have time for love.

Karate Bastard posted:

So cairo can do that, huh? It seems obvious now that you mention it... Do you know of any good python docs for cairo? The C API docs were all right I guess, but all that C felt a bit alien after half a decade immersed in python...

Edit: spellng

http://www.tortall.net/mu/wiki/CairoTutorial
http://www.pygtk.org/articles/cairo-pygtk-widgets/cairo-pygtk-widgets.htm

You will need to look at the C API a bit but if you got the basic info down I gave you in the first link it should be easy to understand.

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.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Milde posted:

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

There's sensible conventions that actually give information, and then there's just being a nitpicker.

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.

such a nice boy
Mar 22, 2002

Milde posted:

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.

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.

Adbot
ADBOT LOVES YOU

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.

  • Locked thread