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
leterip
Aug 25, 2004

Lister_of_smeg posted:

Just come across this little snippet of code.

code:
ret = execute(os.system, cmd)
if ret and ret != 0:
    raise Error("%s returned %d" % (cmd, ret))
Am I missing something or is that if statement a bit silly? If ret was 0 it wouldn't evaluate to true.
For any number, "if ret" implies "ret != 0", so yeah you don't need that second condition. But you can construct crazy objects that don't have that property, like
code:
class Duck(object):
    def __ne__(self, o):
        return o != 0
d = Duck()
so "if d" would evaluate to true, but "d != 0" would evaluate to false. Thus, "if d" does not imply "d != 0". Obviously this is contrived and not what's going on there (I hope), so in the case of things not specifically crafted to break your ideas, like return codes from a command (assumably numbers), you're right.

Adbot
ADBOT LOVES YOU

Reformed Pissboy
Nov 6, 2003

If execute() can return None (as subprocess.poll() does if the process hasn't completed), then that check also makes sense; otherwise a straight if ret != 0 may catch processes that are still executing :goleft:

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES

the posted:

I'm sorry, my programming knowledge is rather limited.

For what little it's worth, I followed it. However, I have a physics PhD, so chances are I think in a similiar way you do. :)

(astrophysics rules)

Awkward Davies
Sep 3, 2009
Grimey Drawer
Anyone around to answer some fairly simple questions regarding regex?

edit: nevermind, got distracted by Achewood

Awkward Davies fucked around with this message at 06:56 on Mar 3, 2012

Chimp_On_Stilts
Aug 31, 2004
Holy Hell.
I want to write a Python script that, on a Mac or Windows computer, can be double-clicked to run. It would then need to open a cmd or Terminal window to accept some user input.

Basically, I am trying to make an ultra-simple text adventure just to practice my Python skills.

I can do the text adventure bit, but I don't know how to make my *.py files into executable files that will leave a command prompt running for the user to interact with. How do I do this?

OnceIWasAnOstrich
Jul 22, 2006

Chimp_On_Stilts posted:

I want to write a Python script that, on a Mac or Windows computer, can be double-clicked to run. It would then need to open a cmd or Terminal window to accept some user input.

Basically, I am trying to make an ultra-simple text adventure just to practice my Python skills.

I can do the text adventure bit, but I don't know how to make my *.py files into executable files that will leave a command prompt running for the user to interact with. How do I do this?

py2exe and py2app can be used pretty simply to convert them into an .exe or OSX app that someone can doubleclick on.

Thermopyle
Jul 1, 2003

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

Trying to remove the scientific notation from this graph I generated with the following code.



code:
hfmt = matplotlib.dates.DateFormatter('%m/%d %H:%M')

fig = plot.figure()
ax = fig.add_subplot(111)

ax.xaxis.set_major_formatter(hfmt)

formy = plot.ScalarFormatter()
formy.set_scientific(False)
ax.yaxis.set_major_formatter(formy)

plot.plot(matplotlib.dates.epoch2num(legend), data[profile_id])
fig.autofmt_xdate(rotation=90)
plot.savefig(out_file)
I barely know what I'm doing with matplotlib, so this is all based on copy/paste from the internets. Anyone have some pointers on how to get rid of the scientific notation?

Chimp_On_Stilts
Aug 31, 2004
Holy Hell.
I'm working on some very basic text adventures because I find it's a fun way to learn. Here's the design document (:lol::lol:) for my second adventure:

code:
# My second text adventure. Intended to be a little more advanced.

# Game will be five rooms in a 1-3-1 arrangement as follows:
#
#       X
#     X X X
#       X


# Player commands:
#   Walk between rooms with N, S, E, W
#   Ask for HELP (a list of commands)
#   EXAMINE interesting objects 
#   OPEN things
#   TAKE objects and hold them in an inventory
#   LIST player inventory
#   USE an object (specifically, a key on a door)

# Win condition:
#   EXAMINE a statue in the Eastern Room to find the *Round Key*
#   TAKE the *Round Key*
#
#   OPEN a box in the Western Room
#   TAKE the *Square Key* from inside the box
#
#   USE the *Round Key* and the *Square Key* in a Door in the Southern room
#   OPEN the door
#
#   Note: ALL CAPS denotes a command, *inside asterisks* denotes an inventory item
Two questions:
1. The way I did my previous exercise, I made a player_enters() and a prompt() function for each room. The player entered, which triggered the prompt asking for a command, which allowed the player to enter a new room. Simple stuff. The player could also ask for help and open a door. When the player passed in each command via raw_input(), I had a simple if statement tree determining what to do:

code:
def promptNorth():
    cmd = raw_input("> ").lower()
    
    if cmd == "open":
        print
        obj_open()
    elif cmd == "n":
        print "You cannot go that way."
        print
        promptNorth()
    elif cmd == "s":
        roomSouth()
    elif cmd == "help":
        help()
        promptNorth()
    else:
        print "That is not a valid command. Try again."
        print
        promptNorth()
This seems sloppy as hell because, if there's a lot of commands to do, that if tree is going to get long as hell. What's a more succinct way to take player input and determine what to do with it?

2. What's the best way to keep the player's inventory with him or her between rooms? Global variables? Returning a variable value at the end of each room function then passing it to the next variable? Will I be able to use the same method to keep track of whether the keys are still waiting to be picked up or not, should the player return to the area?



I'm a beginner, I don't know how to make a class yet. Just this simple adventure will stretch my abilities a little.

duck monster
Dec 15, 2004

Hmm. I think your going about this all the wrong way. You really need to think of a more data-driven way to go about it.

Lets say we did a big array of rooms that went like this
code:

rooms = {
      'middle room': {
               'exits':{
                   'north':'north room',
                   'south':'south room',
                   'up':'the tower'
                 },
                'description':'You are in a room in the middle blah. There is a door in the roof',
                'contents': { 'yellow key':'A bright yellow key' },
                'locks': { 'up':'blue key'}
        },

      'south room': {
               'exits':{
                   'north':'middle room',
                   'down':'southern basement'
                 },
                'description':'You are in the southern room. Theres a locked basement below.',
                'contents': {  },
                'locks' :{ 'down':'yellow key' }
        },

      'north room': {
               'exits':{
                   'south':'middle room',
                 },
                'description':'You are in a room in a dull room to the north of the middle',
                'contents': { },
                'locks': { }
        },

      'the tower': {
               'exits':{
                   'down':'middle room',
                 },
                'description':'You are in the bell tower. The room smells of prizes!',
                'contents': { 'gem':'A glittering gem' },
                'locks' : { }
        },

      'southern basement': {
               'exits':{
                   'up':'south room',
                 },
                'description':'You are in a grotty basement.',
                'contents': { 'blue key':'A blue key' },
                'locks' : { }
        },

}


Right, so what we have here is a definition of a little maze that has a middle room, a north and south room, a bell tower, and a basement. To get into the basement you need a yellow key (which is in the middle room). To get into the tower you need a blue key (which is in the basement). In the tower is the gem.

We probably want to set a variable that has your location.

location = 'north room'

From here, we might define a function that returns the room, and perhaps a function that describes the room.

code:

def getRoom(location):
   return rooms[location]

def describeRoom(room):
    print "Location:"
    print room['description']
    print "Exits:"
    for exit in room['exits']:
         print exit
    if (len(room['contents']) > 0): #We dont want to do this if nothing is in the room!
	    print "Contents of room:"
	    for item in room['contents']:
	        print room['contents'][item] #Dont print the key, print the value


So you would use this as follows;

room = getRoom(location)
describeRoom(room)

Ok. So now we need to think in terms of a game loop.

Now, in this loop, we do the following;-
* get room
* display room
* get command
* see if there is an exit with the same name as your command. If so change location
* EXCEPT if there is a lock on the door!
* repeat unless the person typed "quit"

There will be more, but I'll get there in a bit;-
code:
def gameloop():
   #Initialize
   location = 'south room'
   finished = False #This is turned true if the person wants to quit!
   while finished == False:
       #Get room
       room = getRoom(location)
       #describe room
       describeRoom(room)
       #get command
       cmd = raw_input("> ").lower()
       comprehension = False # If we recognise the command this is set true
       #Is it an exit?
       for exit in room['exits']:
         if (cmd == exit):
             if room['locks'].has_key(cmd):
                   print "That is locked!"
             else:
                   location = room['exits'][exit]
                   print "You travel ",cmd
             comprehension = True
       if (cmd == 'quit'):
            finished = True
            print "Later oval office!"
            comprehension = True

        # PUT THE REST OF YOUR COMMANDS HERE!

       if (comprehension == False):
            print "I dont understand that command you DUMB gently caress!"
       
gameloop()
Right. So far so good. Now we need to deal with objects.

The first thing we need is an inventory.

So something like;-

inventory = { }

Its just a dictionary that'll contain the long name keyed to the short name of the item.

Now for actually picking up stuff, we need to look at how our commands work.
we want a command like 'take yellow key'. The command is basically verb<space>noun.

So lets split this at the first space. We only want ONE split, not more. We COULD do more, but thats a much more complex parser

tokens = cmd.split(' ',1) #This splits the command on space, but only 1 split

so token[0] is the verb and token[1] is the noun (or whatever, subject)

BUT if your only doing a one word command like "south" , then there will be NO token[1].

So with that in mind, the parser is this
code:
tokens = cmd.split(' ',1)
verb = token[0]
if len(tokens) > 1:
    noun = token[1]
Too easy.

So now we can add some more commands in. I'll paste in the full and final code, and you can find the new code using the comments. Note how I'm accessing the noun and verb variables for this. I've added a get, drop, inventory and unlock command . get <item> drop <item> inventory and unlock <direction>

code:

rooms = {
      'middle room': {
               'exits':{
                   'north':'north room',
                   'south':'south room',
                   'up':'the tower'
                 },
                'description':'You are in a room in the middle blah. There is a door in the roof',
                'contents': { 'yellow key':'A bright yellow key' },
                'locks': { 'up':'blue key'}
        },

      'south room': {
               'exits':{
                   'north':'middle room',
                   'down':'southern basement'
                 },
                'description':'You are in the southern room. Theres a locked basement below.',
                'contents': {  },
                'locks' :{ 'down':'yellow key' }
        },

      'north room': {
               'exits':{
                   'south':'middle room',
                 },
                'description':'You are in a room in a dull room to the north of the middle',
                'contents': { },
                'locks': { }
        },

      'the tower': {
               'exits':{
                   'down':'middle room',
                 },
                'description':'You are in the bell tower. The room smells of prizes!',
                'contents': { 'gem':'A glittering gem' },
                'locks' : { }
        },

      'southern basement': {
               'exits':{
                   'up':'south room',
                 },
                'description':'You are in a grotty basement.',
                'contents': { 'blue key':'A blue key' },
                'locks' : { }
        },

}


def getRoom(location):
   return rooms[location]

def describeRoom(room):
    print "Location:"
    print room['description']
    print "Exits:"
    for exit in room['exits']:
         print exit
    if (len(room['contents']) > 0): #We dont want to do this if nothing is in the room!
	    print "Contents of room:"
	    for item in room['contents']:
	        print room['contents'][item] #Dont print the key, print the value

def gameloop():
   #Initialize
   location = 'south room'
   finished = False #This is turned true if the person wants to quit!
   inventory = {}
   while finished == False:
		#Get room
		room = getRoom(location)
		#describe room
		describeRoom(room)
		#get command
		cmd = raw_input("> ").lower()
		#SPLIT INTO NOUN VERB
		tokens = cmd.split(' ',1)
		verb = tokens[0]
		if len(tokens) > 1:
	   		noun = tokens[1]
	   	#END SPLIT INTO NOUN VERB
		comprehension = False # If we recognise the command this is set true
		#Is it an exit?
		for exit in room['exits']:
			if (cmd == exit):
				if room['locks'].has_key(cmd):
					print "That is locked!"
				else:
					location = room['exits'][exit]
					print "You travel ",cmd
				comprehension = True
        
        #GET COMMAND
		if (verb == 'get'):
			if room['contents'].has_key(noun): #Is it in the room
				print "You pick up the ",noun
				#Add it to the inventory
				inventory[noun] = room['contents'][noun]
				#And remove it from the room
				del (room['contents'][noun]) #Yes del makes me nervous as well
			else:
				print "That item isnt in the room!"
			comprehension = True
        
		if (verb == 'drop'): #Do this in reverse
			if inventory.has_key(noun): #Have we got it.
				#place it in room
				room['contents'][noun] = inventory[noun]
				# delete from pocketsies
				del (inventory[noun])
			else:
				print "I aint got it!"
			comprehension = True

		if (verb == 'unlock'):
			#First see if theres an lock there
			if room['locks'].has_key(noun):
				#Ok the room is here.
				if inventory.has_key(room['locks'][noun]): #Have we the key that the lock wants?
					#Then delete the lock.
					del(room['locks'][noun])
					#When the lock is gone, the door can be traversed.
					print "The lock is gone! The door is opened!"
				else: #Dont have key
					print "I dont have the key"
			else:
				#It isnt locked.
					print "It isnt locked."
			comprehension = True

		if (cmd == 'inventory'):
			print "Inventory:"
			for item in inventory:
				print inventory[item]
			comprehension = True
        
		if (cmd == 'quit'):
		    finished = True
		    print "Later oval office!"
		    comprehension = True

        # PUT THE REST OF YOUR COMMANDS HERE!

		if (comprehension == False):
		    print "I dont understand that command you DUMB gently caress!"
	    
	    #Finally winning condition
		if inventory.has_key('gem'):
			print "CONGRATULATION YOU GOT THE GEM. GAME OVER, YOU WON A PRIZE OF GEMS"
			finished = True
				
gameloop()
In my day we'd type these loving things out of magazines. :corsair:

pointers to finish it;-
Google how to use something like simplejson to write the game data to disk.

You could probably write an editor to edit room description.

Consider using a key/value store to store command aliases.

I just wrote your game for you, and this was a very fun post to write

duck monster fucked around with this message at 14:24 on Mar 6, 2012

German Joey
Dec 18, 2004
I think he wanted to figure out how to make the game himself in order to learn by doing. =/

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES

Thermopyle posted:

Trying to remove the scientific notation from this graph I generated with the following code.



code:
hfmt = matplotlib.dates.DateFormatter('%m/%d %H:%M')

fig = plot.figure()
ax = fig.add_subplot(111)

ax.xaxis.set_major_formatter(hfmt)

formy = plot.ScalarFormatter()
formy.set_scientific(False)
ax.yaxis.set_major_formatter(formy)

plot.plot(matplotlib.dates.epoch2num(legend), data[profile_id])
fig.autofmt_xdate(rotation=90)
plot.savefig(out_file)
I barely know what I'm doing with matplotlib, so this is all based on copy/paste from the internets. Anyone have some pointers on how to get rid of the scientific notation?

Firstly, the "easy" solution would be to just edit your plot command to something like

code:
plot.plot(matplotlib.dates.epoch2num(legend),data[profile_id]/1.e4)
Which of course you can make cleaner by writing a quick line before it to normalize it how you want to, just make the Y-label say "in ten thousands" or whatever.

It doesn't appear like it will work for this range, but you can also do a semilog plot too.

A third solution is a little bit more to do why this isn't working the way it's supposed to to begin with:

It's good to be in the habit of doing everything in subplots, even if you only have 1 plot (like you're doing here). I *think* the problem is from the line formy=plot.ScalarFormatter()... I'm not sure though, I've not used that command, and I don't have something to readily test it on. Perhaps try:

code:
fig = plot.figure()
ax = fig.add_subplot(111)

hfmt = matplotlib.dates.DateFormatter('%m/%d %H:%M')
ax.xaxis.set_major_formatter(hfmt)

formy = matplotlib.ticker.ScalarFormatter()
formy.set_scientific(False)
ax.yaxis.set_major_formatter(formy)

plot.plot(matplotlib.dates.epoch2num(legend), data[profile_id])
fig.autofmt_xdate(rotation=90)
plot.savefig(out_file)

Chimp_On_Stilts
Aug 31, 2004
Holy Hell.

German Joey posted:

I think he wanted to figure out how to make the game himself in order to learn by doing. =/

Luckily, I don't know a drat thing about arrays yet, so I barely understand the example and can still learn by doing!

I kid of course - I appreciate your help tremendously Duck Monster. I am probably going to stick with my (terrible and inefficient) method on adventure #2, but you preempted my goal of using a non function base method for #3.

I just need to learn to interact with arrays.

EDIT: I just read up on arrays. Apparently they're like lists, but can only carry a uniform data type. Duck Monster, why did you use an array instead of a list?

Chimp_On_Stilts fucked around with this message at 22:34 on Mar 6, 2012

good jovi
Dec 11, 2000

'm pro-dickgirl, and I VOTE!

Chimp_On_Stilts posted:

EDIT: I just read up on arrays. Apparently they're like lists, but can only carry a uniform data type. Duck Monster, why did you use an array instead of a list?

He's not actually using the Array class (I assume that's what you were looking at). I also must assume he was just using the word array in a more general sense, meaning "a bunch of stuff".

rooms is actually a dictionary

Chimp_On_Stilts
Aug 31, 2004
Holy Hell.
I finished "ANOTHER HORRIBLE SPOOKY TEXT ADVENTURE", and boy is it horrible!. It's not supposed to be a masterpiece of interactive fiction, just a way for me to learn by doing. I had fun making it =)

Here's the problems I see with it:
- It's too long and inefficient. Using an if tree for every player action alone would probably land me in the "coding horrors" thread if I wasn't a total newbie.
- The inventory system is totally hamfisted. It uses global variables to determine what the player is holding. Furthermore, I had to write a separate if statement conclusion for every possible combination of inventory items - if there were more than 2 items, this would be insane.
- The code is probably not organized in a smart way. How would a better programmer organize this many functions? Would a better programmer avoid using so many functions in the first place?

I don't want to drop a long program right here in code tags, so download the .py from here if you want to give me some tips (and reminisce about your own newbie coding terrible mistakes!).



My next exercise I hope to move away from the if statement crap. Hopefully I can use Duck Monster's code as an example. I have no experience with libraries, so it'll be fun =)


EDIT: I see I forgot to put a reminder to "type 'help' for a list of commands" into the game. If you want to actually play the adventure, this will be helpful to know.

Chimp_On_Stilts fucked around with this message at 03:07 on Mar 7, 2012

duck monster
Dec 15, 2004

er yeah, dictionary not array. Was a bit drunk doing that post.

But my point remaims, think "data driven".

Cast_No_Shadow
Jun 8, 2010

The Republic of Luna Equestria is a huge, socially progressive nation, notable for its punitive income tax rates. Its compassionate, cynical population of 714m are ruled with an iron fist by the dictatorship government, which ensures that no-one outside the party gets too rich.

<Insert I really don't know anything disclaimer>

But wouldn't you just set up a class for rooms and plot their location on an XY axis since you're working from 4 compass points, then move would just check to see if there is a valid exit in that room and either return, "you idiot you walked into wall, go kill yourself" or edited the room location and printed out the descriptions?

You write all the checking and moving code once, then you just have to fill in the description, objects and exits and poo poo for each room.

Also dictionaries are the best thing ever.

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES
So here's a dumb question. I often times deal with huge arrays and I want to run them many, many times quickly for data sets that can change over the course of the program. For example, if I have a small data table like:

code:
time counts
1   10
2   35
3   22
4   73
5   12
6   95
So lets say I'm running something where not only the counts but the time bin sizes can change depending on what I'm doing. I want the code to be able to tell me exactly where counts=95 or what's the value at time=5. I can't just index it for one case because it will be different every loop. For cases like this, I just reuse a simple function I wrote years ago that works much like Excel's Lookup:

code:
def lookup(value,array,array2=None):                          
        idx=(num.abs(array-value)).argmin()
        if array2=None:
            return idx
        else:
            return array2[idx]:
The stupid question part is - surely there's a built-in function to do this that I just don't know about. What could it be?

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
That would work as long as your map layout is a two dimensional grid. For anything beyond that (step into teleporter, fall down giant hole, dennis), you're going to need to add custom code. It's just easier to have a mapping of exits to room IDs for each room, and it's not that much more code.

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES

Cast_No_Shadow posted:

<Insert I really don't know anything disclaimer>

But wouldn't you just set up a class for rooms and plot their location on an XY axis since you're working from 4 compass points, then move would just check to see if there is a valid exit in that room and either return, "you idiot you walked into wall, go kill yourself" or edited the room location and printed out the descriptions?

You write all the checking and moving code once, then you just have to fill in the description, objects and exits and poo poo for each room.

Also dictionaries are the best thing ever.

I don't know a whole lot about coding for heavily UI situations, but my intitial reaction to this, from a speed standpoint, is that you're going to have an awfully empty map if you're going to actually grid out an entire "zone" in a mud or something.

Suspicious Dish posted:

That would work as long as your map layout is a two dimensional grid. For anything beyond that (step into teleporter, fall down giant hole, dennis), you're going to need to add custom code. It's just easier to have a mapping of exits to room IDs for each room, and it's not that much more code.

Isn't that how CircleMUD was coded? It's been damned near 15 years since I looked at the code for that, but I was pretty sure that's how all those things worked.

Nippashish
Nov 2, 2005

Let me see you dance!

JetsGuy posted:

So lets say I'm running something where not only the counts but the time bin sizes can change depending on what I'm doing. I want the code to be able to tell me exactly where counts=95 or what's the value at time=5. I can't just index it for one case because it will be different every loop. For cases like this, I just reuse a simple function I wrote years ago that works much like Excel's Lookup:

The stupid question part is - surely there's a built-in function to do this that I just don't know about. What could it be?

You can use boolean arrays as indexes, so "what's the count at time == 5" can be written as counts[time==5]. To get the indices where counts==95 you can say i, = np.nonzero(counts==95). (The comma on the LHS unpacks the tuple returned by np.nonzero. If counts was n x m you'd do i,j = np.nonzero(counts==95)).

Both of these return all the values which match the condition, unlike your version which returns only the first match. Returning all the matches means they immediately generalize to things like counts[np.logical_and(3 <= time, time < 10)].

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES

Nippashish posted:

You can use boolean arrays as indexes, so "what's the count at time == 5" can be written as counts[time==5]. To get the indices where counts==95 you can say i, = np.nonzero(counts==95). (The comma on the LHS unpacks the tuple returned by np.nonzero. If counts was n x m you'd do i,j = np.nonzero(counts==95)).

Both of these return all the values which match the condition, unlike your version which returns only the first match. Returning all the matches means they immediately generalize to things like counts[np.logical_and(3 <= time, time < 10)].

Interesting, thanks! I originally intended for my version to return the *closest* match, which I think argmin() does, but maybe I have a bug I'm not even aware of.

This is much nicer though, and can be written in line. Thanks!

Thermopyle
Jul 1, 2003

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

Evolution of the Python programmer:

https://gist.github.com/289467

duck monster
Dec 15, 2004

Thermopyle posted:

Evolution of the Python programmer:

https://gist.github.com/289467

code:
def new(cls, *args, **kwargs):
    return cls(*args, **kwargs)
lol.

I would have called it the "java" python programmer, but "enterprise" works haha.

etcetera08
Sep 11, 2008

Thermopyle posted:

Evolution of the Python programmer:

https://gist.github.com/289467

Ahahahaha, amazing.

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES
Reminded me of this, which I'm sure many of you have seen before. (gently caress Cpp forever)

http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.html

vikingstrike
Sep 23, 2007

whats happening, captain
I feel dumb asking this, but can someone explain what all is going on here? (it's from the link above)

code:
f = lambda x: x and x * f(x - 1) or 1
I've never really used lambda functions before, which may be part of the problem.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
f = lambda x: ... is (in this case) equivalent to def f(x): return .... x and y returns y if x evaluates to true, and false otherwise (which is equivalent to boolean and if they're both bools, and more useful if they aren't). x or y returns x if it's true, and y otherwise. As such, the body of the lambda is equivalent to
code:
if x:
    return x * f(x - 1)
else:
    return 1

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES
I've always been mystified by lambda because I've seen it in a few people's python code and I'm just not entirely sure I understand the benefit of using it.

People have claimed it helps you in that you can use a function without defining it (and something about memory and speed here).

For the purposes of scientific programming, generally the thing that kills me more often that not for "speed" is number of iterations I have to run before I worry about things like memory. I've never had to do high-end simulations like my colleagues down the hall though.

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug
There are a few legitimate situations where it's useful to have a short function without a name. The key argument to sorted comes to mind:

code:
In [1]: class Thing:
   ...:     def __init__(self, string, number):
   ...:         self.string = string
   ...:         self.number = number
   ...:     def __repr__(self):
   ...:         return '<Thing {} {}>'.format(self.string, self.number)
   ...:     

In [2]: t1 = Thing('yes', 4)

In [3]: t2 = Thing('no', 6)

In [4]: t3 = Thing('butts', 3)

In [5]: l = [t1, t2, t3]

In [6]: l
Out[6]: [<Thing yes 4>, <Thing no 6>, <Thing butts 3>]

In [7]: sorted(l, key=lambda thing: thing.number)
Out[7]: [<Thing butts 3>, <Thing yes 4>, <Thing no 6>]

In [8]: sorted(l, key=lambda thing: thing.string)
Out[8]: [<Thing butts 3>, <Thing no 6>, <Thing yes 4>]

vikingstrike
Sep 23, 2007

whats happening, captain

Plorkyeran posted:

f = lambda x: ... is (in this case) equivalent to def f(x): return .... x and y returns y if x evaluates to true, and false otherwise (which is equivalent to boolean and if they're both bools, and more useful if they aren't). x or y returns x if it's true, and y otherwise. As such, the body of the lambda is equivalent to
code:

if x:
    return x * f(x - 1)
else:
    return 1

Thanks for this!

Reformed Pissboy
Nov 6, 2003

I'm guilty of abusing lambda to feed a callable to a function expecting one with different arguments. For example, with PyQt a button's clicked() signal (call) will only connect to a slot (callable) with no arguments. So you can do:
code:
def hi():
    print "A button was clicked"

button.clicked.connect( hi ) # on click, calls `hi()`
But not:
code:
def hi(button_name): # 1 required arg
    print "A button was clicked, it was %s" % (button_name,)

button.clicked.connect( hi ) # on click, still calls `hi()` w/ 0 args -- TypeError!
But you CAN do:
code:
def hi(button_name):
   print "A button was clicked, it was %s" % (button_name,)

button.clicked.connect( lambda: hi("button") ) # on click, calls `<lambda>()`
Then when that lambda() is called, it executes its body, hi("button") as we wanted for some silly reason all along. It's a little dirty and I feel like a bad person, but it's more fun than writing a specific named function for every single signal you may want to handle :shobon:

Eliza
Feb 20, 2011

I have used lambdas to hand functions to bullet pathways in a small shmup. I could use it as a standard argument for a function call and then just memorise and call it.
I guess I could have used an object containing the respective functions too, but it felt fancy just keeping it in a variable.

As I understand it, lambdas mainly serve as a kind of syntactic sugar so you don't have to move one-liner throwaway functions away from a potentially larger method, and as such out of direct sight.

Suspicious Dish
Sep 24, 2011

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

Harm Barn Gumshoe posted:

code:
def hi(button_name):
   print "A button was clicked, it was %s" % (button_name,)

button.clicked.connect( lambda: hi("button") ) # on click, calls `<lambda>()`

code:
from functools import partial

def hi(button_name):
   print "A button was clicked, it was %s" % (button_name,)

button.clicked.connect(partial(hi, "button"))

Reformed Pissboy
Nov 6, 2003

Suspicious Dish posted:

code:
from functools import partial

def hi(button_name):
   print "A button was clicked, it was %s" % (button_name,)

button.clicked.connect(partial(hi, "button"))

Huh, I never knew about this! The (better) support for *args/**kwargs and introspection is really nice :kiddo:

etcetera08
Sep 11, 2008

So in honor of Pycon going on right now, does anyone have recommendations for old Pycon talks that are available online? I've gotten in the habit of watching talks/lectures over the past couple weeks but haven't watched anything Python-specific except for Guido talking about the history of the language to the Dropbox staff:
https://www.youtube.com/watch?v=ugqu10JV7dk

Suspicious Dish
Sep 24, 2011

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

etcetera08 posted:

So in honor of Pycon going on right now, does anyone have recommendations for old Pycon talks that are available online? I've gotten in the habit of watching talks/lectures over the past couple weeks but haven't watched anything Python-specific except for Guido talking about the history of the language to the Dropbox staff:
https://www.youtube.com/watch?v=ugqu10JV7dk

How to Write Obfuscated Python is great for the novelty.

geonetix
Mar 6, 2011


Lysidas posted:

There are a few legitimate situations where it's useful to have a short function without a name. The key argument to sorted comes to mind:

For your example they made the attrgetter function in operator, so you can do things like

code:
from operator import attrgetter

class Blah(object):
     def __init__(self, name):
        self.name = name

things = [Blah('zyx'), Blah('abc'), Blah('xyz')]
print sorted(things, key=attrgetter('name'))
Not much of a change, but lambda's are not the way to go in that situation, since 2.4 at least.

Thermopyle
Jul 1, 2003

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

JetsGuy posted:

Firstly, the "easy" solution would be to just edit your plot command to something like

code:
plot.plot(matplotlib.dates.epoch2num(legend),data[profile_id]/1.e4)
Which of course you can make cleaner by writing a quick line before it to normalize it how you want to, just make the Y-label say "in ten thousands" or whatever.

It doesn't appear like it will work for this range, but you can also do a semilog plot too.

A third solution is a little bit more to do why this isn't working the way it's supposed to to begin with:

It's good to be in the habit of doing everything in subplots, even if you only have 1 plot (like you're doing here). I *think* the problem is from the line formy=plot.ScalarFormatter()... I'm not sure though, I've not used that command, and I don't have something to readily test it on. Perhaps try:

code:
fig = plot.figure()
ax = fig.add_subplot(111)

hfmt = matplotlib.dates.DateFormatter('%m/%d %H:%M')
ax.xaxis.set_major_formatter(hfmt)

formy = matplotlib.ticker.ScalarFormatter()
formy.set_scientific(False)
ax.yaxis.set_major_formatter(formy)

plot.plot(matplotlib.dates.epoch2num(legend), data[profile_id])
fig.autofmt_xdate(rotation=90)
plot.savefig(out_file)

Unfortunately, this didn't change anything. I can't figure out why. :/

spankweasel
Jan 4, 2006

Back home from PyCon. For those of you that missed out, it was pretty freakin' awesome. Lots of real good conversations were had to go with the excellent tutorials and amazing talks.

m0nk3yz - thank you for doing this every year. I've been to two now, and as long as I'm able to do so, I'll continue attending. Seriously, awesome job.

Adbot
ADBOT LOVES YOU

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES

Thermopyle posted:

Unfortunately, this didn't change anything. I can't figure out why. :/

It may be that it's interpreted the same way. Is it possible for you to send me your y-axis data (or post it)? If not, I'll just make some poo poo up.

I do not have time right now to do it, but I promise I'll look at it sometime (probably the end of the week) and try to give you a much more definitive answer as to what is going wrong.

  • Locked thread