Re: [Tutor] best practices for where to set instance member variables
"Gregory, Matthew" wrote Is there a guideline on where instance member variables should be set within a class? That is, is it a bad idea to set self variables within private member functions rather than returning them to the enclosing caller? There is nothing really specific to OOPP its just the normal rules of defining functions. ie they should not have side effects so far as is possible. So retrning results to the caller is generally preferred. The only significant difference with methods is that you can look up attributtes of self rather than pass them as arguments. This is different to normal functions where we prefer passing arguments rather than using global top access varuiables outside the function defiitioon. But otherwise its all the same rules. Or should I avoid calls to internal functions from other member functions altogether (even if they are somewhat complex)? No! This is one of the most powerful ways of achieving reuse. For example if you define top level methods that are implemented almost entirely by calling lower level methods then it is easy for a subclass to modify the top level function by overriding just the low level methods that it needs to change. That is a very powerful technique for minimisiong change to the external interface and thereby maintaining the Liskov Substitution Principle. A concrete example: class Shape: def draw(self, X, Y): pass def erase(self): pass def move(self,X,Y): self.erase() self.draw(X,Y) Now subclasses only need to implement draw and erase and they get move() for free. class Foo: def __init__(self, a): self.a = self._f1(a) def _f1(self, a): return a This one is nearly always better. -- 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
Re: [Tutor] Iterating through a list of replacement regex patterns
On Sat, 4 Sep 2010 11:57:00 am David Hutto wrote: > First of all, I'll respond more thoroughly tomorrow, when I can > review what you said more clearly, but for now I'll clarify. > > Here is the whole code that I'm using: > > http://pastebin.com/Ak8DFjrb David, in genrandfiles() you say this: mkd = 0 # This makes the range dir for range of the files for later matched # len of dictionary regex word matches if mkd == 0: makerangedirs() Firstly, I don't understand the comment. All the words individually make sense, but altogether, they look like something generated by one of those monkeys with a typewriter... *wink* Secondly, given that in the previous line you just set mkd = 0, is there any possible circumstance where the test "if mkd == 0" would *not* succeed? Why don't you just unconditionally call makerangedirs()? mkd = 0 makerangedirs() > This is supposed to recreate a thought experiment I've heard about, > in which, if you have an infinite amount of monkeys, with an infinite > amount of typewriters, they'll eventually spit out Shakespeare. Ha ha, well, I don't want to discourage you, but the sun will burn out and die long before you get more than a couple of words of Shakespeare from this technique. On the other hand, there are ways to randomly generate non-random text *incredibly quickly*. See http://en.wikipedia.org/wiki/Weasel_program for more detail. -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] nested functions
hello, i have to plug two functions b() and c() inside another one a(); i wonder if the code defining b and c must be in the same text file of a or it is possible to import b and c somehow, hence giving the code a neater appearance thank you ! -- roberto ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] nested functions
> hello, > i have to plug two functions b() and c() inside another one a(); > i wonder if the code defining b and c must be in the same text file of > a or it is possible to import b and c somehow, hence giving the code a > neater appearance Definitely! Read through http://docs.python.org/tutorial/modules.html, that should definitely get you started. Basically, with b & c defined in file1.py (choose your own appropriate name), from file2.py you can do: import file1 def a(...): file1.b() file1.c() or (bit shorter, but can be less clear): from file1 import b, c def a(...): b() c() Evert ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Giving a name to a function and calling it, rather than calling the function directly
Hi folks, I'm new to Python, I'm working my way through some intro books, and I have a question that I wonder if someone could help me with please? This is my attempt at solving an exercise where the program is supposed to flip a coin 100 times and then tell you the number of heads and tails. ATTEMPT 1 returns: The coin landed on tails 100 times The coin landed on heads 0 times ATTEMPT 2 returns: The coin landed on tails 75 times The coin landed on heads 25 times I expected to see the result in attempt 2. I don't fully understand why the results are different however. Is it because Python only runs the randint function once when I call it by the name I assigned to it in attempt 1, but it runs the function fully on each iteration of the loop in attempt 2? Why are these two things different? Thanks in advance, Chris -- ATTEMPT 1 -- import random heads = 0 tails = 0 tossNo = 0 toss = random.randint(1,2) while tossNo <= 99: if toss == 1: heads += 1 tossNo += 1 elif toss == 2: tails += 1 tossNo += 1 print "The coin landed on tails " + str(tails) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" -- ATTEMPT 2 -- import random heads = 0 tails = 0 tossNo = 0 while tossNo <= 99: if random.randint(1,2) == 1: heads += 1 tossNo += 1 elif random.randint(1,2) == 2: tails += 1 tossNo += 1 print "The coin landed on tails " + str(tails) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
On 9/4/10, lists wrote: > Hi folks, > > I'm new to Python, I'm working my way through some intro books, and I > have a question that I wonder if someone could help me with please? > > This is my attempt at solving an exercise where the program is > supposed to flip a coin 100 times and then tell you the number of > heads and tails. > > ATTEMPT 1 returns: > > The coin landed on tails 100 times > > The coin landed on heads 0 times > > ATTEMPT 2 returns: > > The coin landed on tails 75 times > > The coin landed on heads 25 times > > I expected to see the result in attempt 2. I don't fully understand > why the results are different however. Is it because Python only runs > the randint function once when I call it by the name I assigned to it > in attempt 1, but it runs the function fully on each iteration of the > loop in attempt 2? Why are these two things different? Exactly. Essentially when you say x=random.randint(1,2) you are putting the value returned by randint into x, and this happens only once. Had you moved that assignment into the while loop it would keep replacing x, or toss in your case, with a random integer, but because you just call it once it is only assigned once. Python, or any language, would have no way of knowing that you want to reassign toss each time. Loops are used to repeat actions, but you left the assignment of your random int outside of the loop in attempt1 and so there is no way for Python to know that you actually want toss updated 100 times. I hope I explained this okay. > > Thanks in advance, > > Chris > -- > ATTEMPT 1 > -- > import random > > heads = 0 > tails = 0 > tossNo = 0 > toss = random.randint(1,2) > > while tossNo <= 99: > if toss == 1: > heads += 1 > tossNo += 1 > elif toss == 2: > tails += 1 > tossNo += 1 > > print "The coin landed on tails " + str(tails) + " times \n" > print "The coin landed on heads " + str(heads) + " times \n" > > -- > ATTEMPT 2 > -- > import random > > heads = 0 > tails = 0 > tossNo = 0 > > while tossNo <= 99: > if random.randint(1,2) == 1: > heads += 1 > tossNo += 1 > elif random.randint(1,2) == 2: > tails += 1 > tossNo += 1 > > print "The coin landed on tails " + str(tails) + " times \n" > print "The coin landed on heads " + str(heads) + " times \n" > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor > -- Have a great day, Alex (msg sent from GMail website) mehg...@gmail.com; http://www.facebook.com/mehgcap ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] iterating over less than a full list
Say I have and iterable called some_stuff which is thousands of items in length and I am looping thru it as such: for x in some_stuff etc... However, what if I want only to iterate through only the first ten items of some_stuff, for testing purposes. Is there a concise way of specifying that in the for statement line? -Bill ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over less than a full list
if its a dictionary, then I think you will need to use limit if its normal array you can use range(0,10) and access some_stuff[i] On Sat, Sep 4, 2010 at 10:44 PM, Bill Allen wrote: > Say I have and iterable called some_stuff which is thousands of items in > length and I am looping thru it as such: > > for x in some_stuff > etc... > > However, what if I want only to iterate through only the first ten items of > some_stuff, for testing purposes. Is there a concise way of specifying that > in the for statement line? > > > -Bill > > > > > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor > > -- Nitin Pawar ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over less than a full list
On 4 September 2010 19:14, Bill Allen wrote: > Say I have and iterable called some_stuff which is thousands of items in > length and I am looping thru it as such: > > for x in some_stuff > etc... > > However, what if I want only to iterate through only the first ten items of > some_stuff, for testing purposes. Is there a concise way of specifying that > in the for statement line? You can use a slice or use a counter. slice, for x in some_stuff[:10]: etc counter, count = 0 for x in some_stuff: if x <= 10: print x else: break greets Sander ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over less than a full list
On 4 September 2010 19:25, Sander Sweers wrote: > for x in some_stuff: > if x <= 10: > print x > else: > break Oops, corrected version... count = 0 for x in some_stuff: if count < 10: print x count +=1 else: break Greets Sander ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Creating custom GUI elements
Hey guys, How would I go about creating custom GUI elements? For example, if I wanted to make a simple LEGO maker app, how would I write the code for the bricks so that the user could drag them around and then build LEGO models? Thanks! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over less than a full list
On 04/09/2010 18:29, Sander Sweers wrote: On 4 September 2010 19:25, Sander Sweers wrote: for x in some_stuff: if x<= 10: print x else: break Oops, corrected version... count = 0 for x in some_stuff: if count< 10: print x count +=1 else: break Greets Sander ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor I prefer for i, x in enumerate(some_stuff): if i < 10: do_it(x) else: break Cheers. Mark Lawrence. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over less than a full list
On Sun, 5 Sep 2010 03:14:24 am Bill Allen wrote: > Say I have and iterable called some_stuff which is thousands of items > in length and I am looping thru it as such: > > for x in some_stuff > etc... > > However, what if I want only to iterate through only the first ten > items of some_stuff, for testing purposes. Is there a concise way of > specifying that in the for statement line? The Pythonic way is to use itertools.islice. import itertools for x in itertools.islice(some_stuff, 10): blah blah blah will stop at the end of some_stuff, or after 10 items, whichever happens first. islice() optionally takes the full set of arguments that ordinary list slicing takes, so that islice(iterable, start, end, stride) is nearly the same as list(iterable)[start:end:stride]. -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
lists wrote: Hi folks, I'm new to Python, I'm working my way through some intro books, and I have a question that I wonder if someone could help me with please? This is my attempt at solving an exercise where the program is supposed to flip a coin 100 times and then tell you the number of heads and tails. ATTEMPT 1 returns: The coin landed on tails 100 times The coin landed on heads 0 times ATTEMPT 2 returns: The coin landed on tails 75 times The coin landed on heads 25 times I expected to see the result in attempt 2. I don't fully understand why the results are different however. Is it because Python only runs the randint function once when I call it by the name I assigned to it in attempt 1, but it runs the function fully on each iteration of the loop in attempt 2? Why are these two things different? Thanks in advance, Chris -- ATTEMPT 1 -- import random heads = 0 tails = 0 tossNo = 0 toss = random.randint(1,2) while tossNo <= 99: if toss == 1: heads += 1 tossNo += 1 elif toss == 2: tails += 1 tossNo += 1 print "The coin landed on tails " + str(tails) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" -- ATTEMPT 2 -- import random heads = 0 tails = 0 tossNo = 0 while tossNo <= 99: if random.randint(1,2) == 1: heads += 1 tossNo += 1 elif random.randint(1,2) == 2: tails += 1 tossNo += 1 print "The coin landed on tails " + str(tails) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" If your purpose was really to "give a name to a function," you can do that by: toss = random.randint Notice that we do *not* include the parentheses. You want to call the function (by whatever name) inside the loop. So change it to while tossNo <= 99: if toss(1,2) == 1: heads += 1 tossNo += 1 I have no idea why you have an elif clause in there. DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Creating custom GUI elements
On Sat, Sep 4, 2010 at 1:40 PM, aug dawg wrote: > Hey guys, > > How would I go about creating custom GUI elements? For example, if I wanted > to make a simple LEGO maker app, how would I write the code for the bricks > so that the user could drag them around and then build LEGO models? > > Thanks! > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor > > You'd probably want to look into one of the gui toolkits, wxPython, PyGTK, PyQT, etc. No need to reinvent the wheel. -- Greg Bair gregb...@gmail.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over less than a full list
Bill Allen wrote: Say I have and iterable called some_stuff which is thousands of items in length and I am looping thru it as such: for x in some_stuff etc... However, what if I want only to iterate through only the first ten items of some_stuff, for testing purposes. Is there a concise way of specifying that in the for statement line? -Bill You could use islice() import itertools for x in itertools.islice(some_stuff, 0, 10) print x DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
- Original message - > On 9/4/10, lists wrote: > > Hi folks, > > > > I'm new to Python, I'm working my way through some intro books, and I > > have a question that I wonder if someone could help me with please? > > > > This is my attempt at solving an exercise where the program is > > supposed to flip a coin 100 times and then tell you the number of > > heads and tails. > > > > ATTEMPT 1 returns: > > > > The coin landed on tails 100 times > > > > The coin landed on heads 0 times > > > > ATTEMPT 2 returns: > > > > The coin landed on tails 75 times > > > > The coin landed on heads 25 times > > > > I expected to see the result in attempt 2. I don't fully understand > > why the results are different however. Is it because Python only runs > > the randint function once when I call it by the name I assigned to it > > in attempt 1, but it runs the function fully on each iteration of the > > loop in attempt 2? Why are these two things different? > Exactly. Essentially when you say > x=random.randint(1,2) > you are putting the value returned by randint into x, and this happens > only once. Had you moved that assignment into the while loop it would > keep replacing x, or toss in your case, with a random integer, but > because you just call it once it is only assigned once. Python, or any > language, would have no way of knowing that you want to reassign toss > each time. Loops are used to repeat actions, but you left the > assignment of your random int outside of the loop in attempt1 and so > there is no way for Python to know that you actually want toss updated > 100 times. I hope I explained this okay. > > > > Thanks in advance, > > > > Chris > > -- > > ATTEMPT 1 > > -- > > import random > > > > heads = 0 > > tails = 0 > > tossNo = 0 > > toss = random.randint(1,2) > > > > while tossNo <= 99: > > if toss == 1: > > heads += 1 > > tossNo += 1 > > elif toss == 2: > > tails += 1 > > tossNo += 1 > > > > print "The coin landed on tails " + str(tails) + " times \n" > > print "The coin landed on heads " + str(heads) + " times \n" > > > > -- > > ATTEMPT 2 > > -- > > import random > > > > heads = 0 > > tails = 0 > > tossNo = 0 > > > > while tossNo <= 99: > > if random.randint(1,2) == 1: > > heads += 1 > > tossNo += 1 > > elif random.randint(1,2) == 2: > > tails += 1 > > tossNo += 1 > > > > print "The coin landed on tails " + str(tails) + " times \n" > > print "The coin landed on heads " + str(heads) + " times \n" Alex has already answered the question you've asked. I would just like to point out a subtle bug in your ATTEMPT 2 code. What your code does is this: - generate a random number 1 or 2 - test if it is 1 - if it isn't, generate a *new* random number - test if this new random number is 2 That the number of 1s and 2s add up to 100 is an accident of the way you are counting them. You should modify the code to generate a single random number each time through the loop and test whether it is 1 or 2. -- sent from my Nokia N900 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Creating custom GUI elements
"aug dawg" wrote How would I go about creating custom GUI elements? For example, if I wanted to make a simple LEGO maker app, how would I write the code for the bricks so that the user could drag them around and then build LEGO models? You find the nearest widget to what you want then you create a new subclass of that widget. Then you override all the methods that act differently. Then you add any new methods that are unique to your widget. If there is nothing really like it you may need to go up to the abstract widgets like Window and use composition to build a new widget built from the standard ones. Thats even harder because thre is less you get to reuse for free. If its a 3D widget you may want to start with Pygame rather than a standard GUI tooklit... Warning, it's a non trivial exercise thats a pain to get exactly right unless its a very minor tweak to an existing widget. But there is no real alternative. The good news is that once you get it right the final app that uses it will be a snap by comparison! 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
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
>> On 9/4/10, lists wrote: >> > Hi folks, >> > >> > I'm new to Python, I'm working my way through some intro books, and I >> > have a question that I wonder if someone could help me with please? >> > >> > This is my attempt at solving an exercise where the program is >> > supposed to flip a coin 100 times and then tell you the number of >> > heads and tails. >> > >> > ATTEMPT 1 returns: >> > >> > The coin landed on tails 100 times >> > >> > The coin landed on heads 0 times >> > >> > ATTEMPT 2 returns: >> > >> > The coin landed on tails 75 times >> > >> > The coin landed on heads 25 times >> > >> > I expected to see the result in attempt 2. I don't fully understand >> > why the results are different however. Is it because Python only runs >> > the randint function once when I call it by the name I assigned to it >> > in attempt 1, but it runs the function fully on each iteration of the >> > loop in attempt 2? Why are these two things different? >> Exactly. Essentially when you say >> x=random.randint(1,2) >> you are putting the value returned by randint into x, and this happens >> only once. Had you moved that assignment into the while loop it would >> keep replacing x, or toss in your case, with a random integer, but >> because you just call it once it is only assigned once. Python, or any >> language, would have no way of knowing that you want to reassign toss >> each time. Loops are used to repeat actions, but you left the >> assignment of your random int outside of the loop in attempt1 and so >> there is no way for Python to know that you actually want toss updated >> 100 times. I hope I explained this okay. >> > >> > Thanks in advance, >> > >> > Chris >> > -- >> > ATTEMPT 1 >> > -- >> > import random >> > >> > heads = 0 >> > tails = 0 >> > tossNo = 0 >> > toss = random.randint(1,2) >> > >> > while tossNo <= 99: >> > if toss == 1: >> > heads += 1 >> > tossNo += 1 >> > elif toss == 2: >> > tails += 1 >> > tossNo += 1 >> > >> > print "The coin landed on tails " + str(tails) + " times \n" >> > print "The coin landed on heads " + str(heads) + " times \n" >> > >> > -- >> > ATTEMPT 2 >> > -- >> > import random >> > >> > heads = 0 >> > tails = 0 >> > tossNo = 0 >> > >> > while tossNo <= 99: >> > if random.randint(1,2) == 1: >> > heads += 1 >> > tossNo += 1 >> > elif random.randint(1,2) == 2: >> > tails += 1 >> > tossNo += 1 >> > >> > print "The coin landed on tails " + str(tails) + " times \n" >> > print "The coin landed on heads " + str(heads) + " times \n" > > Alex has already answered the question you've asked. I would just like to > point out a subtle bug in your ATTEMPT 2 code. What your code does is this: > > - generate a random number 1 or 2 > - test if it is 1 > - if it isn't, generate a *new* random number > - test if this new random number is 2 > > That the number of 1s and 2s add up to 100 is an accident of the way you are > counting them. > > You should modify the code to generate a single random number each time > through the loop and test whether it is 1 or 2. > > -- > sent from my Nokia N900 > Thanks so much for your fast and friendly response guys, I'm bowled over! As you can tell, I'm just starting out and it helps so much to be able to get a helping hand like this. I've taken on board what you have said and edited the code. Kushal, it didn't occur to me that what I was doing in essence was flipping a coin and attempting to get one result, then only flipping a coin if I didn't get that first result. Now that I've edited the code it gives much 'saner' results. I guess I'll have to be much more careful in the future in the design stage!! Here's what I have now: import random heads = 0 tails = 0 tossNo = 0 while tossNo <= 99: coinToss = random.randint if coinToss(1,2) == 1: heads += 1 tossNo += 1 else: tails += 1 tossNo += 1 print "The coin landed on tails " + str(tails) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
> if coinToss(1,2) == 1: > heads += 1 > tossNo += 1 > else: > tails += 1 > tossNo += 1 Looking good. You can hoist "tossNo += 1" out of each branch of your if statement too, if you like, to make it even more streamlined (In other words, execute it once, right after the coin flip, and before the if-statement). Alan ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
>> if coinToss(1,2) == 1: >> heads += 1 >> tossNo += 1 >> else: >> tails += 1 >> tossNo += 1 > > Looking good. You can hoist "tossNo += 1" out of each branch of your if > statement too, if you like, to make it even more streamlined (In > other words, execute it once, right after the coin flip, and before > the if-statement). > > Alan Ah right, I get you. i.e while tossNo <= 99: coinToss = random.randint tossNo += 1 if coinToss(1,2) == 1: heads += 1 else: tails += 1 That makes sense. :-) Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
On Sun, 5 Sep 2010 08:39:07 am lists wrote: > while tossNo <= 99: > coinToss = random.randint Move that out of the loop. There's no need to make the assignment 100 times. > tossNo += 1 > if coinToss(1,2) == 1: > heads += 1 > else: > tails += 1 Rather than count the number of loops yourself, let Python do the counting: import random coinToss = random.randint heads = tails = 0 for tossNo in range(100): if coinToss(1, 2) == 1: heads += 1 else: tails += 1 Can we do better? Absolutely! Since we know that there are exactly 100 coin tosses, and the number of heads plus the number of tails makes 100, why are we counting them both? import random coinToss = random.randint heads = 0 for tossNo in range(100): if coinToss(1, 2) == 1: heads += 1 print "The coin landed on tails " + str(100-heads) + " times." print "The coin landed on heads " + str(heads) + " times." One small weakness -- if we ever decide to change the number of coin tosses from 100 to some other number, we have to remember to change 100 in two places. We can fix that by defining a named constant. Python doesn't actually have constants, so we use the naming convention "all uppercase means this is a constant, please don't modify it": import random coinToss = random.randint heads = 0 COUNT = 100 for tossNo in range(COUNT): if coinToss(1, 2) == 1: heads += 1 print "The coin landed on tails " + str(COUNT-heads) + " times." print "The coin landed on heads " + str(heads) + " times." Can we do better? Absolutely -- nothing says that heads must be 1 and tails 2. If we make heads 1 and tails 0, we get a neat optimization: import random coinToss = random.randint heads = 0 COUNT = 100 for tossNo in range(COUNT): heads += coinToss(0, 1) Can we do better? Yes. The function "coinToss" is misleading. It doesn't toss a coin, not even figuratively speaking -- it takes two arguments, and returns an integer between those two limits. How is that related to tossing a coin? What are you going to do, this? coinToss(1, 7) # toss a seven-sided coin No, that's ridiculous, and so the name is misleading. What your function does is return a random integer. That's no surprise, because it's just random.randint renamed. So let's fix that by making a proper coinToss function: import random def coinToss(): return random.randint(0, 1) heads = 0 COUNT = 100 for tossNo in range(COUNT): heads += coinToss() Can we do better? Yes, for some definition of "better": import random import functools coinToss = functools.partial(random.randint, 0, 1) COUNT = 100 heads = sum(coinToss() for tossNo in range(COUNT)) print "The coin landed on tails %d times." % (COUNT-heads) print "The coin landed on heads %d times." % heads It's certainly short and concise. You should be able to guess what sum does, and if you can guess what functools.partial does you're doing well :) -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Giving a name to a function and calling it, rather than calling the function directly
On 9/4/2010 10:14 AM, lists wrote: Hi folks, I'm new to Python, I'm working my way through some intro books, and I have a question that I wonder if someone could help me with please? This is my attempt at solving an exercise where the program is supposed to flip a coin 100 times and then tell you the number of heads and tails. ATTEMPT 1 returns: The coin landed on tails 100 times The coin landed on heads 0 times ATTEMPT 2 returns: The coin landed on tails 75 times The coin landed on heads 25 times I expected to see the result in attempt 2. I don't fully understand why the results are different however. Is it because Python only runs the randint function once when I call it by the name I assigned to it in attempt 1, but it runs the function fully on each iteration of the loop in attempt 2? Why are these two things different? Thanks in advance, Chris -- ATTEMPT 1 -- import random heads = 0 tails = 0 tossNo = 0 toss = random.randint(1,2) while tossNo<= 99: if toss == 1: heads += 1 tossNo += 1 elif toss == 2: tails += 1 tossNo += 1 print "The coin landed on tails " + str(tails) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" -- ATTEMPT 2 -- import random heads = 0 tails = 0 tossNo = 0 You should have only 1 call to randint in the loop while tossNo<= 99: if random.randint(1,2) == 1: heads += 1 tossNo += 1 else: tails += 1 tossNo += 1 print "The coin landed on tails " + str(tails) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" You can also simplify: import random heads = 0 tosses = 100 for i in range(tosses): heads += random.randint(0,1) print "The coin landed on tails " + str(tosses - heads) + " times \n" print "The coin landed on heads " + str(heads) + " times \n" Or even simpler: import random tosses = 100 heads = sum(random.randint(0,1) for i in range(tosses)) print ... -- Bob Gailer 919-636-4239 Chapel Hill NC ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] iterating over less than a full list
Thanks to everyone who replied. Some of the methods presented where some I had thought of, others were new to me. Particularly, I did not realize I could apply a slice to a list. The for x in some_stuff[:value] form worked very well for my purposes. I can also see I need to look into the itertools module and see what goodies are to be found there. -Bill On Sat, Sep 4, 2010 at 2:07 PM, Dave Angel wrote: > > > Bill Allen wrote: > >> Say I have and iterable called some_stuff which is thousands of items in >> length and I am looping thru it as such: >> >> for x in some_stuff >> etc... >> >> However, what if I want only to iterate through only the first ten items >> of >> some_stuff, for testing purposes. Is there a concise way of specifying >> that >> in the for statement line? >> >> >> -Bill >> >> >> > You could use islice() > > import itertools > for x in itertools.islice(some_stuff, 0, 10) > print x > > DaveA > > > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Creating custom GUI elements
> How would I go about creating custom GUI elements? For example, > if I wanted to make a simple LEGO maker app, how would I write the > code for the bricks so that the user could drag them around and then > build LEGO models? For 2D legos, using the wxPython widget toolkit, you could probably use its widget called FloatCanvas to provide a space in which bitmaps can be moved around a screen and their coordinates tracked. Then you would have to write the code that determines if the bitmap of the brick is in the right position to snap into place with another brick. Che ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor