[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" > > 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 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 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 > Thanks again all! Hopefully as I learn more I'll find it easier to make the most efficient design choices :-) Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] slicing a string
Hi guys, Continuing my Python learning, I came across an exercise which asks me to take a string and reverse it. I understand that there is a function to do this i.e mytext.reverse() I imagine that the exercise author would rather I did this the hard way however. ;-) Assuming that mytext is "test", I've found that mytext[-1:-4:-1] doesn't work (as I expected it to) but that mytext[::-1] does. While that's fine, I just wondered why mytext[-1:-4:-1] doesn't work? Thanks again, Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] slicing a string
>> Assuming that mytext is "test", I've found that mytext[-1:-4:-1] >> doesn't work (as I expected it to) but that mytext[::-1] does. >> >> While that's fine, I just wondered why mytext[-1:-4:-1] doesn't work? > > How does it not "work"? What did you expect to happen? What did it do instead? > > Greets > Sander > Hi, assuming mytext is "test", word[-1:-4:-1] returns tse My understanding of how the index works on test would be: 0 1 2 3 t e s t -4 -3 -2 -1 So I just wasn't clear on what happened to the last 't' I expected to see. Cheer, Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] slicing a string
>>> Assuming that mytext is "test", I've found that mytext[-1:-4:-1] >>> doesn't work (as I expected it to) but that mytext[::-1] does. >>> >>> While that's fine, I just wondered why mytext[-1:-4:-1] doesn't work? >> >> How does it not "work"? What did you expect to happen? What did it do >> instead? >> >> Greets >> Sander >> > > Hi, assuming mytext is "test", word[-1:-4:-1] returns tse > > My understanding of how the index works on test would be: > > 0 1 2 3 > t e s t > -4 -3 -2 -1 > > So I just wasn't clear on what happened to the last 't' I expected to see. > > Cheer, > > Chris > Sorry I mean mytext[-1:-4:-1] not word[-1:-4:-1] :-S ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] slicing a string
>>> Assuming that mytext is "test", I've found that mytext[-1:-4:-1] >>> doesn't work (as I expected it to) but that mytext[::-1] does. >>> >>> While that's fine, I just wondered why mytext[-1:-4:-1] doesn't >>> work? >> >> It does work. >> But remember that slices give you the first item to one less >> than the second index, so for a 4 letter word you need an >> index of of -5... >> > "test"[-1:-4:-1] >> 'tse' > "test"[-1:-5:-1] >> 'tset' > > > But remember that you can make it simpler if you simply don't specify > the start and end points: > 'hello'[::-1] > 'olleh' > > -- > The saddest aspect of life right now is that science gathers knowledge > faster than society gathers wisdom. > -- Isaac Asimov > Thanks all :-) That makes sense now Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Random list exercise
Hi tutors, Still on my Python learning journey! I've just competed an exercise which asks the student to "Create a program that creates a list of words in random order. This program should print all the words and not repeat any." I've printed the list for my own needs. The list randwords aims to answer the specific request of the exercise author. If anyone has the inclination and a minute to spare, please run your eyes over my answer. It works, but is it an OK way to approach the exercise? Thanks again :-D Chris import random #LIST words = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven"] randwords = [] while words: #has entries in it wordslen = len(words) #get the length of the list index = random.randint(0, wordslen -1) #get a random index chosenword = words[index] randwords.append(chosenword) #append the random word to a new list del words[index] #del the word from the old list for word in randwords: print word # print them ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Random list exercise
> > > On Thu, Sep 9, 2010 at 4:51 PM, lists wrote: >> >> Hi tutors, >> >> Still on my Python learning journey! I've just competed an exercise >> which asks the student to "Create a program that creates a list of >> words in random order. This program should print all the words and not >> repeat any." I've printed the list for my own needs. The list >> randwords aims to answer the specific request of the exercise author. >> >> If anyone has the inclination and a minute to spare, please run your >> eyes over my answer. It works, but is it an OK way to approach the >> exercise? >> >> Thanks again :-D >> >> Chris >> >> import random >> >> #LIST >> words = ["one", "two", "three", "four", "five", "six", "seven", >> "eight", "nine", "ten", "eleven"] >> randwords = [] >> >> while words: #has entries in it >> wordslen = len(words) #get the length of the list >> index = random.randint(0, wordslen -1) #get a random index >> chosenword = words[index] >> randwords.append(chosenword) #append the random word to a new list >> del words[index] #del the word from the old list >> >> for word in randwords: >> print word # print them > > Several small and not so small points: > > 1. you assign wordslen each pass through your loop. While it doesn't matter > in a small loop, it wastes time on the order of the size of your list. > Instead move wordslen = len(... above your while loop. Any time you put > code in a loop that doesn't change in each iteration, you should move it out > of the loop. > > 2. since you only use chosenword once in your loop, you could remove > chosenword = words[index] line and replace chosenword in the append(... with > words[index] > > 3. your list doesn't contain any duplicate words. Since your program is > supposed to catch this, you should add a duplicate to see if it works. > (No!) > > 4. I think your line del words[index] is supposed to help out with item 3 > but it doesn't. It just removes the word you just used selected. > > 5. And finally, I think you want to print > > Just minor points. nice job -- getting there > -- > Joel Goldstick > Ah, back to the drawing boards! I'll fix and post back! Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Random list exercise
>>> >>> Hi tutors, >>> >>> Still on my Python learning journey! I've just competed an exercise >>> which asks the student to "Create a program that creates a list of >>> words in random order. This program should print all the words and not >>> repeat any." I've printed the list for my own needs. The list >>> randwords aims to answer the specific request of the exercise author. >>> >>> If anyone has the inclination and a minute to spare, please run your >>> eyes over my answer. It works, but is it an OK way to approach the >>> exercise? >>> >>> Thanks again :-D >>> >>> Chris >>> >>> import random >>> >>> #LIST >>> words = ["one", "two", "three", "four", "five", "six", "seven", >>> "eight", "nine", "ten", "eleven"] >>> randwords = [] >>> >>> while words: #has entries in it >>> wordslen = len(words) #get the length of the list >>> index = random.randint(0, wordslen -1) #get a random index >>> chosenword = words[index] >>> randwords.append(chosenword) #append the random word to a new list >>> del words[index] #del the word from the old list >>> >>> for word in randwords: >>> print word # print them >> >> Several small and not so small points: >> >> 1. you assign wordslen each pass through your loop. While it doesn't >> matter in a small loop, it wastes time on the order of the size of your >> list. Instead move wordslen = len(... above your while loop. Any time you >> put code in a loop that doesn't change in each iteration, you should move it >> out of the loop. >> >> 2. since you only use chosenword once in your loop, you could remove >> chosenword = words[index] line and replace chosenword in the append(... with >> words[index] >> >> 3. your list doesn't contain any duplicate words. Since your program is >> supposed to catch this, you should add a duplicate to see if it works. >> (No!) >> >> 4. I think your line del words[index] is supposed to help out with item 3 >> but it doesn't. It just removes the word you just used selected. >> >> 5. And finally, I think you want to print >> >> Just minor points. nice job -- getting there >> -- >> Joel Goldstick >> > > > I looked into this a little more, and although I'm ok with my comments, I > did some experimenting and looked into the stuff in random. I came up with > this. It may not be helpful since you may be learning about loops and > randint, but this works: > > import random > > #LIST > words = ["one", "two", "three", "four", "five", "six", "seven", > "eight", "four", "nine", "ten", "eleven"] > > word_set = list(set(words)) # this removes duplicates since set contains > one of each value. Then convert back to a list > print "original words: ", words # just wanted to see my original list > print "removed duplicates with set:", word_set # this shows that I don't > have duplicates > random.shuffle(word_set) # this shuffles the list in place. Now word_set > is shuffled (randomized!) > print "randomized: ", word_set # see! > > Hey Joel, I've not done sets yet. I guess part of the problem when you're a noob like myself is that there is always going to be a more efficient way of doing something (but just that I haven't learnt it yet) :-D Looking at the original code again, I think that the wordslen = len(words) bit might have to stay in the loop. The value of wordslen changes at each iteration of the loop you see. The reason I'm removing one entry from the words list at each iteration is to ensure that all of the words are included in randwords (although again, this probably isn't the best way to do it!). I think I may need to add something like if words[index] not in randwords: to make sure that the word isn't already in the list I want to jumble up' and print perhaps? Thanks Chris Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Random list exercise
>>> Several small and not so small points: >>> >>> 1. you assign wordslen each pass through your loop. While it doesn't >>> matter in a small loop, it wastes time on the order of the size of your >>> list. Instead move wordslen = len(... above your while loop. Any time you >>> put code in a loop that doesn't change in each iteration, you should move it >>> out of the loop. >>> >>> 2. since you only use chosenword once in your loop, you could remove >>> chosenword = words[index] line and replace chosenword in the append(... with >>> words[index] >>> >>> 3. your list doesn't contain any duplicate words. Since your program is >>> supposed to catch this, you should add a duplicate to see if it works. >>> (No!) >>> >>> 4. I think your line del words[index] is supposed to help out with item 3 >>> but it doesn't. It just removes the word you just used selected. >>> >>> 5. And finally, I think you want to print >>> >>> Just minor points. nice job -- getting there >>> -- >>> Joel Goldstick This seems to work Joel, It removes the extraneous assignment of chosenword and gets rid of duplicate entries from the word list. while words: #has entries in it wordslen = len(words) #get the length of the list index = random.randint(0, wordslen -1) #get a random index if words[index] not in randwords: #as long as the word isn't already in the new list randwords.append(words[index]) #append the random word to a new list del words[index] #del the word from the old list else: del words[index] #remove the duplicate word from the source list ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Random list exercise
Ooops, I forgot to send to the list too! -- Forwarded message -- From: lists Date: Fri, Sep 10, 2010 at 10:22 AM Subject: Re: [Tutor] Random list exercise To: Christopher King > you could try random.shuffle and save a lot of time, it takes a mutable > sequence (like a list) and shuffles it Hey there, For the few exercises I've been doing, I think the author has been attempting to make the reader do things 'the difficult way' so that the reader understands how things work. Hopefully the next few chapters will introduce me to doing things the easier way lol :-D random.shuffle is cool though. I'm really impressed on the sheer volume of functions that Python provides to make a programmer's life easier! Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Random list exercise
> On 9/10/2010 5:22 AM, lists wrote: >>> >>> you could try random.shuffle and save a lot of time, it takes a mutable >>> sequence (like a list) and shuffles it >> >> Hey there, >> >> For the few exercises I've been doing, I think the author has been >> attempting to make the reader do things 'the difficult way' so that >> the reader understands how things work. Hopefully the next few >> chapters will introduce me to doing things the easier way lol :-D >> >> random.shuffle is cool though. I'm really impressed on the sheer >> volume of functions that Python provides to make a programmer's life >> easier! >> >> Chris > > also when you reply, make sure you reply to all the tutors, not just me > Hi Chris, I forgot like you did earlier ;-) I did then take the email and send it to the list so everyone got it. Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Getting/setting attributes
Hi tutors, I'm trying to each myself programming and come from a background in system administration with some experience in scripting (so I'm very new to it). Currently I'm grappling with the concept of object orientating programming and have a question about setting & getting attributes. As I understand it, it makes most sense to set/get the attribute of an object using a method rather than doing it directly. I've been reading various ways of doing this, and the information seems a little contradictory. I've muddled my way through the code below to try and force setting or getting the 'address' attribute through the address method rather than allowing direct access. Does this make sense to you? Ta, Chris. class Computer(object): def __init__(self): """instantiate the class with default values""" self.address = "" @property # use the property.getter decorator on this method def address(self): return self._address @address.setter #use the property.setter decorator on this method def address(self, addrvalue): self._address = addrvalue computer1 = Computer() computer1.address = "test" print computer1.address ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting/setting attributes
> Currently I'm grappling with the concept of object orientating > programming and have a question about setting & getting attributes. Oops, just re-read that email. Anyone spot the obvious typo... Ahemmm of course I meant object orientated ;-) Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting/setting attributes
>> > Currently I'm grappling with the concept of object orientating >> >> Oops, just re-read that email. Anyone spot the obvious typo... Ahemmm >> of course I meant object orientated ;-) > > > Actually I believe you mean object *oriented*. > -Wayne Wow, spelling lessons too. And I thought this place only helped people out with Python ;-) I hope you'll forgive my mistake. I'm English, although we invented the language I guess sometimes we have to Americanise our speech to fit in with common technical convention :-P. http://www.english-for-students.com/Oriented-or-Orientated.html Thanks Wayne, Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting/setting attributes
> > My opinion - unless there is some verification or translation or action > required it is better (easier, clearer) to just access and assign the > attribute directly. This makes sense. I guess my current way of doing it just reflects my inexperience. At the moment I'm just fumbling this out so I guess I'm being over-cautious. > >> I've been reading various ways of doing this, and the information seems a >> little >> contradictory. >> > Example, please? Forgive me for any mistakes in this explanation, I'm still learning, but as far as I can figure out, in some earlier versions (before 2.2 perhaps?) it wasn't possible to assign a decorator directly to a method using the at sign, and it was necessary to do this elsewhere within the class itself. I think this link explains what I mean: http://docs.python.org/release/2.4.2/whatsnew/node6.html It seems some tutorials I've been reading were written for this older syntax. >> >> I've muddled my way through the code below to try and force setting or >> getting the 'address' attribute through the address method rather than >> allowing direct access. > > Just because you have a getter and setter does not prohibit direct reference > to _address. I had read something about that. I wonder if the idea behind doing it in the way I've shown is to help prevent the programmer from doing it accidentally perhaps? >> >> class Computer(object): >> >> def __init__(self): >> """instantiate the class with default values""" >> self.address = "" >> > I suggest (if you want to go the setter/getter route that you initialize > _address, just in case someone tries to reference it without setting it. > Do you mean like: class Computer(object): def __init__(self): address = "" self.address = address Or am I missing the point? Thanks for your time Bob, Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Getting/setting attributes
>> As I understand it, it makes most sense to set/get the attribute of >> an object using a method rather than doing it directly. > > Heavens no!!! That's backwards! > > It might be justified in languages like Java, where you can't easily > change your mind about direct attribute access. There's also a school > of thought that disapproves of direct attribute access for a number of > philosophical reasons, but if you strongly agree with that philosophy > you'll probably find Python isn't a good language for you. (It has to > do how much the compiler should forbid the programmer from doing, and > how much software reliability that buys you.) Heh, at the moment I don't have a programming philosophy. It's slowly being formed by conversations with people like you :-) > > 90% of the time, stick to direct attribute access, especially for short > scripts and pre-release versions of software. If and only if you find > that too limiting, or perhaps not limiting enough, then change to using > getter and setter functions and properties. This definitely seems to be the consensus. My instinct is telling me that it's probably best to use getters and setters when requiring input from a user that needs to be validated perhaps, but that my initial reading on the matter seems to have over emphasised the importance of accessing attributes via methods. Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] local day names in ascii
Reply to anush badii <[EMAIL PROTECTED]> 06-06-19 08:52: > Why don't you use the extended ASCII characters where Swedish characters are > included. Not to be be picky but "extended ASCII" isn't a character set and have never been. He should be using ISO-8859-1 (or as it's sometimes called Latin 1). jem ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Waiting until a thread ends
Hi tutors! I'm not a hard-core programmer but have used Python in systems administration (it makes sense to me to use a scripting language which supports both Windows and Unix). The code below is an excerpt from a module I have written to collect information about hosts on my network and populate a database with this data. I have a couple of thousand PCs to check, so decided to try and use Python's inbuilt threading module to allow me to scan multiple hosts concurrently. I've tried to design this function so that it won't end until all of the threads it spawns have completed. I want it to work like this so I can be sure that each step of the script has completed before moving onto the next step.. I find that if the thread I'm calling uses subprocess.popen (for instance, a function using the windows ping command to collect information), that requests for ping are sent, and are results are returned before the script prints 'FINISH'. When I'm spawning a thread that connects to a PC using WMI however, the output I get is more like this: CONNECTING TO PC1 USING WMI CONNECTING TO PC2 USING WMI CONNECTING TO PC3 USING WMI CONNECTING TO PC4 USING WMI CONNECTING TO PC5 USING WMI PC1 = SERVICE PACK3 FINISH PC2 = SERVICE PACK3 PC3 = SERVICE PACK3 PC4 = SERVICE PACK3 PC5 = SERVICE PACK3 I'm somewhat perplexed by this, because as I understood it: if t.isAlive(): t.join() checks to see if any threads are still running, and if they are, it will wait until the threads have terminated. I'm guessing that I'm missing something here and I wondered if anyone has the time to point out the error of my ways? Thanks :-) def wmiem(): DATABASELOC = shared.DATABASELOCMAXTHREADS = shared.MAXTHREADS hoststate = [] #list of running threads try: conn = sqlite3.connect(DATABASELOC) c = conn.cursor() except: raw_input("Couldn't connect to the database. Press 'Enter' to exit") exit() currenttime = time.time() anhourago = currenttime - 3600 #work out the time an hour ago by subtracting 3600 secs off unixtime tup = (anhourago,) c.execute(""" SELECT DISTINCT hostname FROM ping WHERE pingtime > ? AND pingresult = 1; """, tup) for computer in c.fetchall(): for value in computer: while threading.activeCount() > MAXTHREADS: time.sleep(0.5) print 'wmi started on ' + value t = threading.Thread(target=pingandwmi.whatsmyservicepack, args=(value,)) hoststate.append(t) print threading.activeCount() t.start() if t.isAlive(): t.join() # wait till threads have finished. print 'FINISHED' ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Waiting until a thread ends
> > Only really glanced at this, but you seem to be checking only the last > thread *after* the loop? Surely you should be storing all the threads in a > list (or someplace) as you create them, and then check them all for liveness > and if so join them each in turn, to ensure you only print 'FINISHED' once > you've checked and confirmed that all the threads created have in fact > finished. > > Walter > > That makes absolute sense. Doh on my part! Thanks! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Waiting until a thread ends
> Only really glanced at this, but you seem to be checking only the last >> thread *after* the loop? Surely you should be storing all the threads in a >> list (or someplace) as you create them, and then check them all for liveness >> and if so join them each in turn, to ensure you only print 'FINISHED' once >> you've checked and confirmed that all the threads created have in fact >> finished. >> >> Walter >> >> > That makes absolute sense. Doh on my part! > > Thanks! > > Just done a little more reading and came across this in an O'Reilly article here http://www.oreillynet.com/onlamp/blog/2008/01/pymotw_threading.html Seems like an elegant way to accomplish a wait until all running threads have finished. Using enumerate() to wait for all running threads: It is not necessary to retain an explicit handle to all of the daemon threads you start in order to ensure they have completed before exiting the main process. threading.enumerate()returns a list of active Thread instances. The list includes the current thread, and since joining the current thread is not allowed (it introduces a deadlock situation), we must check before joining. import randomimport threadingimport time def worker(): """thread worker function""" t = threading.currentThread() pause = random.randint(1,5) print 'Starting:', t.getName(), 'sleeping', pause time.sleep(pause) print 'Ending :', t.getName() return for i in range(3): t = threading.Thread(target=worker) t.setDaemon(True) t.start() main_thread = threading.currentThread()for t in threading.enumerate(): if t is main_thread: continue print 'Joining :', t.getName() t.join() ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Waiting until a thread ends
> > >> Only really glanced at this, but you seem to be checking only the last >>> thread *after* the loop? Surely you should be storing all the threads in a >>> list (or someplace) as you create them, and then check them all for liveness >>> and if so join them each in turn, to ensure you only print 'FINISHED' once >>> you've checked and confirmed that all the threads created have in fact >>> finished. >>> >>> Walter >>> >>> >> That makes absolute sense. Doh on my part! >> >> Thanks! >> >> > Just done a little more reading and came across this in an O'Reilly article > here http://www.oreillynet.com/onlamp/blog/2008/01/pymotw_threading.html > > Seems like an elegant way to accomplish a wait until all running threads > have finished. > > Using enumerate() to wait for all running threads: > > It is not necessary to retain an explicit handle to all of the daemon > threads you start in order to ensure they have completed before exiting the > main process. threading.enumerate()returns a list of active Thread instances. > The list includes the current thread, and since joining the current thread > is not allowed (it introduces a deadlock situation), we must check before > joining. > > In my continuing quest the find the best way of doing this I came across the following method: for thread in threading.enumerate(): if thread is not threading.currentThread(): thread.join() print 'FINISHED' In my newbie understanding, you can't join() the current thread, because it's the main thread (the one from which the others are called), join()ing it would lock the program up (it would never complete). The above only join()s a thread if it isn't the current thread, thus (hopefully) getting around this. Swapping my earlier stupid code for this seems to work as expected in my tests. Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Waiting until a thread ends
> > > >> In my continuing quest the find the best way of doing this I came across >> the following method: >> >> for thread in threading.enumerate(): >> if thread is not threading.currentThread(): >> thread.join() >> print 'FINISHED' >> >> In my newbie understanding, you can't join() the current thread, because >> it's the main thread (the one from which the others are called), join()ing >> it would lock the program up (it would never complete). >> >> The above only join()s a thread if it isn't the current thread, thus >> (hopefully) getting around this. Swapping my earlier stupid code for this >> seems to work as expected in my tests. >> > > Thanks for the postbacks, it's been useful/interesting for me. > > Best, > > Walter > I'm really pleased that it was of some help to somebody else too. Kind Regards, Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Using xml.etree
Hi Tutors, I have been trying to learn how to parse XML with Python and learn how to use xml.etree. Lots of the tutorials seem to be very long winded. I'm trying to access a UK postcode API at www.uk-postcodes.com to take a UK postcode and return the lat/lng of the postcode. This is what the XML looks like: http://www.uk-postcodes.com/postcode/HU11AA.xml The function below returns a dict with the xml tag as a key and the text as a value. Is this a correct way to use xml.etree? Thanks in advance! Chris def ukpostcodesapi(postcode): import urllib import xml.etree.ElementTree as etree baseURL='http://www.uk-postcodes.com/' geocodeRequest='postcode/'+postcode+'.xml' #grab the xml tree=etree.parse(urllib.urlopen(baseURL+geocodeRequest)) root=tree.getroot() results={} for child in root[1]: #here's the geo tag results.update({child.tag:child.text}) #build a dict containing the geocode data return results #example usage (testing the function) results = ukpostcodesapi('hu11aa') print results['lat']+' '+results['lng'] ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using xml.etree
Hello again. So, any xml.etree experts out there who might have missed this over the weekend? Thanks in advance! Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Using xml.etree
Thanks Tim, Will do. Chris On Mon, Sep 19, 2011 at 11:05 AM, Tim Golden wrote: > On 19/09/2011 11:01, Tim Golden wrote: >> >> you're more likely to find people familiar with the package (including >> its maintainer in fact...) > > Sorry, I misread your post and thought you were referring lxml.etree > (which is a 3rd-party lib). My basic point still stands, though: > you'll get more library-specific help on python-list. > > TJG > ___ > 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] Using xml.etree
On Mon, Sep 19, 2011 at 9:20 PM, Sander Sweers wrote: > On 17/09/11 13:08, lists wrote: >> >> I have been trying to learn how to parse XML with Python and learn how >> to use xml.etree. Lots of the tutorials seem to be very long winded. >> >> I'm trying to access a UK postcode API at www.uk-postcodes.com to take >> a UK postcode and return the lat/lng of the postcode. This is what the >> XML looks like: http://www.uk-postcodes.com/postcode/HU11AA.xml >> >> The function below returns a dict with the xml tag as a key and the >> text as a value. Is this a correct way to use xml.etree? > > Define correct, does it give the desired result? Then I would say yes it is > correct. There may be alternative ways to get to the same result though. > >> def ukpostcodesapi(postcode): >> import urllib > > Why do the import here, for speed? You are reading an xml file from the > internet, guess where most of the time is spend in your function ;-). > >> import xml.etree.ElementTree as etree >> >> baseURL='http://www.uk-postcodes.com/' >> geocodeRequest='postcode/'+postcode+'.xml' > > You could use string formatting here. > url = 'http://www.uk-postcodes.com/postcode/%s.xml' % postcode > > Also what would happen if postcode includes a space? > >> >> #grab the xml >> tree=etree.parse(urllib.urlopen(baseURL+geocodeRequest)) > > What happens if you get an error (a 404 error perhaps)? You might want to > add a try/except block around reading the xml from the internet. > >> root=tree.getroot() >> results={} >> for child in root[1]: #here's the geo tag >> results.update({child.tag:child.text}) #build a dict >> containing the >> geocode data >> return results > > As you only get 1 set of long/lat tags in the xml you could use find(). See > below an example. > > from xml.etree import ElementTree as ET > import urllib2 > > url = 'http://www.uk-postcodes.com/postcode/HU11AA.xml' > xml = urllib2.urlopen(url).read() > tree = ET.XML(xml) > > geo = {} > > for leaf in tree.find('geo'): > geo[leaf.tag] = leaf.text > > Greets > Sander Thank you I've been working on this and ended up with http://pastebin.com/Y9keC9tB Chris ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Hello and newbie question about "self"
Hi Alan, Alan Gauld wrote: > "Patrick" <[EMAIL PROTECTED]> wrote > >> Can anyone please point me to a document that explains "self" in >> layman's terms. > > Try the OOP topic inmy tutorial... Thanks will have a look. >> Or lacking such a doc throw in a much appreciated >> layman's explanation what "self" is and when/where to use it? > > Others have given code samples but a conceptuial explanation > is that > a) self is only used in OO programming within metjhods of a class. Now that really helps. I was wondering about that and this answers it. > b) self refers to the actual instance of the object receiving the > message with caused the method to be invoked. This and reading chapter 23 in the book makes things much clearer now. Thanks! > Thus if we have a class C with a method m and 3 instances > a,b and z then when we invoke a.m() self will refer to a and > when we invoke b.m() self will refer to b. This means that the > innards of the method can use self to access the instance > specific data for that invocation. Even more clear now :) > If you have used C++ at all you might recognise it as the > same as 'this' in C++ except that in Python you must explicitly > specify it whereas C++ creates 'this' magically behind the scenes. Last time I used C++ was (iirc) in 1987 with a Borland product. I recall "this" and remember I got stuck on it then too. > See my tutorial for more on this under the heading > "Using classes". Will do. Thanks for the pointer. > If you haven't started writing classes yet, you can safely ignore > it for now! I probably won't need to start writing classes but I really want to finish the book before I start coding something. I have a small script I did in (horrible) bash and look forward to try to implement it in (less horrible) Python. Thanks for your help. Regards, Patrick ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Next steps after creating virtualenv (new github project)?
Hello, I want to execute: print('Hello world.') in a file called hello.py After creating a virtual-env (via PyCharm) I have these directories: ./foo ./foo/venv ./foo/venv/lib ./foo/venv/lib/python3.6 ./foo/venv/lib/python3.6/site-packages ./foo/venv/include ./foo/venv/bin I want to store my small project in git and upload it to github later. What is the best practice for the directory layout? Are there (official) docs how to start a new project after creating the virtualenv? Regards, Thomas Güttler -- Thomas Guettler http://www.thomas-guettler.de/ I am looking for feedback: https://github.com/guettli/programming-guidelines ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor