|
Hi there .... I've just joined this list and thought I'd introduce
myself. I used to be fairly competent in c but never made the grade to c++. I've done very little programming in the last couple of years or so. I'm getting a Raspberry-pi for our local Junior school and am starting to learn Python so I can show the year five and year six kids how to write simple games. I'm already enjoying this lovely language. One of the few c things I miss is the switch/case statement. if and elif in it's place is a bit cumbersome. Still, it works. One of the things I wanted to do is to use a four integer array to get four integers returned from a function. I ended up using what I think is a list. (I'm not really sure of the datatypes yet). This is what I did, and it works, but looks very inelegant to me: correct = 0 match = 0 wrong = 0 results = [correct, match, wrong] results = getflag(flag_1, results) results = getflag(flag_2, results) results = getflag(flag_3, results) results = getflag(flag_4, results) Any thoughts? Kind regards, Barry. -- From Barry Drake - a member of the Ubuntu advertising team _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
On 30/03/12 15:04, Barry Drake wrote:
> One of the things I wanted to do is to use a four integer array to get > four integers returned from a function. I ended up using what I think > is a list. (I'm not really sure of the datatypes yet). This is what I > did, and it works, but looks very inelegant to me: > > correct = 0 > match = 0 > wrong = 0 > results = [correct, match, wrong] > > results = getflag(flag_1, results) > results = getflag(flag_2, results) > results = getflag(flag_3, results) > results = getflag(flag_4, results) Sorry - I meant three-digit array, and the indents in the code fragment above were all in line originally. -- From Barry Drake is part of the Ubuntu advertising team. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Barry Drake-2
Hi and welcome Barry,
> One of the things I wanted to do is to use a four integer array to get four integers returned from a function. I ended up using what I think is a list. (I'm not really sure of the datatypes yet). This is what I did, and it works, but looks very inelegant to me: > > correct = 0 > match = 0 > wrong = 0 > results = [correct, match, wrong] > > results = getflag(flag_1, results) > results = getflag(flag_2, results) > results = getflag(flag_3, results) > results = getflag(flag_4, results) > > Any thoughts? Not sure. In the sense that you can "optimise" (refactor) it in the same way you could do with C. Eg: results = [0, 0, 0] flags = [0, 1, 2, 3] for flag in flags: results = getflag(flag, results) I skipped the constant variables, but that should be clear. The only non-C thing here is the loop, but I would think that's pretty clear. Note that flag takes on integer values here of course. It could probably be done even more fancy/Pythonic, but I don't think there's a reason to do that. Of course, depending on the getflag function itself, you may be able to rewrite things differently, but that's for another question I guess. Cheers, Evert ps: I was going to comment on the indentation, but then spotted your other email. I am going to comment on the subject line though ;-), because that's not related to your actual question. A relevant subject helps a lot, among others for web searches from other people later one. > Kind regards, Barry. > > -- > From Barry Drake - a member of the Ubuntu advertising team > > _______________________________________________ > Tutor maillist - [hidden email] > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Barry Drake-2
On 30/03/2012 15:13, Barry Drake wrote:
> On 30/03/12 15:04, Barry Drake wrote: >> One of the things I wanted to do is to use a four integer array to get >> four integers returned from a function. I ended up using what I think >> is a list. (I'm not really sure of the datatypes yet). This is what I Please read the tutorial if you haven't done so already at http://docs.python.org/tutorial/index.html >> did, and it works, but looks very inelegant to me: >> >> correct = 0 >> match = 0 >> wrong = 0 >> results = [correct, match, wrong] Usually written results = [0, 0, 0] or even results = [0] * 3 >> >> results = getflag(flag_1, results) >> results = getflag(flag_2, results) >> results = getflag(flag_3, results) >> results = getflag(flag_4, results) How is getflag defined and what are flag_1/2/3/4 ? > > Sorry - I meant three-digit array, and the indents in the code fragment > above were all in line originally. > -- Cheers. Mark Lawrence. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Evert Rol
On 30/03/12 16:19, Evert Rol wrote:
> Not sure. In the sense that you can "optimise" (refactor) it in the same way you could do with C. Eg: > results = [0, 0, 0] > flags = [0, 1, 2, 3] > for flag in flags: > results = getflag(flag, results) > That's exactly what I hoped for. I hadn't realised I can initialise a list in one go - it seems that lists work a lot like the arrays I was used to in c. Thanks to the others who took the time to answer. Just now, Asokan's solution is a bit obscure to me - I'll work on that one, but the above is lovely and elegant; and easy to understand. Someone asked about the getflag function - it is: def getflag(thisflag, results): if (thisflag == 2): results[0] += 1 elif (thisflag == 1): results[1] += 1 elif (thisflag == 0): results[2] += 1 return(results) In c, I would have used switch and case, but I gather there is no direct equivalent in Python ... But it works as is. -- From Barry Drake - a member of the Ubuntu advertising team. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
On Fri, Mar 30, 2012 at 9:12 PM, Barry Drake <[hidden email]> wrote:
> On 30/03/12 16:19, Evert Rol wrote: >> >> Not sure. In the sense that you can "optimise" (refactor) it in the same >> way you could do with C. Eg: >> results = [0, 0, 0] >> flags = [0, 1, 2, 3] >> for flag in flags: >> Â Â results = getflag(flag, results) >> > > That's exactly what I hoped for. Â I hadn't realised I can initialise a list > in one go - it seems that lists work a lot like the arrays I was used to in > c. Â Thanks to the others who took the time to answer. Â Just now, Asokan's > solution is a bit obscure to me - I'll work on that one, but the above is > lovely and elegant; and easy to understand. Â Someone asked about the getflag > function - it is: > > def getflag(thisflag, results): > Â Â if (thisflag == 2): > Â Â Â Â results[0] += 1 > Â Â elif (thisflag == 1):> In c, I would have used switch and case, but I gather there is no direct > equivalent in Python ... But it works as is. > > -- > From Barry Drake - a member of the Ubuntu advertising team. > > > _______________________________________________ > Tutor maillist - [hidden email] > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor and directly index on thisflag > Â Â Â Â results[1] += 1 > Â Â elif (thisflag == 0): > Â Â Â Â results[2] += 1 > Â Â return(results) > For the specific values it may be simpler to write: def getflag(thisflag, results): results[2- thisflag] += 1 return results Or you may rearrange the meaning of results and write results[thisflag] += 1 HTH Asokan Pichai _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Barry Drake-2
Barry,
On Fri, 2012-03-30 at 16:42 +0100, Barry Drake wrote: [...] > def getflag(thisflag, results): > if (thisflag == 2): > results[0] += 1 > elif (thisflag == 1): > results[1] += 1 > elif (thisflag == 0): > results[2] += 1 > return(results) Two thoughts spring to mind: -- is it possible to arrange the data model such that the value of the thisflag is the index into the sequence, then: def getflag(thisflag, results): results[thisflag] += 1 return results -- seriously "overengineered" for this particular example but the replacement for switch statement is a dictionary and function pointers. from functools import partial def alt(thisflag, results): def setflag(x): results[x] += 1 { 0: partial(setflag, 2), 1: partial(setflag, 1), 2: partial(setflag, 0), }[thisflag]() return results -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:[hidden email] 41 Buckmaster Road m: +44 7770 465 077 xmpp: [hidden email] London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Barry Drake-2
Barry Drake wrote:
> On 30/03/12 16:19, Evert Rol wrote: >> Not sure. In the sense that you can "optimise" (refactor) it in the same >> way you could do with C. Eg: results = [0, 0, 0] >> flags = [0, 1, 2, 3] >> for flag in flags: >> results = getflag(flag, results) >> > > That's exactly what I hoped for. I hadn't realised I can initialise a > list in one go - it seems that lists work a lot like the arrays I was > used to in c. Thanks to the others who took the time to answer. Just > now, Asokan's solution is a bit obscure to me - I'll work on that one, > but the above is lovely and elegant; and easy to understand. Someone > asked about the getflag function - it is: > > def getflag(thisflag, results): > if (thisflag == 2): > results[0] += 1 > elif (thisflag == 1): > results[1] += 1 > elif (thisflag == 0): > results[2] += 1 > return(results) > > In c, I would have used switch and case, but I gather there is no direct > equivalent in Python ... But it works as is. Here is an alternative to if...elif..., a table (python list) that translates from the flag to an index into the results table. flag_to_result = [2, 1, 0] def update_results(flag, results): try: results[flag_to_result[flag]] += 1 except IndexError: pass # ignore flags other than 0, 1, 2 results = [0, 0, 0] flags = [0, 1, 2, 3, 4, 3, 2, 1] for flag in flags: update_results(flag, results) print results The following operates on an even higher level: from collections import Counter flags = [0, 1, 2, 3, 4, 3, 2, 1] counter = Counter(flags) results = [counter[2], counter[1], counter[0]] print results _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Barry Drake-2
> > Hi there .... I've just joined this list and thought I'd introduce
myself. Welcome! > > correct = 0 > > match = 0 > > wrong = 0 > > results = [correct, match, wrong] > > > > results = getflag(flag_1, results) > > results = getflag(flag_2, results) > > results = getflag(flag_3, results) > > results = getflag(flag_4, results) >> def getflag(thisflag, results): >> if (thisflag == 2): >> results[0] += 1 >> elif (thisflag == 1): >> results[1] += 1 >> elif (thisflag == 0): >> results[2] += 1 >> return(results) >> >> In c, I would have used switch and case, but I gather there is no direct >> equivalent in Python ... But it works as is. C switch is just a different way of doing an if/elif tree, I do not really see any real difference. Although, if there is you can feel free to enlighten me. :) Unlike C, the parenthesis in if statements and returns are not necessary. > if (thisflag == 2): becomes if thisflag == 2: > return(results) becomes return results Furthermore, the way Python binds names means that modifying the list in getflags modifies it in the callee. No need to return and reassign results. >>> def foo(x): ... x[0] += 1 ... >>> bar = [ 1, 3, 4 ] >>> foo( bar ) >>> print bar [2, 3, 4] >>> foo( bar ) >>> print bar [3, 3, 4] Be careful of "results = [0] * 3". This style works fine for immutable types (int, float, str) but does not work as people new to Python think it does. >>> def foo(x): ... x[0][0] += 1 ... >>> bar = [ [0] ]*3 >>> print bar [[0], [0], [0]] >>> foo( bar ) >>> print bar [[1], [1], [1]] >>> foo( bar ) >>> print bar [[2], [2], [2]] This occurs because bar is a list containing 3 elements which are all the exact same object. Modifying one sub-list will modify the "others" as well. Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 -- This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
> Furthermore, the way Python binds names means that modifying the list
> in getflags modifies it in the callee. No need to return and reassign > results. I correct myself. It has nothing to do with name binding, but entirely to do with Python's object model. Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 -- This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Prasad, Ramit-2
Ramit,
On Fri, 2012-03-30 at 16:22 +0000, Prasad, Ramit wrote: [...] > C switch is just a different way of doing an if/elif tree, I do not > really see any real difference. Although, if there is you can feel free > to enlighten me. :) [...] 'fraid not -- though it depends on which compiler and how many cases. For 3 or more cases compilers will generate a hardware supported jump table: a switch statement is a jump table not a cascade of if statements. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:[hidden email] 41 Buckmaster Road m: +44 7770 465 077 xmpp: [hidden email] London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
> [...]
> > C switch is just a different way of doing an if/elif tree, I do not > > really see any real difference. Although, if there is you can feel free > > to enlighten me. :) > [...] > > 'fraid not -- though it depends on which compiler and how many cases. > For 3 or more cases compilers will generate a hardware supported jump > table: a switch statement is a jump table not a cascade of if > statements. Good point, I had forgotten that. Although, it sounded like the OP was referring more to syntax and coding practice than the low level implementation. >I'm already enjoying this lovely language. >One of the few c things I miss is the switch/case statement. if and >elif in it's place is a bit cumbersome. Still, it works. Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Barry Drake-2
On 30/03/2012 15:04, Barry Drake wrote:
> One of the few c things I miss is the switch/case statement. if and elif > in it's place is a bit cumbersome. Still, it works. The recipe here http://code.activestate.com/recipes/410692-readable-switch-construction-without-lambdas-or-di/ refers to several other recipes which you might want to take a look at, sorry I meant to mention this earlier. -- Cheers. Mark Lawrence. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
On 30/03/12 17:58, Mark Lawrence wrote:
> The recipe here > http://code.activestate.com/recipes/410692-readable-switch-construction-without-lambdas-or-di/ > > refers to several other recipes which you might want to take a look > at, sorry I meant to mention this earlier. > Oh, that's neat. Not worth putting into my little project, but I've bookmarked that on for when I need a lot of cases. It also shows how to define a class - that was something I had wondered about, but not yet tackled. I'm really grateful for the answers I have received. It will take me a while to get my head around some of the less obvious code fragment that folk have kindly posted, but I will play around with all of them in due course. Already the code I am playing with has shrunk to about half the number of lines it was before I joined this list and I'm even more than ever impressed with the language. I also like the fact that it can be played with as an interpreted language. Compiling and debugging c code could be a pain at times. In Python, a few print statements together with the syntax error messages from the interpreter make it very easy to see what's happening. Kind regards, Barry. -- From Barry Drake - a member of the Ubuntu advertising team. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Prasad, Ramit-2
On 30/03/12 17:22, Prasad, Ramit wrote:
> Unlike C, the parenthesis in if statements and returns are not > necessary. Furthermore, the way Python binds names means that > modifying the list in getflags modifies it in the callee. No need to > return and reassign results. This is lovely. It's so much friendlier than c. I'm used to c variables going out of scope once you leave the called function. I imagine if you want to leave the variables unchanged, you have to re-assign them inside the function. I quite like it that way. > Be careful of "results = [0] * 3". This style works fine for immutable > types (int, float, str) but does not work as people new to Python > think it does. Thanks for the warning. -- From Barry Drake - a member of the Ubuntu advertising team. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
[snip]
>I'm used to c > variables going out of scope once you leave the called function. I > imagine if you want to leave the variables unchanged, you have to > re-assign them inside the function. [snip] Lists are mutable objects. When you pass a list to a function you bind a name in the functions namespace to the list object. Every name binding to that object will have the ability to modify the list. If you want to modify the list but not change it for others usually you do something like new_list = list( old_list ) OR new_list = old_list[:] Now if you wanted to change an immutable object (like int) then you would have to return object because the name binding is only the function's scope. It should also be noted that you can modify the list but you cannot reassign the list from the function. Consider: >>> >>> def blah( a ): ... a = [] ... >>> b = [ 1, 3, 4 ] >>> blah( b ) >>> print b [1, 3, 4] >>> The reason b is untouched is because a = [] just binds the name 'a' to a new list object while the name 'b' is still bound to the original list object. To bind 'b' to the new list I would have had to return it from blah(). Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 -- This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
On 3/30/2012 10:56 AM Prasad, Ramit said...
> Lists are mutable objects. When you pass a list to a function you bind > a name in the functions namespace to the list object. Every name > binding to that object will have the ability to modify the list. > > If you want to modify the list but not change it for others usually > you do something like > > new_list = list( old_list ) > OR > new_list = old_list[:] Be aware though that this copies only the 'top' level objects -- if those object are themselves mutable you may still have issues: >>> a = [1,2,3] >>> b = [4,5,6] >>> c = [a,b] >>> d = c[:] >>> d.append(1) >>> d [[1, 2, 3], [4, 5, 6], 1] >>> c [[1, 2, 3], [4, 5, 6]] >>> # so far so good ... >>> b.append(7) >>> d [[1, 2, 3], [4, 5, 6, 7], 1] >>> c [[1, 2, 3], [4, 5, 6, 7]] >>> To avoid this, look at copy.deepcopy as an alternative: >>> d = copy.deepcopy(c) >>> d [[1, 2, 3], [4, 5, 6, 7]] >>> b.append(8) >>> c [[1, 2, 3], [4, 5, 6, 7, 8]] >>> d [[1, 2, 3], [4, 5, 6, 7]] >>> HTH, Emile _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
|
In reply to this post by Barry Drake-2
Barry,
On Fri, 2012-03-30 at 18:27 +0100, Barry Drake wrote: > On 30/03/12 17:58, Mark Lawrence wrote: > > The recipe here > > http://code.activestate.com/recipes/410692-readable-switch-construction-without-lambdas-or-di/ > > > > refers to several other recipes which you might want to take a look > > at, sorry I meant to mention this earlier. > > > > Oh, that's neat. Not worth putting into my little project, but I've > bookmarked that on for when I need a lot of cases. It also shows how to > define a class - that was something I had wondered about, but not yet > tackled. whereas this Python simulacrum remains O(n). The people who comment saying C switch is always O(n) have clearly never looked at any compiler output. Personally, I am in the camp that says: don't use a device that makes it appear the performance is not what it is. Thus I would prefer if/elif/else cascade over this device since it is simpler and more obvious that it is O(n). But it is a nice example of what Python can achieve even though I would not use it myself. -- Russel. ============================================================================= Dr Russel Winder t: +44 20 7585 2200 voip: sip:[hidden email] 41 Buckmaster Road m: +44 7770 465 077 xmpp: [hidden email] London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder _______________________________________________ Tutor maillist - [hidden email] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor |
| Powered by Nabble | Edit this page |
