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
mightygerm
Jun 29, 2002



Bozart posted:

Alright then, cool. I got Learning Python and read the Tutorial, so I think I am good to go.

The only annoying thing is that the help for built in classes and methods sucks hard after Matlab's great help system. I'll have to spend time bumming around on the python wiki to see if they have better documentation there. Is the Programming Python book significantly better or more in depth than Learning Python? I figure it has a different focus because it has a different animal on the cover!

In the interactive interpreter, you can do this
code:
>>> import sys
>>> print sys.__doc__     
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.

Dynamic objects:

argv -- command line arguments; argv[0] is the script pathname if known
path -- module search path; path[0] is the script directory, else ''
modules -- dictionary of loaded modules
...etc...
Replace sys with whatever module you're looking for. Can also be used for functions.

As for books, I've never read Learning Python, but the 'Programming' series of books are usually more in-depth than the 'Learning' series.

Adbot
ADBOT LOVES YOU

Bozart
Oct 28, 2006

Give me the finger.

Mighty Germ posted:

In the interactive interpreter, you can do this... (snip)

As for books, I've never read Learning Python, but the 'Programming' series of books are usually more in-depth than the 'Learning' series.

What I mean is that stuff like this:
code:
>>> help(string.translate)
Help on function translate in module string:

translate(s, table, deletions='')
    translate(s,table [,deletions]) -> string
    
    Return a copy of the string s, where all characters occurring
    in the optional argument deletions are removed, and the
    remaining characters have been mapped through the given
    translation table, which must be a string of length 256.  The
    deletions argument is not allowed for Unicode strings.
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

code:
>> help strrep
 STRREP Replace string with another.
    S = STRREP(S1,S2,S3) replaces all occurrences of the string S2 in
    string S1 with the string S3.  The new string is returned.
 
    STRREP(S1,S2,S3), when any of S1, S2, or S3 is a cell array of
    strings, returns a cell array the same size as S1,S2 and S3
    obtained by performing a STRREP using corresponding elements of
    the inputs.  The inputs must all be the same size (or any can
    be a scalar cell). Any one of the strings can also be a character
    array with the right number of rows.
 
    Example:
        s1='This is a good example';
        strrep(s1,'good','great') returns 'This is a great example'
        strrep(s1,'bad','great')  returns 'This is a good example'
        strrep(s1,'','great')     returns 'This is a good example'
 
    See also strfind, regexprep.

    Overloaded methods:
       string/strrep

    Reference page in Help browser
       doc strrep
Which is much more descriptive.

Edit:
This also illustrates how screwed up matlab's string handling is. You can have a cell array of strings or a character row or a matrix of characters, and all chars are stored as DOUBLE! Andyou can't overload builtin types.

Bozart fucked around with this message at 22:35 on Apr 16, 2008

hairacles
Mar 1, 2006

Ba-dunk-a-dunk
Well, I'm dumb, my question earlier, was answered. Turns out it I was supposed to be passing in a Node instead of an array. Thanks for the help anyways.

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.

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.

Bozart posted:

What I mean is that stuff like this:
Which is much more descriptive.

You might want to use a IDE that has integrated documentation, its has been very useful in my experience. There are a few for every OS that do this. Now this doesn't help in the interpretor but its useful none the less.

sd6
Jan 14, 2008

This has all been posted before, and it will all be posted again
Need some help with the ctypes module.

code:
from ctypes import *

class record(Structure):
    _fields_=("key", py_object), ("value", py_object)
Does anyone know how I can write a condition test to see if one of the fields is null? The ctypes tutorial says initializing a py_object without parameters makes it a NULL PyObject pointer. It also says that you can use the bool function on a null pointer and it will return False, but when I do something like:
code:
rec = record()
print bool(rec.key)
IDLE just gives me "ValueError: PyObject is NULL".

duck monster
Dec 15, 2004

Mighty Germ posted:

In the interactive interpreter, you can do this
code:
>>> import sys
>>> print sys.__doc__     
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.

Dynamic objects:

argv -- command line arguments; argv[0] is the script pathname if known
path -- module search path; path[0] is the script directory, else ''
modules -- dictionary of loaded modules
...etc...
Replace sys with whatever module you're looking for. Can also be used for functions.

As for books, I've never read Learning Python, but the 'Programming' series of books are usually more in-depth than the 'Learning' series.

or use the helper function

help(<thing>)

where thing can be a module, object, function , class, or whatever. combine with dir(<thing>) to peek into somethings internal organs, and you've got all your documentation right there.

That said, I personally find the documentation on the python website excelent.

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.

Appa Time! posted:

Does anyone know how I can write a condition test to see if one of the fields is null? The ctypes tutorial says initializing a py_object without parameters makes it a NULL PyObject pointer. It also says that you can use the bool function on a null pointer and it will return False, but when I do something like:
IDLE just gives me "ValueError: PyObject is NULL".

You can run a condition test on a null pointers object but not on its value, like below. Since the key and value of record are the py_objects value and not the null py_object its self this method will not work.
code:
>>> bool(py_object(1))
:   True
>>>
>>> bool(py_object())
:   False

>>> bool(py_object().value)
:   <type 'exceptions.ValueError'>: PyObject is NULL

tehk fucked around with this message at 06:32 on Apr 18, 2008

Scaevolus
Apr 16, 2007

JoeNotCharles posted:

(Python has no separate arrays, you're really using lists)
>>> import array
>>> help(array)

I prefer 'pydoc' to the interpreter's help(), myself.

sd6
Jan 14, 2008

This has all been posted before, and it will all be posted again

tehk posted:

You can run a condition test on a null pointers object but not on its value, like below. Since the key and value of record are the py_objects value and not the null py_object its self this method will not work.


Yeah I guess I'll use exception handling to check if the value is null, thanks.

oRenj9
Aug 3, 2004

Who loves oRenj soda?!?
College Slice
I'm creating a small application using wxPython. I'm having an issue keeping the wx output box present when there is an error in the application. It opens then quickly closes. Is there a way to get it to stick around longer, or redirect it's output to a file?

This is under Windows XP-64.

Edit:
This fixed my problem:
code:
app = wx.App(True, 'wx_error.log')

oRenj9 fucked around with this message at 20:44 on Apr 20, 2008

Hero Pussy
Aug 4, 2005

please allow me to introduce myself
i'm a man of wealth and taste
I have a really stupid and really basic Python question because I was using string formatting operators and then my brain stopped working and I'm really tired and I can't find where I learned this in my Python book. :(

What is the difference between d and f (or more accurately why is the difference)? Decimal stops when it hits the decimal and floating point displays the whole thing (eg %d of 1234.1928 is 1234, %f of 1234.1928 is 1234.1928), but I can't remember why.

No Safe Word
Feb 26, 2005

Hero Pussy posted:

I have a really stupid and really basic Python question because I was using string formatting operators and then my brain stopped working and I'm really tired and I can't find where I learned this in my Python book. :(

What is the difference between d and f (or more accurately why is the difference)? Decimal stops when it hits the decimal and floating point displays the whole thing (eg %d of 1234.1928 is 1234, %f of 1234.1928 is 1234.1928), but I can't remember why.

%d is actually for integers. %f is for floats.

http://www.python.org/doc/current/lib/typesseq-strings.html

Hero Pussy
Aug 4, 2005

please allow me to introduce myself
i'm a man of wealth and taste

No Safe Word posted:

%d is actually for integers. %f is for floats.

http://www.python.org/doc/current/lib/typesseq-strings.html

o

Yes, this makes more sense.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...
A database security / access question, for which I want a Python solution:

So I have this small to medium sized database, for which I've written an access wrapper in SqlAlchemy. The wrapper handles searches, addition and deletion and so on, and lies between the actual database and the web services that will use it. So far so good.

The complexity comes in terms of different access levels. Not all rows should be accessible to all users, some users will have access to all of them, some to restricted sets: a fairly classic access control problem that I'd like to solve in the software layer. However, I haven't found a great deal of prior art in SqlAlchemy or Python. Any pointers? I'd hate to have to write a whole ACL library just for this.

Land Mime
Jul 13, 2007
Love never blows up and gets killed
Does this really need to be solved at the software layer? Allowing certain users to view certain rows sounds perfectly suited for, well, views. Of course depending on your situation this may be a horrible idea, but its certainly the first thing that came to mind.

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

Land Mime posted:

Does this really need to be solved at the software layer? Allowing certain users to view certain rows sounds perfectly suited for, well, views. Of course depending on your situation this may be a horrible idea, but its certainly the first thing that came to mind.

I had that idea too. Unfortunately, it's not going to work. Neither the groups / users, or the subsets of data they can see will be fixed, or identical across installations. It also causes run-on problems with the object-mapping in SqlAlchemy (e.g. "Country objects are mapped and retrieved from the country, the country_public_view table, the country_restricted_view table, the country_admin_view table ..."). You see my problem.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...
While I'm throwing questions out to the masses: here's one about iterators and generators. There seems to be two styles when people are writing iterators for their own containers - having the yield within the class and having it in an external function.

A toy example - take a container class and give it an iterator to yield the contents:

code:
class L(list):
   def traverse (self):
      for i in self:
         yield i
Simple. But you commonly also see a style where this is done:

code:
class L(list):
   def traverse (self):
      return _traverse (self):

def _traverse (mylist):
      for i in mylist:
         yield i
What's the difference? It seems to me as if these are functionally different. I though that the second (independent) iterator might be thread-safe or allow against multiple simultaneous iterators. Quick experimentation says not. Any ideas?

nonathlon fucked around with this message at 15:06 on Apr 23, 2008

No Safe Word
Feb 26, 2005

outlier posted:

Simple. But you commonly also see a style where this is done:

code:
class L(list):
   def traverse (self):
      return _traverse (self)

def _traverse (mylist):
      for i in mylist:
         yield i
What's the difference? It seems to me as if these are functionally different. I though that the second (independent) iterator might be thread-safe or allow against multiple simultaneous iterators. Quick experimentation says not. Any ideas?

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.

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.

duck monster
Dec 15, 2004

outlier posted:

A database security / access question, for which I want a Python solution:

So I have this small to medium sized database, for which I've written an access wrapper in SqlAlchemy. The wrapper handles searches, addition and deletion and so on, and lies between the actual database and the web services that will use it. So far so good.

The complexity comes in terms of different access levels. Not all rows should be accessible to all users, some users will have access to all of them, some to restricted sets: a fairly classic access control problem that I'd like to solve in the software layer. However, I haven't found a great deal of prior art in SqlAlchemy or Python. Any pointers? I'd hate to have to write a whole ACL library just for this.

I tend to use decorators.

Like just make a decorator that encapsulates an @acl type function.

However, yes, views are another way of tilting at the issue. I just suspect it could get a bit sticky if you get too complicated with them.

oRenj9
Aug 3, 2004

Who loves oRenj soda?!?
College Slice

Milde posted:

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.

Exactly...

Example:
code:
class fib():
  def __init__(self):
    self.num = (1,1)
  def __iter__(self):
    while True:
      self.num = (self.num[1], sum(self.num))
      yield self.num[1]
This class could be used like Milde said:
code:
fib_seq = iter(fib())
fib_seq.next()
Or in a loop:
code:
fib_seq = fib()
for x in fib_seq:
  if x > 1000000:
    break
  print x
edit: Minor code refactor.

oRenj9 fucked around with this message at 06:27 on Apr 24, 2008

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

Milde posted:

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

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.

The dichotomy in method / external iterators is a puzzle because of its presence in code that I've seen. In a way, it's a relief that no one else understands what the difference because I sure can't see it. Any method or function that yields should create an independent generator - with it's own state - when first called. So functionally the two should be identical. And - for tidier code - why not just put the whole iterator in a method.

(I have to go beyond __iter__ in my particular project because the container has to be iterated over in a number of different ways. It's a tree structure and need iteration over vertexes, arcs, in post-order, pre-order etc.)

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. :)

oRenj9
Aug 3, 2004

Who loves oRenj soda?!?
College Slice

outlier posted:

(I have to go beyond __iter__ in my particular project because the container has to be iterated over in a number of different ways. It's a tree structure and need iteration over vertexes, arcs, in post-order, pre-order etc.)

I would create sub-classes for each of the different iterators. It would make the code much cleaner and it will end up functionally the same since each time iter() is called, it creates a new generator instance anyway.

PrinceofLowLight
Mar 31, 2006
Wow. I was learning C on and off with a friend for a while. Just started toying around with Python and after a few days I can already do more than I could in C.

Having one minor recurring issue, though. Whenever I have it print a variable, it skips a line. As in:

name = raw_input("What is your name?")

print name "is a very stupid name."

Would read as:

What is your name? Princeoflowlight

Princeoflowlight
is a very stupid name.


I'm using Pydev/Eclipse. Is there something in the default settings or something?

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
My first thought was that raw_input was storing the \n (end-of-line) character from when you hit return after typing your name, and that "print name.strip()" would fix it. But when I tried it from the Python prompt, it didn't do that. Weird.

What happens if you just run Python and type that at the >>> prompt?

bitprophet
Jul 22, 2004
Taco Defender

PrinceofLowLight posted:

print name "is a very stupid name."

I think the problem is you're passing >1 argument to 'print' (which doesn't even seem legal, how are you doing that?). Try this:

code:
print "%s is a very stupid name." % name

No Safe Word
Feb 26, 2005

bitprophet posted:

I think the problem is you're passing >1 argument to 'print' (which doesn't even seem legal, how are you doing that?).
I thought the same thing and it turns out it isn't.

The language reference confirms it as well as simply trying it in the interpreter.

And I was ready to pass it through a bit of bytecode exploration using the code here, but SyntaxErrors abound.

edit: and for those interested, when you "fix" it using the other way (putting a comma after name instead of using string formatting), it looks like this:

code:
OFFSET INSTRUCTION          OPCODE    ARG  TYPE                  VALUE
    0  LOAD_GLOBAL          (116)       0  GLOBAL VARIABLE       (raw_input)
    3  LOAD_CONST           (100)       1  CONSTANT              ('What is your name?')
    6  CALL_FUNCTION        (131)       1  OTHER                 (1)
    9  POP_TOP              (  1)
   10  LOAD_GLOBAL          (116)       1  GLOBAL VARIABLE       (name)
   13  PRINT_ITEM           ( 71)
   14  LOAD_CONST           (100)       2  CONSTANT              ('is a very stupid name.')
   17  PRINT_ITEM           ( 71)
   18  PRINT_NEWLINE        ( 72)
   19  LOAD_CONST           (100)       0  CONSTANT              (None)
   22  RETURN_VALUE         ( 83)

No Safe Word fucked around with this message at 18:43 on Apr 24, 2008

Strong Sauce
Jul 2, 2003

You know I am not really your father.





Either use a comma:

print name, "is a very stupid name."

or, since they are both strings, use + to concatenate.

print name+ " is a very stupid name."

bitprophet
Jul 22, 2004
Taco Defender

No Safe Word posted:

I thought the same thing and it turns out it isn't.

The language reference confirms it as well as simply trying it in the interpreter.

Well, if you put a comma or a plus sign, of course it works. His code was literally:

code:
print name "is a very stupid name."
which is incorrect:

code:
Python 2.5.1 (r251:54863, Oct  5 2007, 13:50:07) 
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> name = "Foo"
>>> print name "is not Bar"
  File "<stdin>", line 1
    print name "is not Bar"
                          ^
SyntaxError: invalid syntax
Pedantry: only slightly less dickish when it concerns programming :downs:

EDIT: anyway, to double-check whether raw_input sneaks in newlines, it doesn't seem to:

code:
Python 2.5.1 (r251:54863, Oct  5 2007, 13:50:07) 
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> name = raw_input("What is your name?")
What is your name?foo
>>> print name, "is a very stupid name"
foo is a very stupid name
>>>

oRenj9
Aug 3, 2004

Who loves oRenj soda?!?
College Slice

No Safe Word posted:

And I was ready to pass it through a bit of bytecode exploration using the code here, but SyntaxErrors abound.

That is awesome, thanks for the link!

PrinceofLowLight
Mar 31, 2006
Sorry, typed it up as I was running out the door.

Here's the original code:

name = raw_input('What is your name?')
print name + "is a very stupid name"

Here's the output:

What is your name? Princeoflowlight
Princeoflowlight
is a very stupid name

I've also tried using a comma instead of a plus sign, but that doesn't fix it.

Now I'm thinking it's something with PyDev, since I just ran it in Python.exe and it didn't insert the new line. No idea where to start looking, though.

Lancer383
Aug 15, 2007

Say what you want about the tenants of national socialism, Dude, at least it was an ethos.
Not sure why you're having that issue with the print command -- have you tried using sys.stdout.write(string)? In your example it would be:

code:
import sys

name = raw_input("What is your name?")
sys.stdout.write(name + " is a stupid name.")

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

PrinceofLowLight posted:

Now I'm thinking it's something with PyDev, since I just ran it in Python.exe and it didn't insert the new line. No idea where to start looking, though.

Here you go: http://pydev.sourceforge.net/faq.html#why_raw_input_input_does_not_work_correctly

(Found it by googling for "PyDev raw_input"

PrinceofLowLight
Mar 31, 2006
Thanks! Wow, that's annoying to have to do every time. Rather unPython-like. Maybe I'll just work with Komodo Edit.

CrusaderSean
Jun 10, 2002
AwakenedDreamer
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']

CrusaderSean fucked around with this message at 02:02 on May 1, 2008

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']

CrusaderSean
Jun 10, 2002
AwakenedDreamer

Milde posted:

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

I had no idea about the syntax or control flow of your code until I read this. That's pretty neat! Thanks

Adbot
ADBOT LOVES YOU

Moof Strydar
Jul 13, 2001

In my small utilities, I've taken to using a kind of fake enum, along the lines of this:

code:
enumIDs = ['ID_NEWPROJECT',
           'ID_OPENPROJECT',
           'ID_SAVEPROJECT']

for i, id in enumerate(enumIDs):
    exec id + ' = ' + str(i)
    
del enumIDs
del i
del id

# ID_NEWPROJECT, ID_OPENPROJECT and ID_SAVEPROJECT are now normal variables.
# For bitwise use just change "str(i)" to "str(pow(2, i))"
My question is, am I creating a vulnerability by using exec in this way?

  • Locked thread