Re: [Tutor] calling a method within a function
I understand... but don't blame me if it hurts your head ;) The class is here: http://python.pastebin.com/gPpep50Y The function is here: http://python.pastebin.com/faK0vZ8U The issue is with the 'reflectance' method of the FlightData class (line 76). You can see in the class definition I now just add reflectance to self, but before I was trying to return it, and in the function (line 38-40) I was calling the method to get the array. On Ipython it worked fine to call the method and get a refl array. The array worked as expected (ie. refl.max(), refl.min() returned floats). But when I passed the same FlightData object to the function and called it inside it would not work. It would still return a numpy.ma.core.MaskedArray, but the max and min methods on the array returned empty values, which caused my function to crash. On Wed, Dec 8, 2010 at 2:18 AM, Alan Gauld alan.ga...@btinternet.com wrote: John washa...@gmail.com wrote I have a strange problem with a piece of code I've written. It's a bit overly complicated to make an example with, but the gist is below. But in the example below, it works. However, in my example, when I call the method from within the function, it returns something other than what I expect. Care to give us a clue? What did you expect? What did you get? What does the real code look like? Its a bit hard to diagnose your problem based on a bit of code that works and a loose description of your dissapointment with another bit of code that may or may not work - depending on what you expected! -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - tu...@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor -- Configuration `` Plone 2.5.3-final, CMF-1.6.4, Zope (Zope 2.9.7-final, python 2.4.4, linux2), Python 2.6 PIL 1.1.6 Mailman 2.1.9 Postfix 2.4.5 Procmail v3.22 2001/09/10 Basemap: 1.0 Matplotlib: 1.0.0 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] calling a method within a function
I understand... but don't blame me if it hurts your head ;) First a few comments. Theres an awful lot of superfluous stuff in there that would make it much easier to read and work with. The docstring does not appear to be accurate and there are about 30 lines of commented code. Do you use a version control, system? That would avoid the need for all of that commenting. Even so the function is very long and could be easily broken into smaller, more maintainable chunks that would help you diagnose and manage problems more effectively. In the class you assifn self to D in init? If its just to avoid some typing you could just use D instead of self in the parameter list. The use of self is just a convention. However, for the sake of 3 characters I personally think its a convention worth following... However, to your problem,... The class is here: http://python.pastebin.com/gPpep50Y The function is here: http://python.pastebin.com/faK0vZ8U The issue is with the 'reflectance' method of the FlightData class (line 76). You can see in the class definition I now just add reflectance to self, but before I was trying to return it, and in the function (line 38-40) I was calling the method to get the array. The reflectance method does not return anything, it will set your value to None. HTH, Alan G. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python vs. MATLAB
Hi, Hugo ! Excellent explanation. Thank you. All the best, hilton On Mon, Dec 6, 2010 at 5:05 PM, Hugo Arts hugo.yo...@gmail.com wrote: On Mon, Dec 6, 2010 at 6:09 PM, Joel Schwartz j...@joelschwartz.com wrote: Chris, Can you say more about number (7) in your list? What does pass by value mean and what are the alternatives? Thanks, Joel Generally, pass-by-* refers to how the arguments to functions are treated. * In call-by-value, the value of the arguments are copied into the function. There is no way to modify variables outside of the function since you don't have access to them, only to copies. C uses this, among many others: int a = 5 void func(int b) { b = 6; } func(a); a == 5; /* evaluates to true, variable outside function scope remains unchanged */ The value b, inside the function, contains a copy of a. So when it is modified, the original a remains unchanged. * in call-by-reference, the function is given implicit *references* to its arguments. When modifying the variables inside of the function, the variable outside is also changed. you can simulate it in many languages by passing an expicit reference rather than an implicit one (such as C's pointers): int a = 5 void func(int * b) { *b = 6; } func(a); a == 6; /* evaluates to true. the function was able to modify a variable outside of its scope */ * python uses something that wikipedia calls call-by-sharing. It is not call-by-value, nor is it call-by-reference. It means, in short, that while the function has access to the callers, *values*, it does NOT have access to the callers *variables*. To demonstrate: a = [] def f(b): b.append(1) b = [2] f(a) print a # prints [1] As in pass-by-reference, the function f could modify it's callers values by appending 1 to the list. However, unlike *real* pass-by-reference, when trying to *re-assign* the variable into something entirely different, there was no effect (a did not become equal to [2]). Many people call python pass-by-reference, even though this is technically incorrect. The difference comes from the semantics of variables and values. In languages such as C, a variable is an area of memory that contains something. An assignment then, copies the value on the right into the variable (memory) on the left. python doesn't have variables, but names. a name is essentially itself a reference to some *object* that lives somewhere in memory. An assignment is something completely different in this context, it merely sets the reference (variable) on the left to *point to* the object on the right. So, when evaluating function arguments, names inside the function are set to point to the *objects* supplied as arguments, (not to names!). Since we don't have access to the caller's names, python is not a true pass-by-reference language. for more on why python is neither call-by-value nor call-by-reference: http://effbot.org/zone/call-by-object.htm for more on python's variable semantics and how it differs from languages like C: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variableshttp://python.net/%7Egoodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables Hugo ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python vs. MATLAB
On Wed, Dec 8, 2010 at 7:52 PM, Hilton Fernandes hgfer...@gmail.com wrote: Hi, Hugo ! Excellent explanation. Thank you. All the best, hilton Haha, well, at least someone noticed my explanation. I should probably refer you to Steven's dissertation of same, though, I think most would prefer it to mine. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Feedback on coding style
Hi. For the past week, I've been following an online Python guide named: 'Learn Python the Hard Way'. I'm very happy with it as it gives a lot of freedom to explore. However, due to this I have no idea if I'm thinking the right way. That's why I've attached a script of mine I've been working on all day. It works a 100%, but I'm afraid I've made very bad choices concerning design and coding style. (If it could've been much simpler, if there are glaring mistakes, poor methods, ..) Could anyone be so friendly as to offer a bit of feedback, to a newbie? PS: The script very simple accepts 2 arguments from the commandline. First arg being the number to which should be counted, second arg being the interval. Thank you, Adrian #!/usr/bin/env python # Made with python2.7 from sys import argv from sys import exit script, maxnumber, increment = argv maxnumber = int(maxnumber) increment = int(increment) jibjab = 0 numbers = [] askchange = 1 # The script goes as following: # When you start it and give two arguments, check_OP_size # checks wether you won't get too much output. # If you PASS the test, you're immediately sent to the main # function (the_loop, which is performing the actualy goal # of the script). If you FAIL you're sent to ask_change. # ask_change() notifies you that you're going to get # a lot of output and optionally lets you change your arguments. # You're then sent to choice_result which check if your response # is a valid response (e.g. Y/N). If it's not, you're sent to # jibjab_result that gives you 3 chances to type in Y/N. # If you fail typing Y/N three times, the app quits. # If you make it however, you're sent to: change_vars. # Of course, change_vars also immediately sends you to check_OP_size # to check for OP size. # ANY COMMENTS WELCOME AT howit...@archlinux.us def check_OP_size(maxn, incr): global choice, maxnumber, increment if maxn / incr 10: ask_change() if maxn / incr = 10: the_loop(maxnumber, increment) def ask_change(): global choice, maxnumber, increment print You will recieve a lot of output.\nDo you wish to change your data? choice = raw_input(Y/N: ) choice_result() def jibjab_result(): global choice, jibjab if jibjab 2: jibjab += 1 choice = raw_input(Y/N: ) choice_result() elif jibjab = 2: print Idiot. exit() def choice_result(): global choice, maxnumber, increment if choice == Y: change_vars() elif choice == N: the_loop(maxnumber, increment) else: jibjab_result() def change_vars(): global maxnumber, increment maxnumber = raw_input(Give a new max number: ) increment = raw_input(Give a new increment: ) maxnumber = int(maxnumber) increment = int(increment) check_OP_size(maxnumber, increment) #the_loop(maxnumber, increment) def the_loop(maxn, incr): Advances a number with the supplied increment untill it has reached the passed maximum number. maxn = int(maxn) incr = int(incr) i = 0 #for i in range( 0, maxn, incr): while i maxn: print At the top i is %d % i numbers.append(i) i = i + incr print Numbers now: , numbers print At the bottom i is %d % i check_OP_size(maxnumber, increment) print The numbers: for num in numbers: print num, ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python vs. MATLAB
Hi, Hugo ! Never mind that: it is usual that people in lists pay attention to usual posters. Your explanation was clear and straightforward, however it was also short. At least for the time being, i don't need any other document to teach me Python parameter passing semantics. All the best, hilton On Wed, Dec 8, 2010 at 5:04 PM, Hugo Arts hugo.yo...@gmail.com wrote: On Wed, Dec 8, 2010 at 7:52 PM, Hilton Fernandes hgfer...@gmail.com wrote: Hi, Hugo ! Excellent explanation. Thank you. All the best, hilton Haha, well, at least someone noticed my explanation. I should probably refer you to Steven's dissertation of same, though, I think most would prefer it to mine. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Feedback on coding style
On Wed, Dec 8, 2010 at 8:11 PM, howit...@archlinux.us wrote: Hi. For the past week, I've been following an online Python guide named: 'Learn Python the Hard Way'. I'm very happy with it as it gives a lot of freedom to explore. However, due to this I have no idea if I'm thinking the right way. That's why I've attached a script of mine I've been working on all day. It works a 100%, but I'm afraid I've made very bad choices concerning design and coding style. (If it could've been much simpler, if there are glaring mistakes, poor methods, ..) Could anyone be so friendly as to offer a bit of feedback, to a newbie? I like that you've divided the program up into functions, this is A Good Thing(TM). It made it much easier for me to understand what is going on, so keep doing that. little nitpick (maybe not *so* little), your functions are mutually recursive. This is a difficult word that basically means that they are all calling each other in a cycle that is potentially endless. In this case, the cycle goes like this: check_OP_size - ask_change - choice_result - change_vars - check_OP_size. You see that if I keep inputting the right things, I can go through this cycle endlessly. In this case, it's not a big problem, because no one is likely to do that for long enough to cause problems, but if another part of your program is doing the inputting, it can go wrong quickly. Why? Because functions can't call each other indefinitely. Try running this example: def f(): f() f() This is a function that keeps calling itself, the simplest possible cycle. It gives you an error maximum recursion depth exceeded. There are reasons for this, and you should learn about recursion and the call stack at some point, but that is another long essay. For now it is enough to know that recursion is something to be careful with, as there is a limit to how many functions can call each other. Second, you're using globals too much. Functions should rely as much as possible on their arguments, and nothing else. I can count the number of times I needed the global statement on one hand, and I've programmed a lot of python. Globals make your program difficult to follow, because you can't clearly see where the data is coming from and going to. Rather than having your functions communicate through global variables, you should have them communicate through function arguments and return values. See if you can write a version without the global statements. There are a few other little things. The two if statements in check_OP_size can be rewritten into an if/else statement, since the two checks are complementary (one of them will always be true). The while loop in the_loop is a little overcomplicated (you had the right idea with the commented out range call). Lastly, the program could've been written a lot more succinctly, but this will come with time and practice. Writing code is hard, and getting a feel for how to divide up your functions and how to express yourself in python most naturally will take time and practice. I'd say you're on the right track, and if you get rid of all the globals you'll be well on your way to becoming an excelling python programmer. If you need any more help, let us know. Hugo ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Feedback on coding style
On 01/-10/-28163 02:59 PM, howit...@archlinux.us wrote: Hi. For the past week, I've been following an online Python guide named: 'Learn Python the Hard Way'. I'm very happy with it as it gives a lot of freedom to explore. However, due to this I have no idea if I'm thinking the right way. That's why I've attached a script of mine I've been working on all day. It works a 100%, but I'm afraid I've made very bad choices concerning design and coding style. (If it could've been much simpler, if there are glaring mistakes, poor methods, ..) Could anyone be so friendly as to offer a bit of feedback, to a newbie? PS: The script very simple accepts 2 arguments from the commandline. First arg being the number to which should be counted, second arg being the interval. Thank you, Adrian I agree with Hugo, probably on all his points. But to help you fix it, I think I can help you a bit as well. First is I think you're misunderstanding the purpose of a function. A function should be a self-contained piece of code that gets called, and that returns when done. You're using them mostly as a way to implement what BASIC used to have as a GOTO. For example, when a loop is needed, you do it by calling another function which calls the first one. That is called recursion if it's done on purpose, and a bug if it happens by accident. Second is that you're misusing global variables. A function needs to be called with those values it needs to do its work, and it needs to return the results of that work. Very seldom should those things be globals. Start with the first function. You declare it with maxn and incr as parameters, and you call it correctly. But it also uses the globals, rather than using the ones passed in. Then the function ask_change(). You should be passing it the two arguments, and getting back modified arguments as return values. And the function shouldn't call the_loop() itself, it should just get the new values. jibjab_result() is trying to be a loop, by effectively calling itself, through choice_result(). If you need a loop, just write one. And that loop will probably be in ask_change(), without needing any other functions inside. It's good to decompose a problem into functions, but you're not using functions in the way they're designed. For small problems, this can work, but as the problems get more complex, you'll be forced to change your habits. DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Which non SQL Database ?
On Sat, 4 Dec 2010, Jorge Biquez wrote: What would do you suggest to take a look? If possible available under the 3 plattforms. I would second the use of SQLite. It's built into Python now, on all platforms. But you specified non SQL, so one other thing I'd suggest is to just create the data structure you need in Python and use pickle to save it. I recently had an exercise of recovering files from a damaged hard drive. The problem is, it recovered a lot of legitimately deleted files along with the recovered live files. All the files had generic names, with only filetypes to guide me for content, like 028561846.avi instead of descriptive names. I wrote a program to read every single one of these files and determine its MD5 checksum; I stored the results in a dictionary. The key to the dictionary was the checksum; and the value was a list of files that had that checksum; the list was usually, but not always, only one element. Then I pickled that dictionary. In another program, I ran os.walk against my archive CDROMs/DVDRROMs, or some other directories on my hard drive, finding the MD5 of each file; and if it corresponded to a rescued file, it deleted the rescued file. Ideally, I would have also updated the dictionary to drop the files I'd cleaned up, and at the end of processing, re-pickle the edited dictionary; but that wasn't an option as I usually had 2 or 3 instances of the program running simultaneously, each processing a different directory of CD/DVD. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] role playing game - help needed
Peter, Thanks for the advice as to how to use numbers. I had learned this before but the example in the documentation didn't use 'int' so I thought I didn't need to when using dictionary values. Anyway, I finally finished the program. I am sure it isn't the most efficient code and I suspect I should have used the 'while' loop earlier, but the bottom line is it seems to work. I will paste what I came up with in case anyone is interested. Thanks again to everyone. I couldn't have done it wothout you. -Al # character creator / role playing game # have 30 total points to work with # set variables attributes = {strength: 0, health: 0, wisdom: 0, dexterity: 0} MAX_POINTS = int(30) keys = attributes.keys() values = attributes.values() list (values) print( Welcome to Quest. The goal of the game is to help our hero achieve his mission. He will need strength, health, wisdom and dexterity to survive. You will have 30 points to 'spend' on these attributes. Use them wisely. His life depends on it. ) attributes[strength] = int(input(\nHow many points do you want to assign to strength?: )) attributes[health] = int(input(\nHow many points do you want to assign to health?: )) attributes[wisdom] = int(input(\nHow many points do you want to assign to wisdom?: )) attributes[dexterity] = int(input(\nHow many points do you want to assign to dexterity?: )) #point allocation point_total = 0 for val in values: point_total += val print (\nThis is how you have chosen to allocate your 30 points.) print (\nStrength:,(attributes[strength])) print (Health:, (attributes[health])) print (Wisdom:, (attributes[wisdom])) print (Dexterity:, (attributes[dexterity])) available_points = (MAX_POINTS) - (point_total) while point_total != : if point_total 30: print (\nYou have gone over your alloted 30 points.) print (Please re-enter your choices. ) attributes[strength] = int(input(\nHow many points do you want to assign to strength?: )) attributes[health] = int(input(\nHow many points do you want to assign to health?: )) attributes[wisdom] = int(input(\nHow many points do you want to assign to wisdom?: )) attributes[dexterity] = int(input(\nHow many points do you want to assign to dexterity?: )) #point allocation point_total = 0 for val in values: point_total += val print (\nThis is how you have chosen to allocate your 30 points.) print (\nStrength:,(attributes[strength])) print (Health:, (attributes[health])) print (Wisdom:, (attributes[wisdom])) print (Dexterity:, (attributes[dexterity])) available_points = (MAX_POINTS) - (point_total) continue else: break print (\nYou have, available_points, points left.) print (\nSince you have points left over, you may reallocate your points or begin your quest.) choice = int(input(\nTo reallocate, press 1. To begin, press 2: )) while choice != : if choice == 1: print (Please re-enter your choices. ) attributes[strength] = int(input(\nHow many points do you want to assign to strength?: )) attributes[health] = int(input(\nHow many points do you want to assign to health?: )) attributes[wisdom] = int(input(\nHow many points do you want to assign to wisdom?: )) attributes[dexterity] = int(input(\nHow many points do you want to assign to dexterity?: )) #point allocation point_total = 0 for val in values: point_total += val print (\nThis is how you have chosen to allocate your 30 points.) print (\nStrength:,(attributes[strength])) print (Health:, (attributes[health])) print (Wisdom:, (attributes[wisdom])) print (Dexterity:, (attributes[dexterity])) available_points = (MAX_POINTS) - (point_total) print (\nYou have, available_points, points left.) print (\nSince you have points left over, you may reallocate your points or begin your quest.) choice = int(input(\nTo reallocate, press 1. To begin, press 2: )) elif choice == 2: break else: continue print (You are now ready to begin your quest. Good luck.) input (\n\nPress the enter key to continue.\n) On Tue, Dec 7, 2010 at 5:29 PM, Peter Otten __pete...@web.de wrote: Al Stern wrote: I used the following code and got the following error. The result of input is always a string. attributes[strength] = input(\nHow many points do you want to assign to strength?: ) Say you type 42 when you run your script. Then the above assignment is effectively attributes[strength] = 42 and when you loop over the values you try to add a string to an integer which is what Python complains about: 42 + 42 Traceback (most recent call last): File stdin, line 1, in module TypeError: unsupported operand type(s) for +: 'int' and 'str' To get an integer you have to convert the string explicitly: 42 + int(42) 84 The best place to do that is as early as possible, even before you put the value into the dictionary:
Re: [Tutor] role playing game - help needed
Al Stern albst...@gmail.com wrote Anyway, I finally finished the program. I am sure it isn't the most efficient code and I suspect I should have used the 'while' loop earlier, Some things to think about below. attributes = {strength: 0, health: 0, wisdom: 0, dexterity: 0} MAX_POINTS = int(30) keys = attributes.keys() values = attributes.values() you don't need keys and values as variables because you can always fetch them from atttributes as needed. list (values) This converts values into a list, which it already is, then throws it away. I suspect you think its doing something else?. attributes[strength] = int(input(\nHow many points do you want to assign to strength?: )) attributes[health] = int(input(\nHow many points do you want to assign to health?: )) attributes[wisdom] = int(input(\nHow many points do you want to assign to wisdom?: )) attributes[dexterity] = int(input(\nHow many points do you want to assign to dexterity?: )) One of the advantages of using a dict is that you can use a loop here and thus easily extend your data in the futire without changing the input/output code: for name in attributes.keys(): attributes[name] = int( input(How many points do you want to assign to %s % name) ) #point allocation point_total = 0 for val in values: point_total += val point_total = sum( attributes.values() ) print (\nThis is how you have chosen to allocate your 30 points.) print (\nStrength:,(attributes[strength])) print (Health:, (attributes[health])) print (Wisdom:, (attributes[wisdom])) print (Dexterity:, (attributes[dexterity])) And as above this can be a loop: for name in attributes.keys(): print(\n, name, :, attributes[name] ) available_points = (MAX_POINTS) - (point_total) No need for any of the parentheses here while point_total != : You are comparing point_total to a string, but point_total is a number. You need to be careful about keeping your data types consistent. if point_total 30: print (\nYou have gone over your alloted 30 points.) print (Please re-enter your choices. ) #point allocation point_total = 0 for val in values: point_total += val again, use sum() print (\nThis is how you have chosen to allocate your 30 points.) print (\nStrength:,(attributes[strength])) print (Health:, (attributes[health])) print (Wisdom:, (attributes[wisdom])) print (Dexterity:, (attributes[dexterity])) available_points = (MAX_POINTS) - (point_total) continue else: break The logic here could be simplified into while point_total 30: print (\nYou have, available_points, points left.) print (\nSince you have points left over, you may reallocate your points or begin your quest.) choice = int(input(\nTo reallocate, press 1. To begin, press 2: )) while choice != : Again comparing to a string but you have made choice an integer if choice == 1: print (Please re-enter your choices. ) attributes[strength] = int(input(\nHow many points do you want to assign to strength?: )) attributes[health] = int(input(\nHow many points do you want to assign to health?: )) attributes[wisdom] = int(input(\nHow many points do you want to assign to wisdom?: )) attributes[dexterity] = int(input(\nHow many points do you want to assign to dexterity?: )) #point allocation point_total = 0 for val in values: point_total += val Note, you haven't actually assigned anything to values since the user entered the new data. This is another reason it would be better to not have the variable, just get values directly from attributes on demand. HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor