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
jupo
Jun 12, 2007

Time flies like an arrow, fruit flies like a banana.

Haystack posted:

It's not possible using the example you provided

Not that you'd ever want to do it, but it actually is possible:

code:
>>> def MathA():
...     print("2+2")
...     def MathB():
...         print("no")
... 
>>> exec(MathA.__code__.co_consts[2])
no
>>> 

Adbot
ADBOT LOVES YOU

Thermopyle
Jul 1, 2003

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

So thanks for the recommendations for Eventlet! It's awesome.

Anyway, I'm receiving commands over a socket. For example, one command may be the text "!serveryell". What's a good way to execute the correct function for the !serveryell command?

Right now, I have a dict with {"!serveryell": "serveryellfunc()"} and after looking up the command in the dict, I eval("serveryellfunc()").

This feels really lovely to me.

I don't really want to code in a bunch of if statements with each command so that it's easier to add new commands.

Avenging Dentist
Oct 1, 2005

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

Thermopyle posted:

So thanks for the recommendations for Eventlet! It's awesome.

Anyway, I'm receiving commands over a socket. For example, one command may be the text "!serveryell". What's a good way to execute the correct function for the !serveryell command?

code:
d = {'!serveryell': serveryellfunc}
d['!serveryell']()

Thermopyle
Jul 1, 2003

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

Avenging Dentist posted:

code:
d = {'!serveryell': serveryellfunc}
d['!serveryell']()

Oh yeah...duh.

Thanks.

nbv4
Aug 21, 2002

by Duchess Gummybuns

Avenging Dentist posted:

code:
d = {'!serveryell': serveryellfunc}
d['!serveryell']()

am I the only one here that would do this instead:

code:
d['!serveryell'].__call__()
I think it's a little easier to read than with just a () tacked on...

Allie
Jan 17, 2004

Yes, you're the only one, and you're a big weirdo too.

king_kilr
May 25, 2007

nbv4 posted:

am I the only one

Yes, you are terrible for it. All you're doing is obscuring intent, __call__ says to me that you're trying to do something clever, possibly work around the behavior or something (lord knows what), () tells me you want to call a loving function.

Captain Capacitor
Jan 21, 2008

The code you say?
code:
def invalid():
    print "Invalid command!"

d = {'!serveryell': serveryellfunc}
d.get('!serveryell', invalid)()

Is how I've done it before

nbv4
Aug 21, 2002

by Duchess Gummybuns

king_kilr posted:

Yes, you are terrible for it. All you're doing is obscuring intent, __call__ says to me that you're trying to do something clever, possibly work around the behavior or something (lord knows what), () tells me you want to call a loving function.

what males you think callable.__call__() is not the exact same thing as callable()? The reason I do it is because one time I had a line that was something like:

code:
value = other_value / ((val + dic.get('something', 'somethingelse')(var + foo))
and it was not obvious that I was calling 'something' or 'somethingelse' amongst all the parenthesis. Now I either use .__call__(), or I split it up (if I can) into two lines and do it like this:

code:
f = dic.get('something', 'somethingelse')
value = other_value / ((val + f(var + foo))

king_kilr
May 25, 2007

nbv4 posted:

what males you think callable.__call__() is not the exact same thing as callable()? The reason I do it is because one time I had a line that was something like:

I know *exactly* what __call__ does, that is not mutually exclusive with also thinking that using it is simply obscuring the intent of the code.

nbv4
Aug 21, 2002

by Duchess Gummybuns

king_kilr posted:

I know *exactly* what __call__ does, that is not mutually exclusive with also thinking that using it is simply obscuring the intent of the code.
What I meant to ask is what difference in intent do you imply between the two methods? If anything, I think invoking the __call__ method is actually less obscuring than appending parentheses. __call__ is only used for one purpose: to call a callable. On the other hand, parentheses are used for many different purposes: tuples, order of operations, as well as calling callables. With __call__ you're saying loudly, explicitly, and exactly "This object is callable and I'm calling it at this time", whereas with just parentheses you have to look closer to determine why they're there.

It's not very common for a dict to return a function object. It's actually not that common for anything to return a callable. Therefore its easy to assume that in my code example that an operator needs to go between the get(...) and the (var+foo).

You said previously that using __call__ implies that you're doing something clever. Thats exactly whats going on here. I'm calling the return value of another callable. To me thats pretty darn clever.

Avenging Dentist
Oct 1, 2005

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

nbv4 posted:

To me thats pretty darn clever.

If you think that's clever, you must constantly be wowed by every little thing in the world.

Basically, if you're directly calling Python magic functions, you're probably being dumb and no one else in the world is going to want to look at your code. This would be like typing foo.operator + (bar) every time you wanted to add foo and bar together in C++.

(EDIT) More to the point: if you wanted to maximize readability, why would you not use an intermediate variable instead of barfing up a bunch of underscores?

Avenging Dentist fucked around with this message at 09:28 on Mar 18, 2010

nbv4
Aug 21, 2002

by Duchess Gummybuns

Avenging Dentist posted:

If you think that's clever, you must constantly be wowed by every little thing in the world.

Basically, if you're directly calling Python magic functions, you're probably being dumb and no one else in the world is going to want to look at your code. This would be like typing foo.operator + (bar) every time you wanted to add foo and bar together in C++.

(EDIT) More to the point: if you wanted to maximize readability, why would you not use an intermediate variable instead of barfing up a bunch of underscores?

I only used "clever" in my post because thats the word king_kilr used. "something not obvious at first glance" would work better.

And if you read a few post up, I agree using intermediate variables is better than tacking on ()'s after a callable.

Thermopyle
Jul 1, 2003

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

nbv4 posted:

Calling callables __call__ callcallcallcallcallcallcall

As someone much less experienced than most here, and who spends a lot of time trying to figure out other people's code, I would definitely find your usage confusing.

I'd be thinking "What did I miss here? Why didn't he just use ()? What's going on?!?!"

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Here's a design question: I have a funky array class that stores 1) a regular (NumPy) array, and 2) an array of elements related to those in (1), pointed to by entries in an index buffer, pointed to by ranges in an offset array. Example:

Suppose I have 3 keys (this is (1)): [1, 2, 3]. I also have 6 values: [10, 11, 12, 13, 14, 15]. 1 is related to [10, 11, 12, 13], 2 is related to [11, 12, 13, 14], and 3 is related to [12, 13, 14, 15]. So here's how the data looks:

code:
keys = [1, 2, 3]
offsets = [0, 4, 8, 12]
indices = [0, 1, 2, 3,
           1, 2, 3, 4,
           2, 3, 4, 5]
values = [10, 11, 12, 13, 14, 15]
Ok so that's all easy-peasy. The class supports array indexing, where foo[i] returns the ith key along with all the values it's related to.

But, and here's the part where my question comes in, sometimes I may want just the values. Or just the indices. Or the keys + the indices. I can do all these with functions, but then you end up with a class where accessing an element sometimes uses [] and sometimes uses (). It also makes it impossible to iterate over just the values. Would it be entirely too "clever" if I wrote a decorator to turn a function getvalues() into a quasi-array with indexing, len, iterators, and all that?

EDIT: Ok nevermind on all this. I realized it made more sense to return a tuple containing (keys, MyClass(offsets, indices, values)) and let the user use zip as necessary.

Avenging Dentist fucked around with this message at 23:45 on Mar 18, 2010

mediocre dad okay
Jan 9, 2007

The fascist don't like life then he break other's
BEAT BEAT THE FASCIST
Why doesn't this work:
code:
plt.plot([x[0] for x in results["Maximum"]], [x[z] for x in results["Maximum"]], 'r') for z in range( 1, top )
When results is essentially a dictionary in the format

{"Maximum": [[1,2,3],[3,4,5],[6,7,8]...] ...}

I get
code:
  File "practical1.py", line 159
    plt.plot([x[0] for x in results["Maximum"]], [x[z] for x in results["Maximum"]], 'r') for z in range( 1, top )
                                                                                            ^
SyntaxError: invalid syntax
[Finished in 0.218 seconds]
basically I want to plot a dynamic number of rows on a graph using matplotlib.

mediocre dad okay fucked around with this message at 03:46 on Mar 19, 2010

Avenging Dentist
Oct 1, 2005

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

Kulebri posted:

Why doesn't this work:
code:
plt.plot([x[0] for x in results["Maximum"]], [x[z] for x in results["Maximum"]], 'r') for z in range( 1, top )

The outermost for is not part of a list comprehension. That syntax is only for list comprehensions.

mediocre dad okay
Jan 9, 2007

The fascist don't like life then he break other's
BEAT BEAT THE FASCIST

Avenging Dentist posted:

The outermost for is not part of a list comprehension. That syntax is only for list comprehensions.

How do I make it part of one?

Avenging Dentist
Oct 1, 2005

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

Kulebri posted:

How do I make it part of one?

Just put the outer for on the previous line. Stop trying to be clever. (Do you really want a list of lists of all the lines plotted? I doubt it.)

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"

Kulebri posted:

How do I make it part of one?

List comprehensions are when you want to make lists. If you want a loop, just use a loop.

code:
for z in range( 1, top ):
  plt.plot([x[0] for x in results["Maximum"]], [x[z] for x in results["Maximum"]], 'r')
e: Comcast sappin' my post times

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Ok so revenge of the offset array thing. Here's the deal: I have two NumPy arrays: an array of data, and an array of offsets into that data. Put these together and you get something that looks like an array of (jagged) arrays. Each consecutive pair of elements in the offsets represents the begin and end of that chunk: [begin, end). If your outer dimension is N, then len(offsets) == N+1.

Mostly for fun, I want to make arbitrary slices on this work (just for the outer array). Slices of consecutive elements is easy, but non-consecutive is hard. I can do the offsets in a fairly sane way, but I feel like there's room for improvement on the data array. Here's the code (pretend that chop is part of a __getitem__ function in some class; s is the slice). Any ideas?

EDIT: Ok I updated the code a bit but it could still use improvement I think (also I fixed the stupid typos from 1:30 AM)
EDITx2: Ok updated again. I think this is as good as I can get without dropping into C.

Avenging Dentist fucked around with this message at 20:52 on Mar 19, 2010

tef
May 30, 2004

-> some l-system crap ->
google have released the complete materials for a two day course in python (video and accompanying text)

http://code.google.com/edu/languages/google-python-class/ :toot:

Haystack
Jan 23, 2005





Ok, let's say that I have a generator function that can yield either something or nothing. E.g:
code:
def some_generator(will_yield=False)
    if will_yield:
        yield "It doesn't really matter what I yield, just that I do"
What I'd like to know is the simplest way to test whether a function like some_generator() will yield anything at all. The best I've figured out so far is to use a try/except block and the generator's .next() method, like so:
code:
try:
    some_generator().next()
    print True
except StopIteration:
    print False
It's workable, but I can't help but suspect that I've missed some built-in that's supposed to handle cases like this.

Haystack fucked around with this message at 15:26 on Mar 20, 2010

Scaevolus
Apr 16, 2007

It sounds like you've stumbled into the halting problem.

Opinion Haver
Apr 9, 2007

Haystack posted:

Ok, let's say that I have a generator function that can yield either something or nothing. E.g:
code:
def some_generator(will_yield=False)
    if will_yield:
        yield "It doesn't really matter what I yield, just that I do"
What I'd like to know is the simplest way to test whether a function like some_generator() will yield anything at all. The best I've figured out so far is to use a try/except block and the generator's .next() method, like so:
code:
try:
    some_generator().next()
    print True
except StopIteration:
    print False
It's workable, but I can't help but suspect that I've missed some built-in that's supposed to handle cases like this.

I think that it's not 'Pythonic' to do it that way; you're supposed to try code assuming that the generator will yield something, then handle the exception if it throws a StopIteration.

Jo
Jan 24, 2005

:allears:
Soiled Meat

Scaevolus posted:

It sounds like you've stumbled into the halting problem.

I don't think it's a test to see if a function halts, it's just a function to test whether or not the function is iterable.

Avenging Dentist
Oct 1, 2005

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

Jo posted:

I don't think it's a test to see if a function halts, it's just a function to test whether or not the function is iterable.

Rice's Theorem ("any non-trivial statement about the function that is defined by an algorithm is undecidable") is a consequent of the halting problem.

Scaevolus
Apr 16, 2007

Jo posted:

I don't think it's a test to see if a function halts, it's just a function to test whether or not the function is iterable.

I considered that, but that's not what the given example is.

Haystack
Jan 23, 2005





Scaevolus posted:

I considered that, but that's not what the given example is.

Probably should have been more clear with my examples: I am only interested in whether or not the generator function will iterate, even once. The example was just to demonstrate the try/except logic I was using.

Avenging Dentist
Oct 1, 2005

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

Haystack posted:

Probably should have been more clear with my examples: I am only interested in whether or not the generator function will iterate, even once. The example was just to demonstrate the try/except logic I was using.

It's already been explained but I will be as explicit as possible: it is mathematically impossible to determine the results of arbitrary code without running that code (incidentally, this is why virus scanners still manage to let a lot of sufficiently-clever viruses through). The best you can do is introspect into the code and try to use heuristics to figure it out. I do not recommend this.

CRISPYBABY
Dec 15, 2007

by Reene
I've got a question which I'm sure is stupidly easy, but I barely know any Python.

I'm trying to take inputs in a for loop. So, I have the loop that's something like this
code:
for num in employees
     start = raw_input(prompt1)
     end = raw_input (prompt2)
Now, obviously, this just mutates the start and end variables for each run through of the loop. How would I create unique variables for each run through of the loop? I want to record and save each and every one of these values thats inputted. I thought I might be able to change the definition to start + num or something so that I'd have a corresponding start1, start2 etc for each number value, but that command seems more for strings, I guess. How would I do this?

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
(Extremely) explicit:

code:
my_list = []
for num in employees:
    start = raw_input(blahblahblah)
    end = raw_input (blahblahblah)
    range = (start, end)
    my_list.append(range)
Clever (Google "Python list comprehension"):

code:
my_list = [ (raw_input(blahblahblah), raw_input(blahblahblah)) for num in employees ]

CRISPYBABY
Dec 15, 2007

by Reene
Thanks dude, that'll work. Also, naming the variable range helped me think of a way to do the next part of the function really sweetly, so thanks even more.

CRISPYBABY fucked around with this message at 01:22 on Mar 22, 2010

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

attackmole posted:

Thanks dude, that'll work. Also, naming the variable range helped me think of a way to do the next part of the function really sweetly, so thanks even more.

Naming variables after builtin functions is generally a bad idea, and not recommended.

Avenging Dentist
Oct 1, 2005

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

Sailor_Spoon posted:

Naming variables after builtin functions is generally a bad idea, and not recommended.

Using range is generally a bad idea. :smug:

king_kilr
May 25, 2007

Avenging Dentist posted:

Using range is generally a bad idea. :smug:

Py3K :smug:

Avenging Dentist
Oct 1, 2005

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

king_kilr posted:

Py3K :smug:

Can anyone really be said to "use" Py3k yet?

wwqd1123
Mar 3, 2003
I have a 64bit OS and I downloaded python 3.1 64 bit. When I'm in the shell at the top it says 64bit AMD but I am using an intel processor. Is that normal? Is this optimized for AMD or something?

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

wwqd1123 posted:

I have a 64bit OS and I downloaded python 3.1 64 bit. When I'm in the shell at the top it says 64bit AMD but I am using an intel processor. Is that normal? Is this optimized for AMD or something?

x86-64 is often referred to as AMD64 since AMD made the spec and was the only implementor for years (while Intel was pushing IA64, which is basically dead from non-server use).

Adbot
ADBOT LOVES YOU

wwqd1123
Mar 3, 2003

Otto Skorzeny posted:

x86-64 is often referred to as AMD64 since AMD made the spec and was the only implementor for years (while Intel was pushing IA64, which is basically dead from non-server use).

Does that mean I should just go with the regular 32bit version on an intel?

  • Locked thread