Re: [Tutor] introspection
On 2015-05-07 20:45, Dave Angel wrote: You also only showed it working on module globals. (For code at top-level, locals() returns the same as globals() ) You could also try it inside functions, where locals() really makes sense as a name. And you could try it in a nested function where there may very well be non-locals (eg. closure items) that aren't local or global. You've taken me to new territory: http://www.shutupandship.com/2012/01/python-closures-explained.html I wasn't familiar with 'closures' and to be truthful, still am not, although thanks to you I am at least aware of the idea. But more interestingly, you could try it on items of a list, or members of a dictionary, where there's no name at all associated with the object. It simply returns None. I assume that's the point you are making? (That it has no name, or perhaps more accurately expressed: there is no name to discover.) alex ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] introspection
On 05/07/2015 11:23 PM, Alex Kleider wrote: On 2015-05-07 19:10, Dave Angel wrote: def get_name(localmap, item): """As suggested. Returns 'a' name, not necessarily 'the' name.""" for name in localmap: if localmap[name] == item: This is not likely to be what was intended. You want if localmap[name] is item: That can identify if one of the names happens to be bound to the SAME object being examined. Rather than one that happens to have the same value. Correction noted. Thank you for that. The distinction is important. ('==' vs 'is') You also only showed it working on module globals. (For code at top-level, locals() returns the same as globals() ) You could also try it inside functions, where locals() really makes sense as a name. And you could try it in a nested function where there may very well be non-locals (eg. closure items) that aren't local or global. But more interestingly, you could try it on items of a list, or members of a dictionary, where there's no name at all associated with the object. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] introspection
On 2015-05-07 19:10, Dave Angel wrote: def get_name(localmap, item): """As suggested. Returns 'a' name, not necessarily 'the' name.""" for name in localmap: if localmap[name] == item: This is not likely to be what was intended. You want if localmap[name] is item: That can identify if one of the names happens to be bound to the SAME object being examined. Rather than one that happens to have the same value. Correction noted. Thank you for that. The distinction is important. ('==' vs 'is') ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Tip (thank) your mentors
Howdy all, I just received a private message that, briefly and simply, thanked me for advice I gave in this forum, explaining specifically how it helped the recipient understand a concept better. It made my day; I have a spring in my step now. Everyone, never hesitate to thank someone – privately if you wish – for help they've given you. It is inexpensive to give, and very dear to receive. Most of us, most of the time, are engaging in these public discussions to help the community. Gratitude sincerely expressed is an important and valuable way to motivate us to keep contributing. Thank you for keeping our community welcoming and happy. -- \ “Oh, I realize it's a penny here and a penny there, but look at | `\ me: I've worked myself up from nothing to a state of extreme | _o__) poverty.” —Groucho Marx | Ben Finney ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On Thu, May 07, 2015 at 12:15:42PM -0700, Jim Mooney Py3.4.3winXP wrote: > I find this a bit confusing. Since the ID of K remains the same, so it's > the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I > understand that it's immutable but doesn't that mean K is created each time > in local scope so it should have a different ID each time? > > def testid(K=10): > K += 10 > return 'the ID is', id(K), K You have two questions in there, and they are unrelated. K does not increase each time, because you throw the result away each time and start again. testid() uses the default of K=10. In the body of the function, K+=10 adds 10+10 to give 20, and binds that to the local variable K. But it doesn't change the default value, which is still 10 (ints being immutable, it cannot be changed in place). So when you call testid() the second time, the previous value of K is lost and it starts against with K=10. Here is an alternative that does behave like persistent storage from call to call: def testid(K=[10]): K[0] += 10 return 'the ID is', id(K), K Because the default value is a list, and lists are mutable, so long as we *modify* that list, the change will be seen the next time round. Your second question is why the id() doesn't change. There are at least two possible reasons for that: (1) CPython caches small ints. Because they are used so frequently, CPython saves time at the cost of a little bit of memory by using the same objects each time, instead of creating them from scratch each time. The precise ints which are cached are a private implementation detail and subject to change without notice, so don't rely on that. (2) Python only guarantees that IDs are unique for objects which exist at the same time. In other words, Python implementations may re-use IDs. Some do not: Jython and IronPython don't re-use IDs, but CPython does. So if we have a sequence of events like this: (1) create K (2) print id(K) (3) garbage collect K (4) create K again (5) print id(K) again it is possible that the K created in (4) gets the same ID as the one created in (1). -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] introspection
On 05/07/2015 09:50 PM, Alex Kleider wrote: On 2015-04-21 16:48, Cameron Simpson wrote: But it would not be schizophrenic to write a function that returned a name arbitrarily, by inspecting locals(). It depends whether you only need a name, or if you need "the" name. Write yourself a "find_name_from_locals(local_map, value)" function that reports. That will (a) get you a partial answer and (b) cement in your mind what is possible and why. Easy and useful! Cheers, Cameron Simpson Well I finally got around to tackling this little challenge and you are right: It was illuminating. For what it's worth, here's the code that made the light go on: #!../venv/bin/python3 # -*- coding: utf-8 -*- # vim: set file encoding=utf-8 : # # file: 'getname.py' """ def get_name(localmap, item): """As suggested. Returns 'a' name, not necessarily 'the' name.""" for name in localmap: if localmap[name] == item: This is not likely to be what was intended. You want if localmap[name] is item: That can identify if one of the names happens to be bound to the SAME object being examined. Rather than one that happens to have the same value. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] introspection
On 2015-04-21 16:48, Cameron Simpson wrote: But it would not be schizophrenic to write a function that returned a name arbitrarily, by inspecting locals(). It depends whether you only need a name, or if you need "the" name. Write yourself a "find_name_from_locals(local_map, value)" function that reports. That will (a) get you a partial answer and (b) cement in your mind what is possible and why. Easy and useful! Cheers, Cameron Simpson Well I finally got around to tackling this little challenge and you are right: It was illuminating. For what it's worth, here's the code that made the light go on: #!../venv/bin/python3 # -*- coding: utf-8 -*- # vim: set file encoding=utf-8 : # # file: 'getname.py' """ Following through on: Write yourself a "find_name_from_locals(local_map, value)" function that reports. That will (a) get you a partial answer and (b) cement in your mind what is possible and why. Easy and useful! Cheers, Cameron Simpson """ a = 'Alex' j = 'June' ssn = 681769931 # Totally ficticious! # print(locals()) def get_name_1st_version(item): """What I naively thought would work.""" for name in locals(): if name == item: return name def get_name(localmap, item): """As suggested. Returns 'a' name, not necessarily 'the' name.""" for name in localmap: if localmap[name] == item: return name if __name__ == '__main__': # code block to run the application # First attempt: print(get_name_1st_version(a)) print(get_name_1st_version(j)) print(get_name_1st_version(ssn)) print(get_name_1st_version('Alex')) print(get_name_1st_version('June')) print(get_name_1st_version(681769931)) # Second attempt: localmap = locals() # Lesson learned: must use localmap created within the namespace # under scrutiny. print(get_name(localmap, a)) print(get_name(localmap, j)) print(get_name(localmap, ssn)) print(get_name(localmap, 'Alex')) print(get_name(localmap, 'June')) print(get_name(localmap, 681769931)) ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 05/07/2015 07:51 PM, Dave Angel wrote: On 05/07/2015 04:54 PM, Jim Mooney Py3.4.3winXP wrote: On 7 May 2015 at 13:03, Emile van Sebille wrote: Compare to: def testid(K=100): K += 10 return 'the ID is', id(K), K Ah, thanks. I forgot small integers are saved in a table. I was looking at a demo that pointers to defaults in function parameters are persistent. Python doesn't have pointers, and nothing here is persistent. Persistence refers to a value surviving multiple invocations of a program. I think the term you're looking for is "static lifetime". That object will exist for the life of the program. The local variable name K is bound to that object each time the function is called without an argument. It used lists so I tried ints. Although I realized persistence also works for dicts ;') def testid(newitem, K={}): K[newitem] = newitem + 'item' return 'the ID is', id(K), K testid('bonk') ('the ID is', 18263656, {'bonk': 'bonkitem'}) testid('clonk') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem'}) testid('spam') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem', 'spam': 'spamitem'}) The object is not immutable, so it can change. Therefore the += does an in-place change, and you keep the same id. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 05/07/2015 05:25 PM, Alan Gauld wrote: On 07/05/15 21:54, Jim Mooney Py3.4.3winXP wrote: Ah, thanks. I forgot small integers are saved in a table. I was looking at a demo that pointers to defaults in function parameters are persistent. But remember they variables are NOT pointers. They are keys in a dictionary. Very different. Also the id() function is implementation dependant so although it may seem to be a memory address in CPython it is something else in IronPython and something else again in Jython. The only thing guaranteed is that it is a unique id for that object. Unique as long as the two objects you're examining exist at the same time. An id() may be reused once the first object is destroyed. And in general for CPython that happens a lot for small objects. As to default parameter values, the default object is persistent but if you reassign the parameter inside the function it will obviously lose its binding to the default object. It will only be reassigned to it on the next function call (unless it's a generator function). -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 05/07/2015 04:54 PM, Jim Mooney Py3.4.3winXP wrote: On 7 May 2015 at 13:03, Emile van Sebille wrote: Compare to: def testid(K=100): K += 10 return 'the ID is', id(K), K Ah, thanks. I forgot small integers are saved in a table. I was looking at a demo that pointers to defaults in function parameters are persistent. Python doesn't have pointers, and nothing here is persistent. Persistence refers to a value surviving multiple invocations of a program. It used lists so I tried ints. Although I realized persistence also works for dicts ;') def testid(newitem, K={}): K[newitem] = newitem + 'item' return 'the ID is', id(K), K testid('bonk') ('the ID is', 18263656, {'bonk': 'bonkitem'}) testid('clonk') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem'}) testid('spam') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem', 'spam': 'spamitem'}) The object is not immutable, so it can change. Therefore the += does an in-place change, and you keep the same id. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 05/07/2015 03:15 PM, Jim Mooney Py3.4.3winXP wrote: I find this a bit confusing. Since the ID of K remains the same, so it's the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I understand that it's immutable but doesn't that mean K is created each time in local scope so it should have a different ID each time? def testid(K=10): K += 10 return 'the ID is', id(K), K *** Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32. *** testid() ('the ID is', 505991936, 20) testid() ('the ID is', 505991936, 20) testid() ('the ID is', 505991936, 20) K is certainly created new each time, but it is bound to the same object, the one created when the function is defined. K does not have an id(), that object does. Since the object in this case is immutable, the += creates a new object and binds that to K. In your particular code, you never call the id() for the initialization object. I'd add another print, that shows the id(K) before the += All of this is confused by the fact that small ints happen to be interned by your paricular implementation. So you're getting the same object each time. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 05/07/2015 04:03 PM, Emile van Sebille wrote: On 5/7/2015 12:15 PM, Jim Mooney Py3.4.3winXP wrote: I find this a bit confusing. Since the ID of K remains the same, so it's the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I understand that it's immutable but doesn't that mean K is created each time in local scope so it should have a different ID each time? You're looking at the ID of an interned string: Interned int >>> testid() ('the ID is', 7515584L, 20) >>> testid() ('the ID is', 7515584L, 20) >>> testid() ('the ID is', 7515584L, 20) >>> id(20) 7515584L >>> id(10+10) 7515584L >>> id(19+1) 7515584L Compare to: def testid(K=100): K += 10 return 'the ID is', id(K), K -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 07/05/15 21:54, Jim Mooney Py3.4.3winXP wrote: Ah, thanks. I forgot small integers are saved in a table. I was looking at a demo that pointers to defaults in function parameters are persistent. But remember they variables are NOT pointers. They are keys in a dictionary. Very different. Also the id() function is implementation dependant so although it may seem to be a memory address in CPython it is something else in IronPython and something else again in Jython. The only thing guaranteed is that it is a unique id for that object. As to default parameter values, the default object is persistent but if you reassign the parameter inside the function it will obviously lose its binding to the default object. It will only be reassigned to it on the next function call (unless it's a generator function). -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 7 May 2015 at 13:03, Emile van Sebille wrote: > Compare to: > > def testid(K=100): > K += 10 > return 'the ID is', id(K), K > Ah, thanks. I forgot small integers are saved in a table. I was looking at a demo that pointers to defaults in function parameters are persistent. It used lists so I tried ints. Although I realized persistence also works for dicts ;') def testid(newitem, K={}): K[newitem] = newitem + 'item' return 'the ID is', id(K), K >>> testid('bonk') ('the ID is', 18263656, {'bonk': 'bonkitem'}) >>> testid('clonk') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem'}) >>> testid('spam') ('the ID is', 18263656, {'bonk': 'bonkitem', 'clonk': 'clonkitem', 'spam': 'spamitem'}) -- Jim "What a rotten, failed experiment. I'll start over. Maybe dogs instead of monkeys this time." --God ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] pointer puzzlement
On 5/7/2015 12:15 PM, Jim Mooney Py3.4.3winXP wrote: I find this a bit confusing. Since the ID of K remains the same, so it's the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I understand that it's immutable but doesn't that mean K is created each time in local scope so it should have a different ID each time? You're looking at the ID of an interned string: >>> testid() ('the ID is', 7515584L, 20) >>> testid() ('the ID is', 7515584L, 20) >>> testid() ('the ID is', 7515584L, 20) >>> id(20) 7515584L >>> id(10+10) 7515584L >>> id(19+1) 7515584L Compare to: def testid(K=100): K += 10 return 'the ID is', id(K), K Emile ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] pointer puzzlement
I find this a bit confusing. Since the ID of K remains the same, so it's the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I understand that it's immutable but doesn't that mean K is created each time in local scope so it should have a different ID each time? def testid(K=10): K += 10 return 'the ID is', id(K), K *** Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32. *** >>> testid() ('the ID is', 505991936, 20) >>> testid() ('the ID is', 505991936, 20) >>> testid() ('the ID is', 505991936, 20) >>> -- Jim ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] apache python cgi sockets error 13 (resend after joining the tutorial list)
Stewart Lawton writes: > Hi I have tried Python TCPIP sockets and Unix sockets processed in a > python cgi script, called from apache under fedora19. In both cases a > permissions error is returned at sock.connect(). I have tried changing > permissions x and r w on ALL of user, group, other to no avail. In > both cases the cgi script runs if directly executed from > /var/www/cgi-bin with no apache involvement. Make sure that you not only set the permissions for the socket file but also for the directories leading to the file. The man-pages for AF_UNIX (man unix) state under the section NOTES: In the Linux implementation, sockets which are visible in the filesystem honor the permissions of the directory they are in. Their owner, group and their permissions can be changed. Creation of a new socket will fail if the process does not have write and search (execute) permission on the directory the socket is created in. Connecting to the socket object requires read/write permission. > server_address = '../../.././home/johnlawton/workspace/myUnixSock/uds_socket' You are using a relative path here. Are you certain about the working directory of the interpreter? -- Felix Dietrich ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] apache python cgi sockets error 13 (resend after joining the tutorial list)
Can you post again in plain text? The formatting below is all messed up, indentation and spacing errors abound. On 07/05/15 11:56, Stewart Lawton wrote: Hi I have tried Python TCPIP sockets and Unix sockets > processed in a python cgi script, Have you tried opening the same sockets in a script run in your user space? Its most likely a problem of cgi user and your user permissions clashing. #!/usr/bin/envpython import cgi import socket import sys defhtmlTop(): Note we've lost a space. print("""Content-type:text/html\n\n MyServer Template """) defhtmlTail(): print(""" """ ) defcreSockettoServer(): # Create a TCP/IP socket sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server_address ='../../.././home/johnlawton/workspace/myUnixSock/uds_socket' try: sock.connect(server_address) except socket.error,msg: print>>sys.stderr, msg sys.exit(1) #Send data message = 'This is the message. It will be repeated.' # print >>sys.stderr,'sending "%s"' % message sock.sendall(message) return And the indentation above is messed up. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] apache python cgi sockets error 13 (resend after joining the tutorial list)
Hi I have tried Python TCPIP sockets and Unix sockets processed in a python cgi script, called from apache under fedora19. In both cases a permissions error is returned at sock.connect(). I have tried changing permissions x and r w on ALL of user, group, other to no avail. In both cases the cgi script runs if directly executed from /var/www/cgi-bin with no apache involvement. In both cases all the other (non sockets()) python cgi scripting works in the apache server environment. I note I needed to enable http in the ferora19 firewall to have the apache server work from locahost or from another device connected to the router. Please find the myUnix2.cgi socket script below. Help appreciated! Regards, Stewart Lawton #!/usr/bin/envpython import cgi import socket import sys defhtmlTop(): print("""Content-type:text/html\n\n MyServer Template """) defhtmlTail(): print(""" """ ) defcreSockettoServer(): # Create a TCP/IP socket sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server_address ='../../.././home/johnlawton/workspace/myUnixSock/uds_socket' try: sock.connect(server_address) except socket.error,msg: print>>sys.stderr, msg sys.exit(1) #Send data message = 'This is the message. It will be repeated.' # print >>sys.stderr,'sending "%s"' % message sock.sendall(message) return #mainprogram if __name__ == "__main__": try: htmlTop() creSockettoServer() print("Hello World from my Unix2 cgi Script ") htmlTail() except: cgi.print_exception() ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Guess the number
On 07/05/15 05:09, Ikaia Leleiwi wrote: number might be. If the guess is lower then the inputted number then the user inputs the word 'higher' to indicate the computer needs to guess a higher number. If the guess is higher than the inputted number then the user inputs the word 'lower' to indicate the computer needs to guess a lower number. Note that your code does not do that. It ignores the 'higher' or 'lower' input from the user. number = int(input("Pick an integer between 1-100 ")) guess = random.randint(1,100) while guess != number: if guess < number: This if condition should be controlled by the user. So before you get here you need to print the guess and ask for input. The if condition then becomes if next_guess.lower() == 'higher': or similar print("The computer guesses: ",guess) input("higher or lower ") guess = random.randint(guess,100) elif guess > number: same here, the test should be elif next_guess.lower() == 'lower': print("The computer guesses: ",guess) input("higher or lower ") guess = random.randint(1,guess) else: print("Congradulations Computer!! You guessed that the number was ",number) I can't figure out how to narrow down the random integer range as the computer guesses closer and closer to the actual value of the number chosen in the beginning. You could try storing the max and min values of guess so that the limits become randint(guess,hiGuess) and randint(loGuess,guess) And set hiGuess and loGuess when you get an instruction to go up or down loGuess = 1 hiGuess = 100 guess = random(loGuess,hiGuess) number = ... while: if next_guess == 'higher': if guess > loGuess: loGuess = guess elif next_guess == 'lower': if guess < hiGuess: hiGuess = guess else:... guess = randint(loGuess,hiGuess) HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Guess the number
I am having trouble writing a program that guesses a number inputted by the user. A number between 1-100 is inputted into the program and the computer produces a random integer that is the "guess" as to what the inputted number might be. If the guess is lower then the inputted number then the user inputs the word 'higher' to indicate the computer needs to guess a higher number. If the guess is higher than the inputted number then the user inputs the word 'lower' to indicate the computer needs to guess a lower number. My goal is to have this process repeat, continually narrowing down the range of possible numbers that the computer can guess, until it guesses the correct number. The code I have thus far is as follows: #Computer Guesses Number Game #The player chooses a number between 1 and 100 #The computer guesses a number #The player inputs either higher or lower depending whether #the computer guesses higher than the chosen number or lower #When the computer guesses correctly it is congratulated import random number = int(input("Pick an integer between 1-100 ")) guess = random.randint(1,100) while guess != number: if guess < number: print("The computer guesses: ",guess) input("higher or lower ") guess = random.randint(guess,100) elif guess > number: print("The computer guesses: ",guess) input("higher or lower ") guess = random.randint(1,guess) else: print("Congradulations Computer!! You guessed that the number was ",number) --- I can't figure out how to narrow down the random integer range as the computer guesses closer and closer to the actual value of the number chosen in the beginning. Any help would be greatly appreciated Thanks, Kai ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Object references and garbage collection confusion
> > This is what was also confusing as well. I assumed that python stored > objects rather than simply assigning them. > On Tue, May 5, 2015 at 4:48 AM, Alan Gauld wrote: > On 05/05/15 05:29, Brandon D wrote: > >> Hello tutors, >> >> I'm having trouble understanding, as well as visualizing, how object >> references work in the following situation. For demonstration purposes I >> will keep it at the most rudimentary level: >> >> x = 10 >> x = x ** x >> > > Its good to use a simple example but in this case your > example bears no relation to your comments below! > > >> If my knowledge serves me correctly, Python destroys the value once >> reassigned. >> > > Eventually. > Or more accurately Python marks the object for deletion > once all references to the object have been lost. Remember > variables in Python are not storage locations, they are > names attached to objects. When there are no more names > attached to an object it can be deleted. But that does > not necessarily happen immediately, Python gets around > to it when it has the time. > > So, how does x = x + 1 work if it's destroyed before it can >> be referenced? >> > > Its not. This says assign x to the object on the right. > So it has to work out what "the object on the right" is > before it can stick the label x onto the result. > > The only solution I came up with is that the two operands >> are evaluated before storing it in the variable, consequently >> > > replacing the original value of 0. > > Remember, its the name that moves, not the objects. Python > doesn't store the objects in the variables, it assigns > the variable names to the objects. There is a big difference. > > HTH > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Object references and garbage collection confusion
Thanks Steven. I was just confused on the execution of when Python destroys objects that are no long bound or referenced. On Tue, May 5, 2015 at 2:00 PM, Steven D'Aprano wrote: > On Tue, May 05, 2015 at 12:29:59AM -0400, Brandon D wrote: > > Hello tutors, > > > > I'm having trouble understanding, as well as visualizing, how object > > references work in the following situation. For demonstration purposes I > > will keep it at the most rudimentary level: > > > > x = 10 > > > > x = x ** x > > > In the first case statement, Python creates the integer object 10, and > binds it to the name 'x'. From this instant onwards, x will resolve as > the int 10. > > When the second line executes, Python first evaluates the right hand > side 'x ** x'. To do this, it looks up the name 'x', which resolves to > 10. It then evaluates 10**10, which creates the int 100, and > binds that to the name 'x'. From this instant, x now resolves as the new > value 100. > > Immediately afterwards, Python sees that the int 10 is no longer in use. > (Well, in principle -- in practice, things are more complicated.) Since > it is no longer in use, the garbage collector deletes the object, and > reclaims the memory. > > That, at least, is how it works in principle. In practice, Python may > keep a cache of small integers, so that they never get deleted. That > makes things a bit faster, at the cost of a tiny amount of extra memory. > But this will depend on the version and implementation of Python. For > example, some versions of Python cached integers 0 to 100, others -1 to > 255, very old versions might not cache any at all. As a Python > programmer, you shouldn't care about this, it is purely an optimization > to speed up the language. > > > > If my knowledge serves me correctly, Python destroys the value once > > reassigned. So, how does x = x + 1 work if it's destroyed before it can > > be referenced? The only solution I came up with is that the two operands > > are evaluated before storing it in the variable, > > Correct. Let's say x = 10 again, just for simplicity. > > Python first evaluates the right hand side: it looks up 'x', which > resolves to 10. Then it generates the int 1, and adds them together, > giving 11. Then it binds 11 to the name 'x', which frees up the > reference to 10, and (in principle) 10 will be deleted. > > The right hand side of the equals sign is always fully evaluated before > any assignments are done. This is why we can swap two variables like > this: > > a = 1 > b = 2 > a, b = b, a > > The third line evaluates b (giving 2) and a (giving 1), and Python then > does the assignment: > > a, b = 2, 1 > > which is equivalent to a=2, b=1, thus swapping the values. > > > -- > Steve > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor