source code from SA:10648

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

source code from SA:10648

kirby urner-4
Here is some of the code we will be using in class today.  After that,
a source code file from yesterday's class:


Some Games
"""

from random import randint, choice

# a list of (question, answer) tuples
quiz1 = [("What is the capital of Oregon?", "Salem"),
       ("Is Portland north of Salem?", "Yes"),
       ("Does I-5 go to Seattle?", "Yes"),
       ("Does I-5 go to Pendleton?",  "No")]

quiz2 = [("What is the capital of Washington State","Olympia"),
         ("Are kangaroos native to China?","No"),
         ("Who is the president of the USA?", "Obama"),
         ("What computer language is named for Monty Python?", "Python")]

quizzes = [quiz1, quiz2]  # list of possible quizzes

def askq(quiz = quiz1):
    score = 0
    possible = len(quiz)
    while len(quiz) > 0:
        pickone = randint(0, len(quiz)-1)
        print(quiz[pickone][0])
        answer = raw_input("Your answer? ")

        if answer.upper() == quiz[pickone][1].upper():
            # yes and Yes would both count (but not Y)
            print("Correct!")
            score = score + 1
        else:
            print("Correct answer was %s" % quiz[pickone][1])

        quiz.pop(pickone)

    print("Your score was %s out of a possible %s" % (score, possible))

def guessing(a=0,b=10):
    thenumber = randint(a,b)
    while True:
        print("I'm thinking of a number between %s and %s, what is it?" % (a,b))

        answer = raw_input("Guess (q to quit): ")

        if answer == "q":
            print("Thanks for trying, the number was %s" % thenumber)
            break # escape loop

        if not answer.isdigit():
            # trap non-integer answers
            print("That's not a number!")
            continue # loop again

        answer = int(answer)  # convert to integer
        if answer == thenumber:
            print("That's it!")
            break  # escape loop
        elif answer < thenumber:
            print("Try larger!")
        elif answer > thenumber:
            print("Try smaller!")

def mainmenu():
    while True:
        print("""
What game would you like to play?
1  Take a Quiz
2  Guess a Number
0  Exit""")
        sel = raw_input("Your selection? ")
        if sel == "0":
              print("OK, Good Bye")
              break
        elif sel == "1":
              # randomly choose a quize
              askq(choice(quizzes))
        elif sel == "2":
              guessing()
        else:
            print("Huh?  Please try again")


if __name__ == "__main__":
    # askq(quiz1)
    # guessing()
    mainmenu()


=======


from random import randint, random, choice

allcolors = [color.orange, color.red, color.magenta, color.yellow, color.blue,
             color.white, color.green]


def randcolor():
    return (random.random(), random.random(), random.random())

def junk(n=100):
    for i in range(n):
        draw = choice(["ball", "box"])
        if draw == "ball":
            manyspheres(1)
        else:
            manyboxes(1)

def manyboxes(n=100):
    """
    make random boxes....

    mybox = box(pos=(x0,y0,z0), length=L, height=H, width=W)
    """
    for i in range(n):
        thebox = box(
            pos=(randint(-100,100), randint(-100,100), randint(-100,100)),
            size = (randint(1, 10),randint(1,10),randint(1,10)) ,
            color = randcolor())

def manyspheres(n=100):
    for i in range(n):
        theball = sphere(
            pos=(randint(-100,100),randint(-100,100),randint(-100,100)),
            radius = randint(1, 10),
            color = randcolor())

def xyz(n=10):
    posx = cylinder(radius = 0.1, pos=(0,0,0), axis = (n,0,0), color =
color.white)
    negx = cylinder(radius = 0.2, pos=(0,0,0), axis = (-n,0,0), color
= color.white)
    posy = cylinder(radius = 0.3, pos=(0,0,0), axis = (0,n,0), color =
color.white)
    negy = cylinder(radius = 0.4, pos=(0,0,0), axis = (0,-n,0), color
= color.white)
    posz = cylinder(radius = 0.5, pos=(0,0,0), axis = (0,0,n), color =
color.white)
    negz = cylinder(radius = 0.6, pos=(0,0,0), axis = (0,0,-n), color
= color.white)

def circle():
    print "Making a circle"
    theball = sphere(pos=(2,0,0), radius = 1, color = color.red)
    for i in range(10000):
        newx = 2 * math.cos(math.radians(i))
        newy = 2 * math.sin(math.radians(i))
        theball.pos = (newx, newy, 0)
        rate(30)

def clock():
    bighand = cylinder(radius = 0.1, pos=(0,0,0), axis = (0,10,0),
color = color.green)
    littlehand = cylinder(radius = 0.1, pos=(0,0,0), axis = (0,5,0),
color = color.white)
    clock = ring(pos=(0,0,0), axis = (0,0,1), radius = 10, color =
color.red, thickness = 0.1)
    for i in range(0, -10000, -1):
        newx = 10 * math.cos(math.radians(90 + i ))
        newy = 10 * math.sin(math.radians(90 + i ))
        bighand.axis = (newx, newy, 0)
        newx = 5 * math.cos(math.radians(90 + i/12.))
        newy = 5 * math.sin(math.radians(90 + i/12.))
        littlehand.axis = (newx, newy, 0)
        rate(30)


# student code sent by email from another workstation,
# appended and converted into a function (vs. top-level)

from visual import *
import random
window = display(title="Random Sphere", width = 1024, height = 768)
window.select()

class mysphere():
        def __init__(self, my_color, my_pos, my_name, my_radius):
                mysphere_name = sphere(pos = my_pos,
                                       color = my_color, radius = my_radius)

def test2():
    t = 0
    while t < 100000:
            my_color = random.choice(((255, 255, 255), (255, 255, 0),
(255, 0, 0), (255, 0, 255), (0, 255, 255), (0, 0, 255), (255, 0, 0)))
            my_pos = (random.randrange(-1000, 1000),
                      random.randrange(-1000, 1000),
                      random.randrange(-1000,1000))
            my_radius = random.randrange(5, 20)
            new_mysphere = mysphere(my_color, my_pos, t, my_radius)
            t += 1
            rate(50)


if __name__ == "__main__":
    # test2()
    junk()
    # manyboxes()
    # manyspheres()
    # xyz()
    # circle()
    # clock()
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
On Thu, Jul 15, 2010 at 9:24 AM, kirby urner <[hidden email]> wrote:
Here is some of the code we will be using in class today.  After that,
a source code file from yesterday's class:


Some Games
"""

from random import randint, choice

# a list of (question, answer) tuples
quiz1 = [("What is the capital of Oregon?", "Salem"),
      ("Is Portland north of Salem?", "Yes"),
      ("Does I-5 go to Seattle?", "Yes"),
      ("Does I-5 go to Pendleton?",  "No")]

quiz2 = [("What is the capital of Washington State","Olympia"),
        ("Are kangaroos native to China?","No"),
        ("Who is the president of the USA?", "Obama"),
        ("What computer language is named for Monty Python?", "Python")]

quizzes = [quiz1, quiz2]  # list of possible quizzes

def askq(quiz = quiz1):
   score = 0
   possible = len(quiz)
   while len(quiz) > 0:
       pickone = randint(0, len(quiz)-1)
       print(quiz[pickone][0])
       answer = raw_input("Your answer? ")

       if answer.upper() == quiz[pickone][1].upper():
           # yes and Yes would both count (but not Y)
           print("Correct!")
           score = score + 1
       else:
           print("Correct answer was %s" % quiz[pickone][1])

       quiz.pop(pickone)

   print("Your score was %s out of a possible %s" % (score, possible))


So there's a not-so-subtle bug in the above loop, in that the quiz.pop
method exhausts the target list -- forever and for good, so that next
time you run the quiz, either quiz1 or quiz2 (both global variables) will 
have been commended to the ether.

As a class exercise, I was encouraging students to use this scaffolding
to think of other quizzes and add them as quiz3, quiz4 etc.  Note that
the menu loop picks one at random:

        elif sel == "1":
              # randomly choose a quiz
              askq(choice(quizzes))

So the chances are good that one will get an empty quiz 
(list of (Q,A) tuples).  The program doesn't crash, but you get
a score of 0 out of a possible 0.

The remedy, one of them, is just to use a copy of the list internally.

At this point, a student discussed his travails wanting to copy 
a dictionary, after getting bit in the butt by the "multiple references 
to same object" feature.  

He'd discovered the copy module on his own.  

However in this case, with a list, I went with thelist[:] way of doing it.
Here's the remedied function:

def askq(quiz = quiz1):
    score = 0
    possible = len(quiz)
    thequiz = quiz[:]  # from hence forth, use thequiz, leave quiz alone
    
    while len(quiz) > 0:
        pickone = randint(0, len(quiz)-1)
        print(thequiz[pickone][0])
        answer = raw_input("Your answer? ")

        if answer.upper() == quiz[pickone][1].upper():
            # yes and Yes would both count (but not Y)
            print("Correct!")
            score = score + 1
        else:
            print("Correct answer was %s" % quiz[pickone][1])

        thequiz.pop(pickone)

    print("Your score was %s out of a possible %s" % (score, possible))
 
Now of course it's problematic to be popping off a list just because
you wanna not hit the same question twice, and are picking 
questions randomly.  Sure, this is one way to prevent duplicates.
Even the while loop is pegged to the list length.  Didn't have to
be this way.

Just as good if not way better, is to shuffle the indexes ahead 
of time e.g. indexes = range(len(thelist)); indexes.shuffle().

That'll give you a random sequence on a "primary key" with no
need to mess with popping data off a list copy.

Remember that in Python 3.x, range no longer returns a list 
but a range object, a kind of iterable, but not an iterator (you
can't run next on it):

>>> indexes = range(20)
>>> indexes
range(0, 20)

Some older Python...?

>>> indexes.next()
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    indexes.next()
AttributeError: 'range' object has no attribute 'next'

However, next(indexes) is still no good, because an 
iterator needn't be nextable:

>>> next(indexes)
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    next(indexes)
TypeError: range object is not an iterator

OK, make us an iterator then:

>>> theiter = iter(indexes)
>>> next(theiter)
0
>>> next(theiter)
1

Now we're in business.  Start over if we like:

>>> theiter = iter(indexes)
>>> next(theiter)
0

You can have lots of iterators off the same iterable 
and they'll iterate independently...

>>> [next((theiterA, theiterB)[randint(0,1)]) for x in range(10)]
[0, 1, 2, 1, 2, 3, 4, 3, 4, 5]
>>> next(theiterA)
5
>>> next(theiterB)
6
>>> next(theiterA)
6
>>> 

You can't shuffle an iterator though:

>>> theiter = iter(indexes)
>>> shuffle(theiter)
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    shuffle(theiter)
  File "C:\Python31\lib\random.py", line 267, in shuffle
    for i in reversed(range(1, len(x))):
TypeError: object of type 'range_iterator' has no len()
>>> 

So before using shuffle, you need to turn this range 
object into a list.  

>>> from random import shuffle
>>> help(shuffle)
Help on method shuffle in module random:

shuffle(self, x, random=None, int=<class 'int'>) method of random.Random instance
    x, random=random.random -> shuffle list x in place; return None.
    
    Optional arg random is a 0-argument function returning a random
    float in [0.0, 1.0); by default, the standard random.random.

>>> shuffle(indexes)
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    shuffle(indexes)
  File "C:\Python31\lib\random.py", line 270, in shuffle
    x[i], x[j] = x[j], x[i]
TypeError: 'range' object does not support item assignment

>>> indexes = list(range(20))
>>> shuffle(indexes)
>>> indexes
[11, 3, 16, 2, 4, 13, 17, 9, 19, 1, 12, 8, 10, 14, 18, 15, 0, 5, 7, 6]


Or is there something we wanna to check out in itertools?  

Permutation?

Nah, we're done.

Kirby

Note:  more genteel writers may prefer indices to indexes.
I also prefer vertexes to vertices.


_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

Tim Peters
[kirby urner]
...

> Here's the remedied function:
> def askq(quiz = quiz1):
>     score = 0
>     possible = len(quiz)
>     thequiz = quiz[:]  # from hence forth, use thequiz, leave quiz alone
>
>     while len(quiz) > 0:
>         pickone = randint(0, len(quiz)-1)
> ...
>         thequiz.pop(pickone)

You're working too hard ;-)

> Now of course it's problematic to be popping off a list just because
> you wanna not hit the same question twice, and are picking
> questions randomly.  Sure, this is one way to prevent duplicates.
> Even the while loop is pegged to the list length.  Didn't have to
> be this way.
> Just as good if not way better, is to shuffle the indexes ahead
> of time e.g. indexes = range(len(thelist)); indexes.shuffle().
> That'll give you a random sequence on a "primary key" with no
> need to mess with popping data off a list copy.

Still working too hard ;-)

Why not shuffle the quiz guts directly?

def askq(quiz = quiz1):
     thequiz = quiz[:]  # from hence forth, use thequiz, leave quiz alone
     shuffle(thequiz)
     for q, a in thequiz:    # marches over the questions in a random order
         # `q` is the question, `a` is the answer

In fact, if you don't mind permuting the quiz each time, there's no
need to make a copy of the quiz then either (because nothing is ever
removed from it):

def askq(quiz = quiz1):
     shuffle(quiz)
     for q, a in quiz:    # marches over the questions in a random order
         # `q` is the question, `a` is the answer
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
On Thu, Jul 15, 2010 at 7:37 PM, Tim Peters <[hidden email]> wrote:

<< snip >>

> In fact, if you don't mind permuting the quiz each time, there's no
> need to make a copy of the quiz then either (because nothing is ever
> removed from it):
>
> def askq(quiz = quiz1):
>     shuffle(quiz)
>     for q, a in quiz:    # marches over the questions in a random order
>         # `q` is the question, `a` is the answer

Yep, Tim's way is so much more Pythonic.

Here's a new version for tomorrow's class:

def askq2(quiz = quiz1):
    score = 0
    possible = len(quiz)
    shuffle(quiz)
    for question, answer in quiz:
        print(question)
        user_answer = raw_input("Your answer? ")

        if user_answer.upper() == answer.upper():
            # yes and Yes would both count (but not Y)
            print("Correct!")
            score = score + 1
        else:
            print("Correct answer was %s" % answer)

    print("Your score was %s out of a possible %s" % (score, possible))

Onward!

Kirby
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

John Posner
In reply to this post by kirby urner-4
Kirby wrote:

>      for question, answer in quiz:
>          print(question)
>          user_answer = raw_input("Your answer? ")
>    

Kirby, will the class be using Py2 or Py3? It looks like you're
mix-and-matching, using the *print* function (Py3) along with the
*raw_input* function (Py2). Do you really want to inflict "from
__future__ import print_function" on your students?

Best,
John

_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
Good question John.

My lengthy post was confusing because I want on the riff about
how range() doesn't return a list in 3.x (but a range object,
iterable but not an iterator).

In point of fact, I'm using Python 2.6 from start to finish in
this class, with only allusions and honorable mentions of 3.x
features.  Using print as a function is optional in 2.6 without
importing anything special.

Here we are:

>>> import sys
>>> sys.version
'2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)]'
>>> "{0}".format(1)
'1'
>>> print(1)
1

I'm actually forgetting what we might need to import anymore, to
make 2.6 behave like 3.x, when it comes to print and string formatting.


Kirby


On Fri, Jul 16, 2010 at 6:17 AM, John Posner <[hidden email]> wrote:

> Kirby wrote:
>
>>     for question, answer in quiz:
>>         print(question)
>>         user_answer = raw_input("Your answer? ")
>>
>
> Kirby, will the class be using Py2 or Py3? It looks like you're
> mix-and-matching, using the *print* function (Py3) along with the
> *raw_input* function (Py2). Do you really want to inflict "from __future__
> import print_function" on your students?
>
> Best,
> John
>
>
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

Tim Peters
[kirby]
> ...
>  Using print as a function is optional in 2.6 without
> importing anything special.

Nope!  `print` is a statement in all 1.x and 2.x versions of Python.
When you do, say,

    print(1)

before Python 3.x, you're not calling a print function with an
argument of 1, you're giving the expression (1) to the print
statement.  (1) is the same thing as 1, so it just prints "1".

Maybe the difference is clearer here:

    print(1,2,3)

Before 3.x, tjat's the same as

    _x = (1, 2, 3)
    print _x

That is, it's not passing arguments 1, 2 and 3 to a print function,
it's giving a single expression - the 3-tuple (1, 2, 3) - to the print
statement - and is very different from

    print 1, 2, 3

(which gives 3 expressions - not just 1 - to the print statement).

It's really the same as doing, e.g.,

    return(1)

`return` and `print` are statements, and tacking "(1)" on does not
magically turn either into a function call, it's just adding redundant
parentheses to the expression "1".
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
On Fri, Jul 16, 2010 at 7:27 AM, Tim Peters <[hidden email]> wrote:

> [kirby]
>> ...
>>  Using print as a function is optional in 2.6 without
>> importing anything special.
>
> Nope!  `print` is a statement in all 1.x and 2.x versions of Python.
> When you do, say,
>
>    print(1)
>

Ouch, thank you for clearing up a basic confusion Tim!

I knew this only a month ago when I *did* use

from __future__ import print_function

in another Python 2.6 class, but in the fog of battle
was lapsing into a more punch drunk state.  I could
feel when I was writing that last post that I was
saying something wrong.  But what?

I'm glad to be performing in the role of "dunce clown" here
-- somebody's gotta do it (?), might as well be me.

While I'm being in this mode, here's another basic
question.  Is there a way, after importing from __future__,
to revert to the "old ways" later on in the same script?
Here was my (failed) experiment along those lines:

>>> 1/2
0

>>> from __future__ import division
>>> 1/2
0.5
>>> del division
>>> 1/2
0.5
>>> division

Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    division
NameError: name 'division' is not defined
>>> from __future__ import division
>>> division
_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)

I'm not saying this would ever be a good idea, just
wondering about possibilities...

Kirby

> before Python 3.x, you're not calling a print function with an
> argument of 1, you're giving the expression (1) to the print
> statement.  (1) is the same thing as 1, so it just prints "1".
>
> Maybe the difference is clearer here:
>
>    print(1,2,3)
>
> Before 3.x, tjat's the same as
>
>    _x = (1, 2, 3)
>    print _x
>
> That is, it's not passing arguments 1, 2 and 3 to a print function,
> it's giving a single expression - the 3-tuple (1, 2, 3) - to the print
> statement - and is very different from
>
>    print 1, 2, 3
>
> (which gives 3 expressions - not just 1 - to the print statement).
>
> It's really the same as doing, e.g.,
>
>    return(1)
>
> `return` and `print` are statements, and tacking "(1)" on does not
> magically turn either into a function call, it's just adding redundant
> parentheses to the expression "1".
> _______________________________________________
> Edu-sig mailing list
> [hidden email]
> http://mail.python.org/mailman/listinfo/edu-sig
>
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

John Posner
In reply to this post by kirby urner-4
On 7/16/2010 9:59 AM, kirby urner wrote:
> ...  Using print as a function is optional in 2.6 without
> importing anything special.
>    

Kirby, I believe you're confusing these two invocations:

* Using the print *statement* with a single argument (or expression)
enclosed in parentheses.

* Using the print *function* with a single argument

Using multiple arguments clears things up:

 > python
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
 >>> print 1,2,3,4        # statement with multiple arguments
1 2 3 4
 >>> print(1,2,3,4)       # statement with a single argument (a 4-tuple)
(1, 2, 3, 4)
 >>> from __future__ import print_function
 >>> print(1,2,3,4)       # function with multiple arguments
1 2 3 4

-John

P.S. The fact that the keyword "print" doesn't require a trailing SPACE
reminds me of the old DOS documentation for the command that changes to
the root directory:

   cd\

That caused a lot of needless confusion!

_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
On Fri, Jul 16, 2010 at 9:31 AM, John Posner <[hidden email]> wrote:
> On 7/16/2010 9:59 AM, kirby urner wrote:
>>
>> ...  Using print as a function is optional in 2.6 without
>> importing anything special.
>>
>
> Kirby, I believe you're confusing these two invocations:
>

Yes, you're correct, that's precisely what I was doing.

> * Using the print *statement* with a single argument (or expression)
> enclosed in parentheses.
>
> * Using the print *function* with a single argument
>
> Using multiple arguments clears things up:

I'm glad we're touching on this at length, as people
flooding into our pool find themselves waste deep
with backward / forward compatibility issues, and
may fall for the same self-deception I did for a moment.
For another response, see:

http://mail.python.org/pipermail/edu-sig/2010-July/010040.html

Our class concluded today, although I still have some
paperwork to send in, will do that in a few minutes.
I've got an initial blog write-up here, planning another
follow-up post likely later today, also uploading to
Photostream.

Today we talked about RSA a lot, played my silly Google
video, a rambling blather through group theory etc.
(8+ mins).  We also wrote generators for cuboctahedral
numbers and Fibonacci's, both times going of Encyclo-
pedia for Integer Sequences.  If that sounds like a total
geek out, it was.  Also screened two cartoons.

One student got file sharing to work between his hosting
and guest operating systems on VirtualBox.  Another
got his random forest of cylinder/cone VPython objects
to work.  I lectured at quite some length on the history
of the Internet as a succession of protocols, though I was
somewhat vague on the sequence:  smtp, nntp, ftp, http...
whatever (this was before screening 'Warriors of the Net',
one of the two cartoons).

I'll return to post a link to my followup post.

Kirby Urner
4dsolutions.net/ocn/cp4e.html
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
On Fri, Jul 16, 2010 at 1:41 PM, kirby urner <[hidden email]> wrote:


>
> I'll return to post a link to my followup post.
>

So here are my two write-ups of the just completed
Programming in Python (SA:10648):

http://worldgame.blogspot.com/2010/07/teaching-again.html
http://worldgame.blogspot.com/2010/07/finish-line.html

Also, the math teachers on math-teach @ Math Forum
are starting to ramp up again, on the whole idea of
pre-college computer science or digital / discrete math
or whatever we call it:

Here's a link to the thread (public archive).

http://mathforum.org/kb/thread.jspa?threadID=2095707&tstart=0

You'll see me weighing in with my familiar (to some here)
views, but also expressing this new angst about IDLE.

Excerpts:

"""
Steve Holden, chairman of the Python Software Foundation,
has been suggesting the it may be time to retire IDLE,
removing it from the standard distro. Indeed, on Ubuntu
I'm pretty sure one needs to install it separately...
"""

"""
When learning programming for the first time, you can
dive into object oriented thinking right away, because
this style of thinking was modeled on ordinary human
grammar.

noun.verb( ) and noun.adjective correspond to things
(nouns) having behaviors and attributes (what could
be more natural)?
"""

I talk about some of my history lobbying for a new
discrete math course here -- how I first become aware
of the Litvins text (at a planning workshop with
Chris Brooks just about one year ago):

"""
For those new to this list, I've been putting myself out
there as a kind of lobbyist trying to get something called
computational, digital, discrete and/or fill-in-the-blank math
that is for-credit in equal measure with any of the pre-calc
or calc track classes. I've done a lot of writing about this,
describing my network and our political tactics. I won't
go into all that again here.
"""

http://mathforum.org/kb/thread.jspa?threadID=2095937

Kirby

>
> Kirby Urner
> 4dsolutions.net/ocn/cp4e.html
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

Tim Peters
In reply to this post by kirby urner-4
[kirby urner]
> ... here's another basic
> question.  Is there a way, after importing from __future__,
> to revert to the "old ways" later on in the same script?
> ...
> I'm not saying this would ever be a good idea, just
> wondering about possibilities...

In general it's not possible.  At least CPython compiles an entire
file into bytecode before anything is executed.  That's why __future__
imports have to be the first non-trivial statements in a file:  they
can change just about anything, including the bytecode that gets
generated.

For example, here's a little program:

def f():
    print x / y

import dis
dis.dis(f)

That defines a tiny function, then displays the bytecode generated:

  2           0 LOAD_GLOBAL              0 (x)
              3 LOAD_GLOBAL              1 (y)
              6 BINARY_DIVIDE
              7 PRINT_ITEM
              8 PRINT_NEWLINE
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE

It's not necessary to know what any of those mean, although they
should be pretty obvious ;-)  If you change the program by putting:

from __future__ import division

at the top, the output changes:

  4           0 LOAD_GLOBAL              0 (x)
              3 LOAD_GLOBAL              1 (y)
              6 BINARY_TRUE_DIVIDE
              7 PRINT_ITEM
              8 PRINT_NEWLINE
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE

Note that the third operation changed, from BINARY_DIVIDE to BINARY_TRUE_DIVIDE.

This is all done before anything in the file is executed, so after
execution begins it's too late to change any of it:  the opcode will
remain whatever was generated at the start (BINARY_DIVIDE or
BINARY_TRUE_DIVIDE) no matter what you do while the program is
running.  After all, the instant after you import the future, it
becomes the past, and nobody can change the past ;-)
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
On Mon, Jul 19, 2010 at 6:55 PM, Tim Peters <[hidden email]> wrote:

> [kirby urner]
>> ... here's another basic
>> question.  Is there a way, after importing from __future__,
>> to revert to the "old ways" later on in the same script?
>> ...
>> I'm not saying this would ever be a good idea, just
>> wondering about possibilities...
>
> In general it's not possible.  At least CPython compiles an entire
> file into bytecode before anything is executed.  That's why __future__
> imports have to be the first non-trivial statements in a file:  they
> can change just about anything, including the bytecode that gets
> generated.
>
> For example, here's a little program:
>
> def f():
>    print x / y
>
> import dis
> dis.dis(f)
>
> That defines a tiny function, then displays the bytecode generated:
>
>  2           0 LOAD_GLOBAL              0 (x)
>              3 LOAD_GLOBAL              1 (y)
>              6 BINARY_DIVIDE
>              7 PRINT_ITEM
>              8 PRINT_NEWLINE
>              9 LOAD_CONST               0 (None)
>             12 RETURN_VALUE
>
> It's not necessary to know what any of those mean, although they
> should be pretty obvious ;-)  If you change the program by putting:
>
> from __future__ import division
>
> at the top, the output changes:
>
>  4           0 LOAD_GLOBAL              0 (x)
>              3 LOAD_GLOBAL              1 (y)
>              6 BINARY_TRUE_DIVIDE
>              7 PRINT_ITEM
>              8 PRINT_NEWLINE
>              9 LOAD_CONST               0 (None)
>             12 RETURN_VALUE
>
> Note that the third operation changed, from BINARY_DIVIDE to BINARY_TRUE_DIVIDE.
>


Thank you Tim, that's uber-clear and enlightening.

I notice that in IDLE, even a shell restart (menu option) does not
reset division back to the old way.

IDLE 2.6.5
>>> 1/4
0
>>> from __future__ import division
>>> 1/4
0.25
>>> ==== RESTART ====
>>> 1/4
0.25

I also recall how special name __div__ will be triggered by default
in Python 2.6 until division is imported from __future__, then
__truediv__ gets triggered instead:

>>> class Foo (object):
        def __truediv__(self, other):
                print "__truediv__ triggered"
        def __div__(self, other):
                print "__div__ triggered"

>>> o = Foo()
>>> b = Foo()
>>> o/b
__div__ triggered

>>> from __future__ import division
>>> o/b
__truediv__ triggered

If all you've done is define __div__ for your object, that'll work
by default, until you import division, then unless you have
__truediv__ defined, you'll be getting those error messages:

>>> class Foo (object):
        def __div__(self, other):
                print "__div__ triggered"

               
>>> a = Foo()
>>> a/3
__div__ triggered

>>> from __future__ import division
>>> a/3

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    a/3
TypeError: unsupported operand type(s) for /: 'Foo' and 'int'
>>> a/a

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    a/a
TypeError: unsupported operand type(s) for /: 'Foo' and 'Foo'

> This is all done before anything in the file is executed, so after
> execution begins it's too late to change any of it:  the opcode will
> remain whatever was generated at the start (BINARY_DIVIDE or
> BINARY_TRUE_DIVIDE) no matter what you do while the program is
> running.  After all, the instant after you import the future, it
> becomes the past, and nobody can change the past ;-)
>

I'm a little surprised that resetting the IDLE shell doesn't reset
division "back to factory".  It does disappear from the namespace:

>>> dir()
['Foo', '__builtins__', '__doc__', '__name__', '__package__', 'a', 'division']

>>> ======== RESTART =======

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']

>>> division

Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    division
NameError: name 'division' is not defined

>>> 1/4
0.25

Maybe it shouldn't be allowed to disappear from the namespace (del division
raises an exception) as long as its effects are enforced.  That way a program
could test for it.  But then I supposed there's another way.

Reading from PEP 238:

    The true and floor division APIs will look for the corresponding
    slots and call that; when that slot is NULL, they will raise an
    exception.  There is no fallback to the classic divide slot.

    In Python 3.0, the classic division semantics will be removed; the
    classic division APIs will become synonymous with true division.

Testing in 3.1, I see __div__ is indeed gone as a special name for
integers.  Only __truediv__ ( and __floordiv__ and their =/ =//
semantics) have been retained.

__div__ may be in your code, but it's not a special name (nor is
it a mangled private function given the trailing __ prevents mangling).

Python 3.1.2 (r312:79149, Mar 21 2010, 00:41:52) [MSC v.1500 32 bit
(Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> class Foo (object):
        def __truediv__(self, other):
                print ("__truediv__ triggered")
        def __div__(self, other):
                print ("__div__ triggered")

               
>>> o = Foo()
>>> o/3
__truediv__ triggered

>>> dir(3)  # showing __div__ is all gone

['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__',
'__delattr__', '__divmod__', '__doc__', '__eq__', '__float__',
'__floor__', '__floordiv__', '__format__', '__ge__',
'__getattribute__', '__getnewargs__', '__gt__', '__hash__',
'__index__', '__init__', '__int__', '__invert__', '__le__',
'__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__',
'__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__',
'__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__',
'__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__',
'__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
'__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
'__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']


>>> o .__div__(3)
__div__ triggered

What's in __future__ anyway?

>>> import __future__
>>> dir(__future__)
['CO_FUTURE_ABSOLUTE_IMPORT', 'CO_FUTURE_DIVISION',
'CO_FUTURE_PRINT_FUNCTION', 'CO_FUTURE_UNICODE_LITERALS',
'CO_FUTURE_WITH_STATEMENT', 'CO_GENERATOR_ALLOWED', 'CO_NESTED',
'_Feature', '__all__', '__builtins__', '__doc__', '__file__',
'__name__', '__package__', 'absolute_import', 'all_feature_names',
'division', 'generators', 'nested_scopes', 'print_function',
'unicode_literals', 'with_statement']

Kirby
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

A. Jorge Garcia
In reply to this post by kirby urner-4
Regarding your discussion of Grace Hopper, you may find the videos I  
posted on YouTube of interest:

http://www.youtube.com/cistheta2007

HTH,
A. Jorge Garcia
Applied Math & CS
Baldwin SHS & Nassau CC
http://shadowfaxrant.blogspot.com
http://www.youtube.com/calcpage2009
Sent from my iPod

On Jul 19, 2010, at 6:15 PM, kirby urner <[hidden email]> wrote:

> On Fri, Jul 16, 2010 at 1:41 PM, kirby urner <[hidden email]>  
> wrote:
>
>
>>
>> I'll return to post a link to my followup post.
>>
>
> So here are my two write-ups of the just completed
> Programming in Python (SA:10648):
>
> http://worldgame.blogspot.com/2010/07/teaching-again.html
> http://worldgame.blogspot.com/2010/07/finish-line.html
>
> Also, the math teachers on math-teach @ Math Forum
> are starting to ramp up again, on the whole idea of
> pre-college computer science or digital / discrete math
> or whatever we call it:
>
> Here's a link to the thread (public archive).
>
> http://mathforum.org/kb/thread.jspa?threadID=2095707&tstart=0
>
> You'll see me weighing in with my familiar (to some here)
> views, but also expressing this new angst about IDLE.
>
> Excerpts:
>
> """
> Steve Holden, chairman of the Python Software Foundation,
> has been suggesting the it may be time to retire IDLE,
> removing it from the standard distro. Indeed, on Ubuntu
> I'm pretty sure one needs to install it separately...
> """
>
> """
> When learning programming for the first time, you can
> dive into object oriented thinking right away, because
> this style of thinking was modeled on ordinary human
> grammar.
>
> noun.verb( ) and noun.adjective correspond to things
> (nouns) having behaviors and attributes (what could
> be more natural)?
> """
>
> I talk about some of my history lobbying for a new
> discrete math course here -- how I first become aware
> of the Litvins text (at a planning workshop with
> Chris Brooks just about one year ago):
>
> """
> For those new to this list, I've been putting myself out
> there as a kind of lobbyist trying to get something called
> computational, digital, discrete and/or fill-in-the-blank math
> that is for-credit in equal measure with any of the pre-calc
> or calc track classes. I've done a lot of writing about this,
> describing my network and our political tactics. I won't
> go into all that again here.
> """
>
> http://mathforum.org/kb/thread.jspa?threadID=2095937
>
> Kirby
>
>>
>> Kirby Urner
>> 4dsolutions.net/ocn/cp4e.html
> _______________________________________________
> Edu-sig mailing list
> [hidden email]
> http://mail.python.org/mailman/listinfo/edu-sig
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

kirby urner-4
Really excellent 60 Minutes excerpt, thank you.

I should show that in my next math class.

Kirby


On Tue, Jul 20, 2010 at 5:48 AM, Calcpage <[hidden email]> wrote:

> Regarding your discussion of Grace Hopper, you may find the videos I posted
> on YouTube of interest:
>
> http://www.youtube.com/cistheta2007
>
> HTH,
> A. Jorge Garcia
> Applied Math & CS
> Baldwin SHS & Nassau CC
> http://shadowfaxrant.blogspot.com
> http://www.youtube.com/calcpage2009
> Sent from my iPod
>
> On Jul 19, 2010, at 6:15 PM, kirby urner <[hidden email]> wrote:
>
>> On Fri, Jul 16, 2010 at 1:41 PM, kirby urner <[hidden email]>
>> wrote:
>>
>>
>>>
>>> I'll return to post a link to my followup post.
>>>
>>
>> So here are my two write-ups of the just completed
>> Programming in Python (SA:10648):
>>
>> http://worldgame.blogspot.com/2010/07/teaching-again.html
>> http://worldgame.blogspot.com/2010/07/finish-line.html
>>
>> Also, the math teachers on math-teach @ Math Forum
>> are starting to ramp up again, on the whole idea of
>> pre-college computer science or digital / discrete math
>> or whatever we call it:
>>
>> Here's a link to the thread (public archive).
>>
>> http://mathforum.org/kb/thread.jspa?threadID=2095707&tstart=0
>>
>> You'll see me weighing in with my familiar (to some here)
>> views, but also expressing this new angst about IDLE.
>>
>> Excerpts:
>>
>> """
>> Steve Holden, chairman of the Python Software Foundation,
>> has been suggesting the it may be time to retire IDLE,
>> removing it from the standard distro. Indeed, on Ubuntu
>> I'm pretty sure one needs to install it separately...
>> """
>>
>> """
>> When learning programming for the first time, you can
>> dive into object oriented thinking right away, because
>> this style of thinking was modeled on ordinary human
>> grammar.
>>
>> noun.verb( ) and noun.adjective correspond to things
>> (nouns) having behaviors and attributes (what could
>> be more natural)?
>> """
>>
>> I talk about some of my history lobbying for a new
>> discrete math course here -- how I first become aware
>> of the Litvins text (at a planning workshop with
>> Chris Brooks just about one year ago):
>>
>> """
>> For those new to this list, I've been putting myself out
>> there as a kind of lobbyist trying to get something called
>> computational, digital, discrete and/or fill-in-the-blank math
>> that is for-credit in equal measure with any of the pre-calc
>> or calc track classes. I've done a lot of writing about this,
>> describing my network and our political tactics. I won't
>> go into all that again here.
>> """
>>
>> http://mathforum.org/kb/thread.jspa?threadID=2095937
>>
>> Kirby
>>
>>>
>>> Kirby Urner
>>> 4dsolutions.net/ocn/cp4e.html
>>
>> _______________________________________________
>> Edu-sig mailing list
>> [hidden email]
>> http://mail.python.org/mailman/listinfo/edu-sig
>
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig
Reply | Threaded
Open this post in threaded view
|

Re: source code from SA:10648

A. Jorge Garcia
There's a lot of content on YouTube regarding Ada Lovelace Day as  
well.  There was some discussion on the AP-CompSci listserv about  
making a Grace Murray Hopper Day as well.  The problem IIRC was that  
Hopper's and Lovelace's (or is it Byron) birthdays were very close if  
not, in fact, the same day (not year of course).

Regards,
A. Jorge Garcia
Applied Math & CS
Baldwin SHS & Nassau CC
http://shadowfaxrant.blogspot.com
http://www.youtube.com/calcpage2009
Sent from my iPod

On Jul 21, 2010, at 5:14 PM, kirby urner <[hidden email]> wrote:

> Really excellent 60 Minutes excerpt, thank you.
>
> I should show that in my next math class.
>
> Kirby
>
>
> On Tue, Jul 20, 2010 at 5:48 AM, Calcpage <[hidden email]> wrote:
>> Regarding your discussion of Grace Hopper, you may find the videos  
>> I posted
>> on YouTube of interest:
>>
>> http://www.youtube.com/cistheta2007
>>
>> HTH,
>> A. Jorge Garcia
>> Applied Math & CS
>> Baldwin SHS & Nassau CC
>> http://shadowfaxrant.blogspot.com
>> http://www.youtube.com/calcpage2009
>> Sent from my iPod
>>
>> On Jul 19, 2010, at 6:15 PM, kirby urner <[hidden email]>  
>> wrote:
>>
>>> On Fri, Jul 16, 2010 at 1:41 PM, kirby urner <[hidden email]>
>>> wrote:
>>>
>>>
>>>>
>>>> I'll return to post a link to my followup post.
>>>>
>>>
>>> So here are my two write-ups of the just completed
>>> Programming in Python (SA:10648):
>>>
>>> http://worldgame.blogspot.com/2010/07/teaching-again.html
>>> http://worldgame.blogspot.com/2010/07/finish-line.html
>>>
>>> Also, the math teachers on math-teach @ Math Forum
>>> are starting to ramp up again, on the whole idea of
>>> pre-college computer science or digital / discrete math
>>> or whatever we call it:
>>>
>>> Here's a link to the thread (public archive).
>>>
>>> http://mathforum.org/kb/thread.jspa?threadID=2095707&tstart=0
>>>
>>> You'll see me weighing in with my familiar (to some here)
>>> views, but also expressing this new angst about IDLE.
>>>
>>> Excerpts:
>>>
>>> """
>>> Steve Holden, chairman of the Python Software Foundation,
>>> has been suggesting the it may be time to retire IDLE,
>>> removing it from the standard distro. Indeed, on Ubuntu
>>> I'm pretty sure one needs to install it separately...
>>> """
>>>
>>> """
>>> When learning programming for the first time, you can
>>> dive into object oriented thinking right away, because
>>> this style of thinking was modeled on ordinary human
>>> grammar.
>>>
>>> noun.verb( ) and noun.adjective correspond to things
>>> (nouns) having behaviors and attributes (what could
>>> be more natural)?
>>> """
>>>
>>> I talk about some of my history lobbying for a new
>>> discrete math course here -- how I first become aware
>>> of the Litvins text (at a planning workshop with
>>> Chris Brooks just about one year ago):
>>>
>>> """
>>> For those new to this list, I've been putting myself out
>>> there as a kind of lobbyist trying to get something called
>>> computational, digital, discrete and/or fill-in-the-blank math
>>> that is for-credit in equal measure with any of the pre-calc
>>> or calc track classes. I've done a lot of writing about this,
>>> describing my network and our political tactics. I won't
>>> go into all that again here.
>>> """
>>>
>>> http://mathforum.org/kb/thread.jspa?threadID=2095937
>>>
>>> Kirby
>>>
>>>>
>>>> Kirby Urner
>>>> 4dsolutions.net/ocn/cp4e.html
>>>
>>> _______________________________________________
>>> Edu-sig mailing list
>>> [hidden email]
>>> http://mail.python.org/mailman/listinfo/edu-sig
>>
_______________________________________________
Edu-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/edu-sig