From jjp@connix.com Mon Jun 5 15:58:28 2000 From: jjp@connix.com (John Posner) Date: Mon, 5 Jun 2000 10:58:28 -0400 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes Message-ID: <001201bfcefe$84ca51d0$6e64fea9@jake> Hi -- I don't know if anyone else has commented on the Sieve of Eratosthenes implementation posted by Kirby Urner at the end of April. I put my response on the back burner until now, so here goes ... In my opinion, Kirby's implementation (see below) works too hard. The critical problem is that it uses an old-fashioned LOOP to do the work instead of using a nifty, Pythonic FILTER. After all, a SIEVE is just a kind of FILTER. ------------------------------------------- my implementation # construct a list of candidate whole numbers, # using command-line argument as upper limit import sys limit = int(sys.argv[1]) nums = range(2, limit) # initialize result list primes = [] # process the candidate list until no numbers remain while len(nums) > 0: # first item on list must be prime -- call it "prm" prm = nums[0] # add prime to result list primes.append(prm) # implement the sieve: filter out multiples of "prm" nums = filter(lambda n: n % prm > 0, nums) # display results print primes ------------------------------------------- NOTE 1: For clarity, I think the long-winded forms of "while" and "lambda" are preferable. That is: while len(nums) > 0: <-- instead of --> while nums: lambda n: n % prm > 0 <-- instead of --> lambda n: n % prm The short forms take advantage of a quirk of Python: the Boolean value TRUE is implemented as non-zero/non-empty. NOTE 2: My implementation is a main program, not a function. Packaging it up as a function (say, "erat") introduces a scoping problem: when you attempt to define the lambda function within the "erat" function, it can't see the "erat" function's local variable "prm". Solution: use a default argument to implement a closure, passing the "erat" function's local variable into the scope of the labmda function (cf. "Programming Python", Mark Lutz, O'Reilly & Associates, p. 746): lambda n: n % prm > 0 ... must be replaced by ... lambda n, p=prm: n % p > 0 This ain't for a first implementation! ------------------------------------------- Kirby's implementation def erastosthenes(n): # a prime number sieve, thanks to Erastosthenes # returns list of primes <= n cutoff = n ** 0.5 # 2nd root of n is cutoff sieve = [0, 0]+[1]*(n-1) # [0 0 1 1 1...] with 1st 1 in position 2 results = [] # empty list, will contain primes when done prime = 2 # initial prime while prime <= cutoff: # done when prime > 2nd root of n j = 2*prime # jump to 2*prime (first multiple) # turn sieve elements corresponding # to multiples of prime from 1 to 0, up to n. while j <= n: sieve[j]=0 j = j + prime # scan for a 1 in sieve beyond highest prime so far prime = prime + sieve[prime+1:].index(1) + 1 # now translate remaining 1s into actual integers i=0 for entry in sieve: # step through all entries... if entry: # if entry is 1 (i.e. true) results.append(i) # add prime to list i=i+1 return results # return list of primes ------------------------------------------- -- John Posner, Editor jjp@oreilly.com O'Reilly & Associates 860-663-3147 From djmitche@midway.uchicago.edu Mon Jun 5 17:58:16 2000 From: djmitche@midway.uchicago.edu (Dustin James Mitchell) Date: Mon, 5 Jun 2000 11:58:16 -0500 (CDT) Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <001201bfcefe$84ca51d0$6e64fea9@jake> Message-ID: On Mon, 5 Jun 2000, John Posner wrote: > In my opinion, Kirby's implementation (see below) works too hard. The > critical problem is that it uses an old-fashioned LOOP to do the work > instead of using a nifty, Pythonic FILTER. After all, a SIEVE is just a kind > of FILTER. > NOTE 2: My implementation is a main program, not a function. Packaging it up > as a function (say, "erat") introduces a scoping problem: when you attempt > to define the lambda function within the "erat" function, it can't see the > "erat" function's local variable "prm". Solution: use a default argument to > implement a closure, passing the "erat" function's local variable into the > scope of the labmda function (cf. "Programming Python", Mark Lutz, O'Reilly > & Associates, p. 746): While correct, and better in the eyes of a Python pro, I think that your modifications stray too far from Kirby's "math through programming" bent -- there is no clear mathematical analogue to a filter, and it further introduces the scoping problem you mention. Which brings me to an interesting point -- Python is great for many kinds of math/programming lessons, but it has one critical flaw in its implementation of the lambda operator, as you mention above. While students can still do interesting experiments with functions a la >>> def twice(f, x): return f(f(x)) >>> twice(lambda x : x + x, 4) 16 ... you run into a frustrating brick wall when you try to include local variables in the lambda. Although you can use the default-argument trick, it's difficult to explain that to students who have not yet mastered Python. The answer is `it's that way because I said so', and (IMHO) that's not the way to design a curriculum. My $0.02 Dustin --------------------------------------------------------------------- | Dustin Mitchell )O( | --------------------------------------------------------------------- From pdx4d@teleport.com Mon Jun 5 19:38:43 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Mon, 05 Jun 2000 11:38:43 -0700 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <001201bfcefe$84ca51d0$6e64fea9@jake> Message-ID: <3.0.3.32.20000605113843.0078fdd4@pop.teleport.com> John Posner wrote: >In my opinion, Kirby's implementation (see below) works too hard. The >critical problem is that it uses an old-fashioned LOOP to do the work >instead of using a nifty, Pythonic FILTER. After all, a SIEVE is just >a kind of FILTER. I appreciate John's taking the time to explore an alternative -- I hadn't really tuned in FILTER until now. Note that my version, while not as compact in code, uses only addition to change 1s to 0s. Using % over range(2,limit) implies many divisions, and perhaps is not as fast, though I haven't done any work to ascertain this for a fact. Kirby From pdx4d@teleport.com Mon Jun 5 20:07:08 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Mon, 05 Jun 2000 12:07:08 -0700 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <3.0.3.32.20000605113843.0078fdd4@pop.teleport.com> References: <001201bfcefe$84ca51d0$6e64fea9@jake> Message-ID: <3.0.3.32.20000605120708.00789d24@pop.teleport.com> >Note that my version, while not as compact in code, uses only >addition to change 1s to 0s. Using % over range(2,limit) >implies many divisions, and perhaps is not as fast, though >I haven't done any work to ascertain this for a fact. > >Kirby In fact, I'd go even further and say it's the essence of the Erastosthenes method that we _do not_ try to figure out if 13 (for example) goes evenly into some gnarly multi-digit number -- nor should we ask the computer this question. In filtering out non-primes, we're just counting off, and crossing out every 13th number, never trying to divide anything into anything else and looking at the remainder. So I'd say the % or mod operator really _can't_ be part of this process -- IF we're going to call this is a Sieve of Erastosthenes. Gotta remain faithful to the core strategy to merit that moniker. Trial-by-division, on the other hand, does use % (aka mod). Again, I certainly learned from John's post and value his contribution. I'm not a Python guru (yet) and likely could compactify my code (without sacrificing readability) in many methods -- including in erastosthenes(). Kirby PS: Dustin, would your agree that reduce(mul,terms) and reduce(add,terms) are a useful way to introduce sums and products, corresponding to geeky greek symbols capital SIGMA and capital PI. In other words: from operator import mul,add def sum(terms): """Same as SIGMA (terms is a list)""" return reduce(add,terms) def product(terms): """Same as PI (terms is a list)""" return reduce(mul,terms) Would these be useful as "math through programming" Python definitions? Note: n! would be the same as product( range(1,n+1) ). From pingster@ilm.com Mon Jun 5 21:51:41 2000 From: pingster@ilm.com (Ka-Ping Yee) Date: Mon, 5 Jun 2000 13:51:41 -0700 (PDT) Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <3.0.3.32.20000605120708.00789d24@pop.teleport.com> Message-ID: On Mon, 5 Jun 2000, Kirby Urner wrote: > In fact, I'd go even further and say it's the essence of > the Erastosthenes method that we _do not_ try to figure > out if 13 (for example) goes evenly into some gnarly > multi-digit number -- nor should we ask the computer > this question. This makes sense to me. Similarly, the use of square root seems like asking a bit much. You can use the "filter" function to obtain your results at the end, and you can use the third argument to the "range" function to perform the stepping more succinctly and clearly: def eratosthenes(max): sieve = [0, 0] + [1] * max prime = 2 while prime < max: for i in range(prime * 2, max + 1, prime): sieve[i] = 0 while prime < max: prime = prime + 1 if sieve[prime]: break return filter(lambda i, sieve=sieve: sieve[i], range(max + 1)) -- ?!ng From pingster@ilm.com Mon Jun 5 21:55:06 2000 From: pingster@ilm.com (Ka-Ping Yee) Date: Mon, 5 Jun 2000 13:55:06 -0700 (PDT) Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: Message-ID: On Mon, 5 Jun 2000, Dustin James Mitchell wrote: > Which brings me to an interesting point -- Python is great for many kinds > of math/programming lessons, but it has one critical flaw in its > implementation of the lambda operator, as you mention above. [...] > you run into a frustrating brick wall when you try to include local > variables in the lambda. Indeed. This is an important flaw, in my opinion, and (like many others) i'm hoping it will be addressed in Python 3000. It's listed as one of the things we hope to fix. It amounts to more than just the convenience of creating lambdas, for me -- it's really an issue of lexical scoping as a fundamental property of the programming language, and has far-reaching (good) implications. -- ?!ng From pdx4d@teleport.com Tue Jun 6 00:28:52 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Mon, 05 Jun 2000 16:28:52 -0700 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: References: Message-ID: <3.0.3.32.20000605162852.007089d0@pop.teleport.com> Ka-Ping Yee wrote: >You can use the "filter" function to obtain your results >at the end, and you can use the third argument to the >"range" function to perform the stepping more succinctly >and clearly: > > def eratosthenes(max): > sieve = [0, 0] + [1] * max > prime = 2 > while prime < max: > for i in range(prime * 2, max + 1, prime): > sieve[i] = 0 > while prime < max: > prime = prime + 1 > if sieve[prime]: break > return filter(lambda i, sieve=sieve: sieve[i], range(max + 1)) > This I like quite a bit! Good job. I'd probably keep the cut-off at 2nd root, even if I don't use root function, plus given the preponderance of 0s after awhile, I'd like to use the list.index(n) primitive to search a sliced sieve for the next 1, vs stepping by 1 through a break loop, i.e.: def erastosthenes(max): # with thanks to Ka-Ping Yee """Sieve of Erastosthenes""" sieve = [0, 0] + [1] * max prime = 2 while prime*prime <= max: for i in range(prime * 2, max + 1, prime): sieve[i] = 0 prime = prime+1 + sieve[prime+1:].index(1) return filter(lambda i, final=sieve: final[i], range(max + 1)) Ka-Ping, if you have no objection, maybe I'll swap in the above on http://www.inetarena.com/~pdx4d/ocn/numeracy2.html ? Note: also change var name to final in the lamda, as sieve=sieve looks more cryptic IMO. Kirby From pingster@ilm.com Tue Jun 6 00:45:09 2000 From: pingster@ilm.com (Ka-Ping Yee) Date: Mon, 5 Jun 2000 16:45:09 -0700 (PDT) Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <3.0.3.32.20000605162852.007089d0@pop.teleport.com> Message-ID: On Mon, 5 Jun 2000, Kirby Urner wrote: > This I like quite a bit! Good job. Thanks. > Ka-Ping, if you have no objection, maybe I'll swap in the > above on http://www.inetarena.com/~pdx4d/ocn/numeracy2.html ? Sure, feel free to use whatever you like. > Note: also change var name to final in the lamda, as > sieve=sieve looks more cryptic IMO. Perhaps it's just a matter of personal taste, but i actually tend to prefer using the same variable name both inside and outside a lambda in this situation. It's more consistent, and the idiom "spam=spam" is a tip that you're passing local variables to an inner scope. This way, you can almost create the illusion that Python has a form of lexical scoping that requires declaring what names should be visible in the inner scope, and that the syntax for such a declaration is ", spam=spam". It's a lie, but a helpful lie. :) -- ?!ng From pdx4d@teleport.com Tue Jun 6 00:46:17 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Mon, 05 Jun 2000 16:46:17 -0700 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: References: <3.0.3.32.20000605162852.007089d0@pop.teleport.com> Message-ID: <3.0.3.32.20000605164617.006c8358@pop.teleport.com> >It's a lie, but a helpful lie. :) Useful discussion. I'll swap in the new code, with thanks to John Posner as well, as it was his idea to phase in the 'filter' primitive (good suggestion). Kirby From pdx4d@teleport.com Tue Jun 6 01:27:55 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Mon, 05 Jun 2000 17:27:55 -0700 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <3.0.3.32.20000605164617.006c8358@pop.teleport.com> References: <3.0.3.32.20000605162852.007089d0@pop.teleport.com> Message-ID: <3.0.3.32.20000605172755.006c45b4@pop.teleport.com> Here's an ugly way to avoid lambda -- illustrative of points made in 'Learning Python: Nested Functions Aren't Nested Scopes' (pg 118-120): def erastosthenes(max): # with thanks to Ka-Ping Yee """Sieve of Erastosthenes""" global sieve # force to module level sieve = [0, 0] + [1] * max prime = 2 while prime*prime <= max: for i in range(prime * 2, max + 1, prime): sieve[i] = 0 prime = prime+1 + sieve[prime+1:].index(1) def final(x): return sieve[x] # internal function return filter(final, range(max + 1)) Could also make def final(x): return sieve[x] a top-level function and eliminate this line from inside erastosthenes(). I'm not advocating this approach -- why we have lambda is so we can avoid it. Still, it's a useful example of "learning Python through Python" (if not math). Kirby From pingster@ilm.com Tue Jun 6 01:35:07 2000 From: pingster@ilm.com (Ka-Ping Yee) Date: Mon, 5 Jun 2000 17:35:07 -0700 (PDT) Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <3.0.3.32.20000605172755.006c45b4@pop.teleport.com> Message-ID: On Mon, 5 Jun 2000, Kirby Urner wrote: > > Here's an ugly way to avoid lambda -- illustrative of > points made in 'Learning Python: Nested Functions > Aren't Nested Scopes' (pg 118-120): [...] > global sieve # force to module level This is the key line. > def final(x): return sieve[x] # internal function Switching "lambda" to "def" doesn't really make much difference. Or in other words, it's not lambda's "fault". "lambda" is just a shorthand for "def"..."return". The two lines: final = lambda x: sieve[x] def final(x): return sieve[x] are entirely equivalent. It's making "sieve" a global variable that really makes the difference here (naturally, having the function poke around in its module space is generally not a good idea). -- ?!ng From tim_one@email.msn.com Tue Jun 6 02:30:30 2000 From: tim_one@email.msn.com (Tim Peters) Date: Mon, 5 Jun 2000 21:30:30 -0400 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: Message-ID: <000e01bfcf56$cdaa7260$0ca0143f@tim> [Ka-Ping Yee. defending the arithmetic purity of The Sieve] > ... > You can use the "filter" function to obtain your results > at the end, and you can use the third argument to the > "range" function to perform the stepping more succinctly > and clearly: > > def eratosthenes(max): > sieve = [0, 0] + [1] * max > prime = 2 > while prime < max: > for i in range(prime * 2, max + 1, prime): Note that this line can be written > for i in range(prime ** 2, max + 1, prime): (that is, start at the square of the prime rather than twice the prime) instead for a substantial reduction in the total amount of work needed. It should be an interesting exercise for students to figure out why this is a valid optimization! > sieve[i] = 0 > while prime < max: > prime = prime + 1 > if sieve[prime]: break > return filter(lambda i, sieve=sieve: sieve[i], range(max + 1)) > > > -- ?!ng From pdx4d@teleport.com Tue Jun 6 03:51:19 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Mon, 05 Jun 2000 19:51:19 -0700 Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <000e01bfcf56$cdaa7260$0ca0143f@tim> References: Message-ID: <3.0.3.32.20000605195119.00744778@pop.teleport.com> Tim Peters wrote: >Note that this line can be written > >> for i in range(prime ** 2, max + 1, prime): > >(that is, start at the square of the prime rather than twice the prime) >instead for a substantial reduction in the total amount of work needed. It >should be an interesting exercise for students to figure out why this is a >valid optimization! I didn't see this at first, but yes -- if there's another factor < prime, it'll already have been taken care of in the elimination, so it's safe to start the range at prime**2. Plus there's the optimization of stopping with the elimination game altogether when prime**2 >= max (outermost loop) -- because high composites will have been crossed off by their lowest prime factors. I've added your name to the marquee re those contributing to the compactification of our Sieve of Erastosthenes (http://www.inetarena.com/~pdx4d/ocn/numeracy2.html) Here's the code as of now: def erastosthenes(n): """A prime number sieve, returns list of primes <= n Thanks to Erastosthenes for the algorithm, with streamlining by Ka-Ping Yee, John Posner and Tim Peters""" sieve = [0, 0] + [1] * n # [0 0 1 1 1...] prime = 2 # initial prime while prime**2 <= n: for i in range(prime**2, n+1, prime): sieve[i] = 0 # step through sieve by prime prime = prime+1 + sieve[prime+1:].index(1) # get next prime # filter grabs corresponding range members only when seive = 1 return filter(lambda i, sieve=sieve: sieve[i], range(n+1)) Kirby From redbird@rbisland.cx Tue Jun 6 04:20:22 2000 From: redbird@rbisland.cx (Gordon Worley) Date: Mon, 5 Jun 2000 23:20:22 -0400 Subject: Long Boolean expressions (was [Edu-sig] Kirby Urner's Sieve of Eratosthenes) In-Reply-To: <20000605160105.363951CE2D@dinsdale.python.org> References: <20000605160105.363951CE2D@dinsdale.python.org> Message-ID: At 12:01 PM -0400 6/5/2000, John Posner wrote: >NOTE 1: For clarity, I think the long-winded forms of "while" and "lambda" >are preferable. That is: > > while len(nums) > 0: <-- instead of --> while nums: > lambda n: n % prm > 0 <-- instead of --> lambda n: n % prm > >The short forms take advantage of a quirk of Python: the Boolean value TRUE >is implemented as non-zero/non-empty. I can't say that I agree. First of all, this is not a quirk of Python, this is a feature. It is also present in many, many other programming languages. Secondly, this is a style widely used by Python hackers and other end-users (of Python, not of Python scripts), so while the long form might be appropriate in the context of learning Python syntax, it is not during application, except, of course, by end-users who are having difficulty with the more concise formation. Thus, using the long form only hurts others by not forcing them to learn the style that they are going to encounter when reading other people's code. Finally, while the '> 0' bit part works in this situation, it is not very robust since any, to quote, "non-zero/non-empty" is true. Thus, '!= 0' should be used instead of '> 0', so that this long form will work in all situations. -- - Gordon Worley http://www.rbisland.cx/ mailto:redbird@rbisland.cx From jjp@connix.com Tue Jun 6 18:00:50 2000 From: jjp@connix.com (John Posner) Date: Tue, 6 Jun 2000 13:00:50 -0400 Subject: [Edu-sig] RE: Long Boolean expressions Message-ID: <003401bfcfd8$e65c7dd0$6e64fea9@jake> Hi, Gordon -- I agree with your analysis almost completely. I was aiming my implementation at the person who is (1) learning computer programming and (2) learning Python. My one (slight) objection is your wanting to change: * the comparison operation "> 0", which is firmly in the numerical realm * to the comparison operation "!= 0", which is more in the logical realm ("not equal to FALSE") But again, I have pedagogy in mind, not "Boolean purity". :-) -John -- John Posner, Editor jjp@oreilly.com O'Reilly & Associates 860-663-3147 ---------- I can't say that I agree. First of all, this is not a quirk of Python, this is a feature. It is also present in many, many other programming languages. Secondly, this is a style widely used by Python hackers and other end-users (of Python, not of Python scripts), so while the long form might be appropriate in the context of learning Python syntax, it is not during application, except, of course, by end-users who are having difficulty with the more concise formation. Thus, using the long form only hurts others by not forcing them to learn the style that they are going to encounter when reading other people's code. Finally, while the '> 0' bit part works in this situation, it is not very robust since any, to quote, "non-zero/non-empty" is true. Thus, '!= 0' should be used instead of '> 0', so that this long form will work in all situations. ---------- -- John Posner, Editor jjp@oreilly.com O'Reilly & Associates 860-663-3147 From jsydik@virtualparadigm.com Tue Jun 6 18:23:46 2000 From: jsydik@virtualparadigm.com (Jeremy J. Sydik) Date: Tue, 06 Jun 2000 12:23:46 -0500 Subject: [Edu-sig] RE: Long Boolean expressions References: <003401bfcfd8$e65c7dd0$6e64fea9@jake> Message-ID: <393D33A2.98C7C067@virtualparadigm.com> Even with this consideration, I would have to disagree, ESPECIALLY if we're looking at the pedagogical issues of educating programmers. I agree with your intent that > 0 makes more sense in some cases, but probably not these. The first case is a comparison of len(str), which should ALWAYS be a natural number. To me, != should be used whenever the comparison is against a singleton set (in this case 0). In the other case, the discussion is about numbers in Z/mod N. Again, I think we're looking at the "single" congruence class 0 mod N, and it should IMO be remembered that -a mod N has it's own meaning. I'll just toss the 0.02 in the don't jar Jeremy J. Sydik John Posner wrote: . . . > My one (slight) objection is your wanting to change: > > * the comparison operation "> 0", which is firmly in the numerical realm > > * to the comparison operation "!= 0", which is more in the logical realm > ("not equal to FALSE") > From pdx4d@teleport.com Tue Jun 6 18:28:29 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Tue, 06 Jun 2000 10:28:29 -0700 Subject: [Edu-sig] RE: Long Boolean expressions In-Reply-To: <003401bfcfd8$e65c7dd0$6e64fea9@jake> Message-ID: <3.0.3.32.20000606102829.0327abdc@pop.teleport.com> At 01:00 PM 06/06/2000 -0400, John Posner wrote: >Hi, Gordon -- > >I agree with your analysis almost completely. I was aiming my implementation >at the person who is (1) learning computer programming and (2) learning >Python. To which I'm adding (3) learning math (including math algorithms dating to pre-computer days). Kirby From pdx4d@teleport.com Tue Jun 6 20:16:54 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Tue, 06 Jun 2000 12:16:54 -0700 Subject: [Edu-sig] More re the Urner Approach to CP4E (computer programming for everybody) In-Reply-To: <3.0.3.32.20000606102829.0327abdc@pop.teleport.com> References: <003401bfcfd8$e65c7dd0$6e64fea9@jake> Message-ID: <3.0.3.32.20000606121654.03383548@pop.teleport.com> My logic is simple: #1 Everybody should learn some math (a cultural given) #2 These days, that means some programming (extrapolation) ->> Ergo, everybody should learn some programming Easy languages like Python, plus the fact that calculators have already trailblazed a place for high tech in math ed, make extrapolation #2 reasonable. CP4E doesn't mean "everybody becomes a programmer" any more than universal math (UM4E) means "everybody becomes a mathematician". What I'm resisting, with this approach, is the idea that we need to teach "beginner programming" and "beginner math" as two separate subjects, each with its own text books, web sites, teachers, jargon. That'd phase in too much redundancy in a curriculum that's already way too overspecialize and fragmented as it is, as per this quote by mathematician and luminary David Hestenes: http://www.egroups.com/message/synergeo/812 Text books like 'Concrete Mathematics' (Knuth et al, used at Stanford), give a good idea of how the numeracy + computer literacy genre is already well-established at the college level. What I'm attempting in my 'Numeracy + Computer Literacy' series, is to "lower a ladder" to teachers working closer to the high school level (or closer to my prototypical projection of what _could_ be considered the high school level -- in a possible near future).[1] But one might ask: even if we _start_ with early math ed and programming concepts in the same incubator, at some point the two will need to grow apart. For example, how would a math class make use of this idea of "objects", as in object oriented programming. I'm glad I asked this question. I've done some thinking about that, and think that when it comes to "OOP meets math", the way to go is: Polyhedra as Paradigm Objects.[2] Where else do computers strut their stuff so effectively, as in this realm of spatial geometry (aka "videogame heaven")? And what is more purely mathematical and geometric, since ancient times, than the polyhedra (Platonic, Archimedean, and all the rest of it)? With Polyhedra, you can have a superclass (Poly) and a lot of subclasses (Tetra, Octa, Icosa...), with methods for scaling, rotating, translating at the Poly level (once, for all), and data specific to each specific poly (e.g. faces, coordinates), defined at the subclass level. Like this: class Poly: # superclass # generic methods go here def rotate(self,axis,degrees) def scale(self,scalefactor) def translate(self,vector) class Tetra(Poly): # subclass of Poly faces = [('A','B','C'),...] volume = 1 class Octa(Poly) # subclass of Poly faces = [('I','J','K'),...] volume = 4 .... I've already implemented the above design in several ways, in Python, Java, and Xbase. Works well, and gets us nifty graphics, in Povray, VRML.[3] But I'm not saying everybody needs to use my source code. No, I'm just saying this _idea_ (of Polys as paradigm OOP objects) makes plenty of sense, is a potential "grand central station" for convergent trains of thought, a place from which to branch into numerous related areas. Plus here's what, for me, is the clincher. Recent advances in pedagogy around polyhedra owing to the lifework of R. Buckminster Fuller is a way to get a foot in the door for a new brand of futurism that actually has a strong track record already.[4] With "design science" making inroads in K-12 (i.e. pre-college curriculum), we have the option to give kids inspiring and hopeful (realistic, attainable) visions of positive futures, much as we did in Apollo days.[5] So for me, it's a pretty much a no brainer at this point: CP4E, OOP with polyhedra, and RBF's concentric hierarchy, with links to American Lit and positive futurism (lots of Hollywood potential -- but a lot less escapist/phoney/fake than "24th Century Federation Science", which is blockbuster stuff, certainly, but not backed up by real know-how, the way "Bucky Works" already is (Spaceship Earth is much more a present reality than Starship Enterprise -- so let's get on with the show!)).[6] Kirby [1] http://www.inetarena.com/~pdx4d/ocn/numeracy0.html [2] http://www.inetarena.com/~pdx4d/ocn/trends2000.html [3] http://www.inetarena.com/~pdx4d/ocn/oop.html [4] http://www.inetarena.com/~pdx4d/volumes.html [5] http://www.teleport.com/~pdx4d/bworks.html [6] http://www.teleport.com/~pdx4d/pr.html From toconnor@vcd.hp.com Wed Jun 7 17:18:32 2000 From: toconnor@vcd.hp.com (Thomas O'Connor) Date: Wed, 07 Jun 2000 09:18:32 -0700 Subject: [Edu-sig] The Urner Approach to CP4E In-Reply-To: Your message of "Tue, 06 Jun 2000 12:16:54 PDT." <3.0.3.32.20000606121654.03383548@pop.teleport.com> Message-ID: <200006071618.JAA03013@hpvcpjm.vcd.hp.com> ----------> Kirby Urner wrote: > My logic is simple: > > #1 Everybody should learn some math (a cultural given) > #2 These days, that means some programming (extrapolation) > > ->> Ergo, everybody should learn some programming I am a software engineer, former health phsicist (a sub-field of nuclear engineering), currently working with a local high school on a program to promote community partnerships. The objective is to involve professional scientists and engineers in secondary education for the purpose of bringing real world context to math and science curricula. In other words, we are trying to answer the student question: "When am I ever going to use this stuff?" This is largely where my interest in CP4E comes in. While a computer geek, I am not particularly enthusiastic about the use of technology in education. I spend a considerable amount of time sitting in the school observing, and what I observe is a system that cannot afford pens for classroom white boards or specimines for hands-on science, and that treats teachers like hourly assembly line operators constantly expecting them to do more with less. Yet the schools seem to have an enormous budgets for soon to be obsolete computers whose effectiveness in improving education is of dubious value. That said, I will come to the defense Kirby Urner's approach to connecting math and programming. If I understand Kirby's approach correctly, the objective is not to teach programming, it is to use programming as a tool for manipulating abstract concepts. It is the same as handling and manipulating a mechanical assembly in order to understand an isometric drawing of that assembly. With experience, the abstract drawings will reveal themselves without having to resort to physical manipulation, but without the opportunity to do the physical manipulation, the drawings are just a bunch of lines scribbled on paper. Speaking for myself, programming made abstract concepts like functions and variable substition concrete. It enlightened my view of mathematics. It is, I believe, a reasonable and effective use of technology in the classroom. Tom O'Connor From pdx4d@teleport.com Wed Jun 7 18:56:08 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Wed, 07 Jun 2000 10:56:08 -0700 Subject: [Edu-sig] The Urner Approach to CP4E In-Reply-To: <200006071618.JAA03013@hpvcpjm.vcd.hp.com> References: Message-ID: <3.0.3.32.20000607105608.0323ccc0@pop.teleport.com> >That said, I will come to the defense Kirby Urner's approach to >connecting math and programming. If I understand Kirby's approach >correctly, the objective is not to teach programming, it is to use >programming as a tool for manipulating abstract concepts. That's certainly part of it. You could say ordinary math notation is likewise a tool for manipulating abstract concepts. A typical high school math book will introduce SIGMA (capital greek letter -- zig zag). SIGMA works against an indexed list of terms, by summing them together. For some reason, PI (not lower case pi, which is 3.14159...) is rarely introduced at the same time, even though it's a completely parallel operator, and works by multiplying, instead of summing. I'd probably introduce both of these operators at the same time, and then go straight to the Python versions: >>> from operator import mul,add >>> def sum(terms): return reduce(add,terms) >>> def product(terms): return reduce(mul,terms) Usages: >>> myterms = [1,2,3,4,5] >>> sum(myterms) 15 >>> product(myterms) 120 I don't see the Python way of expressing these operations to be intrinsically more or less cryptic than using capital Greek letters. We should remind ourselves of the history of curriculum writing. In the old days, early 1900s and before, it was the norm to learn some ancient Greek and Latin. Kids were being drilled in the greek alphabet _anyway_ (i.e. outside the math classroom context). But this is no longer the case, and the greek alphabet is not being reinforced very effectively in the "language lab" context. On the other hand, batching commands into executable scripts and feeding these to a microprocessor is _very much_ part of the cultural ambience. It's going on everywhere, but was not at the turn of the century. So I would argue that phasing in something like "Python notation" in parallel with the more traditional forms is a way to restore relevance, to integrate content -- and to fill a void left by the demise of ancient Latin and Greek as second languages (to at least a rudimentary degree of fluency). In sum, I think there's a prejudice, with a long history, which goes something like this: "math books full of geeky greek symbols are 'more abstract' and hence 'closer to the real ideas' than are books full of computer algorithms written in ASCII". Whereas I would agree that the greek-enabled notations are often more compressed, and also more cryptic sometimes (I use the adjective "crypto-compressed"), I don't think computer languages are really all that "second class" (in the sense of, once you understand math, you'll throw away these training wheels and just use the "straight stuff" i.e. the Greek letter operators). What I'm saying is that from here on out, we're going to be looking at pre-computer notations and computer languages as parallel/convergent. With the advent of unicode, and the ability to actually deploy Greek letters as operators, e.g. def SIGMA (<-- greek character goes here), the distinction between "standard math notation" and "computer code" is going to further erode (MathCad is a good example of this -- already lets users program using a lot of the standard notations). Kirby From djmitche@midway.uchicago.edu Thu Jun 8 20:33:06 2000 From: djmitche@midway.uchicago.edu (Dustin James Mitchell) Date: Thu, 8 Jun 2000 14:33:06 -0500 (CDT) Subject: [Edu-sig] Kirby Urner's Sieve of Eratosthenes In-Reply-To: <3.0.3.32.20000605120708.00789d24@pop.teleport.com> Message-ID: On Mon, 5 Jun 2000, Kirby Urner wrote: > PS: Dustin, would your agree that reduce(mul,terms) and > reduce(add,terms) are a useful way to introduce sums and > products, corresponding to geeky greek symbols capital > SIGMA and capital PI. In other words: > > from operator import mul,add > > def sum(terms): > """Same as SIGMA (terms is a list)""" > return reduce(add,terms) > > def product(terms): > """Same as PI (terms is a list)""" > return reduce(mul,terms) > > Would these be useful as "math through programming" > Python definitions? > > Note: n! would be the same as product( range(1,n+1) ). I like this, and it's extremely compact, but I would start by simply using sum() and product() as black-box operators, and only delving into their implementation a little bit later (but still before using filters). Dustin --------------------------------------------------------------------- | Dustin Mitchell )O( | --------------------------------------------------------------------- From pdx4d@teleport.com Fri Jun 16 00:41:10 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Thu, 15 Jun 2000 16:41:10 -0700 Subject: [Edu-sig] CP4E and the Python thread In-Reply-To: References: <3.0.3.32.20000605120708.00789d24@pop.teleport.com> Message-ID: <3.0.3.32.20000615164110.03391444@127.0.0.1> I've continued to share re my "math through programming" vision (these days Python-centric), on the Math Forum, in many ways the hub website for the math educator community. Here's an example thread: http://mathforum.com/epigone/k12.ed.math/tahwhawar (first post of June 6 is almost verbatim something from here -- fixed a typo -- followed by two additional posts, so far, Brian Harvey's of June 7 and mine of June 12). As some of you know, Python is one of several threads weaving in to my "PowerPoint presentation" (just came back from one of those seminars where all the presenters have laptops and use PowerPoint to help them walk through their talk). Among other items of interest re my school of thought (PowerPoint slide): We... =================== At the Oregon Curriculum Network website we: * Use Polyhedra to introduce OOP[1] * Organize Polyhedra as per the Fuller hieararchy (FH) -- R. Buckminster Fuller being the futurist, and geodesic dome guy)[2] * Use a sphere packing lattice for context (not just XYZ)[3] * Use triangular packing (not just grid of squares) * Develop Pascal's Triangle (PT) as a tandem "hub" for basing math explorations (i.e. PT + FH in sphere packing context) =================== In other words, there's an aesthetic/theme (as in "desktop theme" for you Windows user) which converges with Python for me (Python having its own thematics, e.g. Monty Python plus assorted snakes, and lets not forget personalities). Another slide: =================== CP4E = Numeracy + Computer Literacy Logic: All need to learn some math Some math means some programming (these days) Ergo: All need to learn some programming OCN approach: (just one of a great many feasible): Python + Povray + HTML ... start somewhere, add more tools/skills as you go =================== Another slide: =================== Math content: Fuller's Hierarchy (FH) Volume table Sphere packing context FCC/HCP/BCC/SC (IVM) Jitterbug Transformation Angle/Frequency distinction Principles/Cases distinction Pascal's Triangle (PT) Triangular Numbers Tetrahedral Numbers Fibonacci Numbers Phi Binomial Theorem Pascal's Tetrahedron Prime numbers in... Trinomial Theorem Gaussian distribution (Bell Curves) Probability and Permutations =================== My seminars these last two days weren't anything to do with Python or math ed (directly), had more to do with organ transplants and "cadaverous livers" (there's a connection here to "The Meaning of Life" however, as in: "but I'm _using_ it!").[4] I gave myself permission to go to towards the deep end of the pool in http://mathforum.com/epigone/math.teaching.technology/freldskeldky discussing in my 2nd post how to generalize from simple domain/range lingo to a more overview/big picture perspective, ala NASA-style computer-enabled countdowns (t-minus whatever) to whatever milestones (e.g. liftoff). Then I assure people I'm not trying to crush more spiritual vocabularies by sounding to "techno" all the time (on the contrary, I'm leaving that door wide open) -- a kind of reassurance I'm sure others would rather not see. Only after posting this meditation did I discover Dr. Knuth's lengthy lecture series on God and Computers at MIT, viewable/hearable via the web thanks to Dr. Dobbs Journal.[5] OK, well that works. Knuth has already figured prominently in my posts to this list. He's a "weighty Friend" (as we Quakers say -- nevermind that Knuth is a Lutheran by the sound of it). This helps provide balance/ballast -- I don't want my school of thought to degenerate into purely cult-like aesthetics (remembering what Matthias said about Pythoneers being cultish -- a warning from a sage).[6] Kirby Curriculum writer Oregon Curriculum Network [1] http://www.inetarena.com/~pdx4d/ocn/oop.html [2] http://www.bfi.org/ [3] http://www.teleport.com/~pdx4d/octet.html [4] http://www.montypython.net/sounds/meaning/liver.wav [5] http://www.technetcast.com/tnc_program.html?program_id=50 [6] http://forum.swarthmore.edu/epigone/amte/snuquoiyor (see Feb 1 post) From humbert@hagen.de Fri Jun 16 19:42:39 2000 From: humbert@hagen.de (L. Humbert) Date: Fri, 16 Jun 2000 20:42:39 +0200 Subject: [Edu-sig] RE: CP4E and the Python thread (Kirby Urner) Message-ID: <00061620510602.01150@haspe> Hi Kirby Urner, hi pythoners, hi teachers, hi developers,=20 after reading the above mentioned mail with the "math through programming= " vision, I want to tell you, how to produce nice *.PDF-Files with Python. So you can switch from ppt to PDF.=20 You may take a look at: http://www.reportlab.com/ There you will find tools to create well formed and layouted PDF-Files an= d a method for doing this with xml-Sources, which is converted to PDF by PythonPoint. I used it with impressive results.=20 =09L. Humbert From addyd@unk.edu Tue Jun 20 16:57:44 2000 From: addyd@unk.edu (addyd@unk.edu) Date: Tue, 20 Jun 2000 10:57:44 -0500 Subject: [Edu-sig] Perhaps we need a Python tutorial with this approach... Message-ID: Perhaps a writer out there would like to take this approach? From a review of the book "Who's Afraid of C++?" by Steve Heller: http://slashdot.org/article.pl?sid=00/06/09/2153222&mode=thread In his unique approach, Steve Heller presents programming concepts and information as a conversation between teacher and student. Breaking with traditional lecture-on-paper format, Heller demystifies computers, programming, and C++ for absolute beginners. That's right -- he recruited a full-fledged novice user, capable of little more than e-mail and word processing, and turned her into a decent programmer while reviewing this book. (She became Mrs. Heller shortly after that.) Any computer owner with time, the ability to follow directions, and the willingness to learn could also become a programmer. The resulting text is more of a collaboration, or a commentary. Steve, the author, presents his information and then Susan, the novice, interrupts to ask questions. The big gamble is that her questions are the same that the average reader would ask. It largely pays off, only occasionally belaboring a point. (To be fair, it could also be called 'reinforcing a point.') (more to the review...and reader comments follow at the link given above) Darren Addy Internet Specialist; interim Web Presence Coordinator Information Technology Services University of Nebraska at Kearney From pdx4d@teleport.com Tue Jun 20 17:38:05 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Tue, 20 Jun 2000 09:38:05 -0700 Subject: [Edu-sig] The Zen of Calculus In-Reply-To: Message-ID: <3.0.3.32.20000620093805.0363fe24@127.0.0.1> More embedded math-through-programming using Python at: http://mathforum.com/epigone/calc-reform/vendarblar Thanks to Matthius and Co. for some earlier email discussions of the calculus using DrScheme -- helped me refine a Python deriv function that accepts another function as its parameter (previously I'd been using Xbase for math-through-programming, still my "bread and butter" language). Kirby From arta@NOSPAMx-stream.nl Mon Jun 26 17:27:06 2000 From: arta@NOSPAMx-stream.nl (A[r]TA) Date: Mon, 26 Jun 2000 18:27:06 +0200 Subject: [Edu-sig] socket-module Message-ID: <20000626182511.60156.qmail@hotmail.com> Hi, I'm having a question. Maybe a strange one, but don't blame me. Just a newbie or something like that :-) If you're looking at the source from SOCKET.PY, you see a two classes. One for the socket-object and one for the file-descriptor. But, this module (in Windows) doesn't import anything. And par example: def accept(self): sock, addr = self._sock.accept() return _socketobject(sock), addr This is the accept method. Where can I see the lowest-level-Python-code? I can't see the real code from HOW it's accepting the connection. Is this possible and how? It's basically for me to see the TCP/IP-packages Python is creating....(very low level) A[r]TA -- -Life can kick your ass, but all you got to do is stand up and move on... From guido@python.org Mon Jun 26 21:28:49 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 26 Jun 2000 15:28:49 -0500 Subject: [Edu-sig] socket-module In-Reply-To: Your message of "Mon, 26 Jun 2000 18:27:06 +0200." <20000626182511.60156.qmail@hotmail.com> References: <20000626182511.60156.qmail@hotmail.com> Message-ID: <200006262028.PAA01232@cj20424-a.reston1.va.home.com> > If you're looking at the source from SOCKET.PY, you see a > two classes. One for the socket-object and one for the file-descriptor. > But, this module (in Windows) doesn't import anything. > And par example: > > def accept(self): > sock, addr = self._sock.accept() > return _socketobject(sock), addr > > This is the accept method. Where can I see the lowest-level-Python-code? > I can't see the real code from HOW it's accepting the connection. > Is this possible and how? It's basically for me to see the TCP/IP-packages > Python is creating....(very low level) The lowest level code is imported at the top by the statement "from _socket import *". This imports a module written in C. If you have a Python source distribution, you can find it at Modules/socketmodule.c. Source code is also on-line in the CVS tree: http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/python/dist/src/Modules/socketmodule.c?cvsroot=python --Guido van Rossum (home page: http://www.python.org/~guido/) From nhv@cape.com Mon Jun 26 20:19:18 2000 From: nhv@cape.com (Norman Vine) Date: Mon, 26 Jun 2000 15:19:18 -0400 Subject: [Edu-sig] socket-module In-Reply-To: <20000626182511.60156.qmail@hotmail.com> Message-ID: <000401bfdfa3$712e8280$ce36ba8c@nhv> A[r]TA writes: > >I'm having a question. Maybe a strange one, but don't blame me. Just >a newbie or something like that :-) > >If you're looking at the source from SOCKET.PY, you see a >two classes. One for the socket-object and one for the file-descriptor. >But, this module (in Windows) doesn't import anything. >And par example: > >def accept(self): > sock, addr = self._sock.accept() > return _socketobject(sock), addr > >This is the accept method. Where can I see the >lowest-level-Python-code? >I can't see the real code from HOW it's accepting the connection. >Is this possible and how? It's basically for me to see the >TCP/IP-packages >Python is creating....(very low level) > You have to go to the 'C' sourcefile src / modules / socketmodule.c Unfortunately because of the inherent system dependencies of socket code this is one of the more difficult modules to follow. socking-it-to-you-low-levelly Norman From addyd@unk.edu Mon Jun 26 22:26:22 2000 From: addyd@unk.edu (addyd@unk.edu) Date: Mon, 26 Jun 2000 16:26:22 -0500 Subject: [Edu-sig] =?iso-8859-1?q?=01=01Howto=3A_MacPython_and_Tkinter?= Message-ID: I see that earlier there was a discussion regarding Mac support for Python and references were made to problems with Tkinter on Macs. I ran across the following reference as to why the problem occurs and how to get around it. If you were already aware of this info when the discussion was held, I apologize. http://schockwellenreiter.editthispage.com/python/tkinterenglish.html Darren Addy Internet Specialist and Interim Web Presence Coordinator Office of Information Technology Services University of Nebraska at Kearney From djmitche@cs.uchicago.edu Tue Jun 27 18:47:01 2000 From: djmitche@cs.uchicago.edu (Dustin James Mitchell) Date: Tue, 27 Jun 2000 12:47:01 -0500 (CDT) Subject: [Edu-sig] socket-module In-Reply-To: <20000626182511.60156.qmail@hotmail.com> Message-ID: On Mon, 26 Jun 2000, A[r]TA wrote: > This is the accept method. Where can I see the lowest-level-Python-code? > I can't see the real code from HOW it's accepting the connection. > Is this possible and how? It's basically for me to see the TCP/IP-packages > Python is creating....(very low level) This is as low as the python code gets -- it's calling native C functions somewhere, which further call the kernel to open the sockets and read and write data. Which is also to say that Python is not operating at the packet level -- far from it. Python is calling C functions such as socket(), read(), write(), and close(). All of the packet-level stuff is taken care of in the kernel. There are ways to peek at the packets themselves, with only a little bit of C programming involved. But not directly from Python. If you're interested in this, I recommend books by the late W. Richard Stevens. I don't have the titles handy, but everything he's written is excellent (and absolutely packed with every detail you need to build networked software). The books are not, however, for the faint of heart. Dustin --------------------------------------------------------------------- | Dustin Mitchell )O( | --------------------------------------------------------------------- From arta@x-stream.nl Wed Jun 28 18:26:27 2000 From: arta@x-stream.nl (A[r]TA) Date: Wed, 28 Jun 2000 19:26:27 +0200 Subject: [Edu-sig] Re: socket-module References: <20000627160426.CECD21D153@dinsdale.python.org> Message-ID: <000a01bfe12e$4a909dc0$56ca8bd4@vincent> > The lowest level code is imported at the top by the statement "from > _socket import *". This imports a module written in C. If you have a > Python source distribution, you can find it at Modules/socketmodule.c. I've been looking there, and for the socket.send-option I found this: /* s.send(data [,flags]) method */ static PyObject * BUILD_FUNC_DEF_2(PySocketSock_send,PySocketSockObject *,s, PyObject *,args) { char *buf; int len, n, flags = 0; if (!PyArg_ParseTuple(args, "s#|i", &buf, &len, &flags)) return NULL; Py_BEGIN_ALLOW_THREADS n = send(s->sock_fd, buf, len, flags); Py_END_ALLOW_THREADS if (n < 0) return PySocket_Err(); return PyInt_FromLong((long)n); } static char send_doc[] = "send(data[, flags])\n\ \n\ Send a data string to the socket. For the optional flags\n\ argument, see the Unix manual."; -----------END CUT--------------- A stupid question maybe. I want to find the parts where is described HOW a TCP-packet is created. Something like: -IP from sender -IP from receiver -data Is it possible? A[r]TA -Life can kick your ass, but all you got to do is stand up and move on... From jeremy@beopen.com Thu Jun 29 17:31:19 2000 From: jeremy@beopen.com (Jeremy Hylton) Date: Thu, 29 Jun 2000 12:31:19 -0400 (EDT) Subject: [Edu-sig] Re: socket-module In-Reply-To: <000a01bfe12e$4a909dc0$56ca8bd4@vincent> References: <20000627160426.CECD21D153@dinsdale.python.org> <000a01bfe12e$4a909dc0$56ca8bd4@vincent> Message-ID: <14683.31191.155112.521340@bitdiddle.concentric.net> >>>>> "A" == writes: A> A stupid question maybe. I want to find the parts where is A> described HOW a TCP-packet is created. Something like: A> -IP from sender A> -IP from receiver A> -data A> Is it possible? The socket interface hides the all the details of TCP/IP from you. If you call send on a socket, the socket library implementation handles all the details. It handles buffering of the data, putting into appropriately-sized TCP packets, retransmission of packets, etc. If you're interested in TCP at that level of detail, you're going to have to look at a TCP stack implementation in the OS kernel. I *strongly* recommend W. Richard Steven's TCP/IP Illustrated series if you go this route. http://www.kohala.com/start/tcpipiv1.html -- protocols http://www.kohala.com/start/tcpipiv2.html -- BSD implementation One thing you can play with is sending raw IP packets, using the a socket create with the SOCK_RAW protocol. I believe this just works on Windows, but requires a setuid root script on Unix. An example: s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) The OS kernel still does some work for you in this case. The only example I can think of is that it computes the checksum for the packet. My ping and traceroute code in Python, while a little buggy and out of date, might get you started. http://www-tech.mit.edu/~jeremy/python/ Jeremy From mmoelter@calpoly.edu Fri Jun 30 01:30:49 2000 From: mmoelter@calpoly.edu (Matthew J. Moelter) Date: Thu, 29 Jun 2000 17:30:49 -0700 Subject: [Edu-sig] beginner trouble, indexing starting w/"0" Message-ID: <395BDF0C.FAA556A7@calpoly.edu> I have been following the Python edu-sig list for a while and in the spirit of observing a "beginner" I decided to show my dad some Python. (He is a long-ago-retired high school math teacher with virtually no programming experience.) Below is how far our session got before we had "trouble": Python 1.6a2 (#54, May 6 2000, 00:26:29) [CW PPC w/GUSI2 w/THREADS] Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> s='Matthew' >>> print s Matthew >>> s 'Matthew' >>> len(s) 7 >>> s[1] 'a' >>> s[0] 'M' >>> While he understood the idea of indexing fine he didn't understand the first element being indexed with "0". When he taught vectors or matrices to the students they usually indexed from 1 to N (vectors), or 1 to N by 1 to M (matrices). The upper left element in a matrix was A(1,1) or something. If this is truly the way Python is configured it seems to me that this could be an important stumbling block. I do not know enough about Python myself to see if this is a necessary approach or if it can/could be changed. Or could it be changed at the users option? "starting index=1" or something? Matt *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- Matthew J. Moelter office: (805) 756-2065 Department of Physics email: mmoelter@calpoly.edu Calif Polytechnic State Univ fax: (805) 756-2435 San Luis Obispo, CA 93407 From jcm@bigskytel.com Fri Jun 30 02:45:33 2000 From: jcm@bigskytel.com (David Porter) Date: Thu, 29 Jun 2000 19:45:33 -0600 Subject: [Edu-sig] beginner trouble, indexing starting w/"0" In-Reply-To: <395BDF0C.FAA556A7@calpoly.edu>; from mmoelter@calpoly.edu on Thu, Jun 29, 2000 at 05:30:49PM -0700 References: <395BDF0C.FAA556A7@calpoly.edu> Message-ID: <20000629194533.A21537@novara.avenue> * Matthew J. Moelter : > I have been following the Python edu-sig list for a while and > in the spirit of observing a "beginner" I decided to show my > dad some Python. (He is a long-ago-retired high school math teacher > with virtually no programming experience.) > > Below is how far our session got before we had "trouble": > > Python 1.6a2 (#54, May 6 2000, 00:26:29) [CW PPC w/GUSI2 w/THREADS] > Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam > >>> s='Matthew' > >>> print s > Matthew > >>> s > 'Matthew' > >>> len(s) > 7 > >>> s[1] > 'a' > >>> s[0] > 'M' > >>> > > While he understood the idea of indexing fine he didn't > understand the first element being indexed with "0". It helped me to visualize it like this: 0 1 2 3 4 5 6 7 |M|a|t|t|h|e|w| -1 0 s[1:3] makes a slice at the numbers, returning 'at'. For s[2] it does the same, just with one item. Also s[-1], which returns 'w'. > I do not know enough about Python myself to see if this is a > necessary approach or if it can/could be changed. Or could it be > changed at the users option? "starting index=1" or something? What if it started at 1? 1 2 3 4 5 6 7 8 |M|a|t|t|h|e|w| -1 0 1 Now, this is even more confusing when trying to use negative indexes. s[1] returns 'M', but s[0] returns 'w', and s[-1] returns 'e'. That is even more confusing to me. While it is confusing at first, once it is visualized as slices and indexes, as above, it seems to me to be the best approach. David. From pdx4d@teleport.com Fri Jun 30 03:22:45 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Thu, 29 Jun 2000 19:22:45 -0700 Subject: [Edu-sig] beginner trouble, indexing starting w/"0" In-Reply-To: <395BDF0C.FAA556A7@calpoly.edu> Message-ID: <3.0.3.32.20000629192245.006986f0@pop.teleport.com> >If this is truly the way Python is configured it seems to me >that this could be an important stumbling block. Hi Matthew -- Whereas in linear algebra texts matrices and vectors are indexed as you describe, all the same matrix and vector ops work fine if your origin for indexing is 0 instead of 1. In other math texts, initial terms in sequences, or initial state variables, are zero-subscripted by convention. Certainly sigma notation doesn't care where you start -- lots of times you find i = 0 to N (just another parameter to deal with, all in a day's work). When it comes to math notations, you encounter lots of arbitrary conventions at every turn -- nothing new with Python. What's more important, for a computer language especially, is reliable adherence to the rules at run time, once they're globally defined at design time. In sum, we should look at indexing as one of those cultural variables that one simply learns about and comes to see as relatively unimportant. Some eat with chopsticks, some use a knife and fork. Ultimately, food is food, and eating is eating. I think it's good to teach that there's not just "one right way" to do these things. Kirby From djmitche@cs.uchicago.edu Fri Jun 30 15:16:34 2000 From: djmitche@cs.uchicago.edu (Dustin James Mitchell) Date: Fri, 30 Jun 2000 09:16:34 -0500 (CDT) Subject: [Edu-sig] beginner trouble, indexing starting w/"0" In-Reply-To: <395BDF0C.FAA556A7@calpoly.edu> Message-ID: On Thu, 29 Jun 2000, Matthew J. Moelter wrote: > While he understood the idea of indexing fine he didn't > understand the first element being indexed with "0". > When he taught vectors or matrices to the students they usually > indexed from 1 to N (vectors), or 1 to N by 1 to M (matrices). > The upper left element in a matrix was A(1,1) or something. > > If this is truly the way Python is configured it seems to me > that this could be an important stumbling block. > I do not know enough about Python myself to see if this is a > necessary approach or if it can/could be changed. Or could it be > changed at the users option? "starting index=1" or something? This is a common problem for those on the border between mathematics and computers. The reason that it's done this way is due to the way computers index things internally. If we want to start indexing at 1 (or (1,1)), then the processor must do some extra work on every array indexing operation, which slows things down. It's possible to change this when you're writing your own class, e.g. class Matrix: ... def get(self,i,j): return self.data[i-1][j-1] or the like. I like your suggestion of making it a user-settable flag (perhaps a command-line switch as well?). Anyone else feel strongly on this issue of modifying Python? Dustin --------------------------------------------------------------------- | Dustin Mitchell )O( | --------------------------------------------------------------------- From fig@oreilly.com Fri Jun 30 15:20:00 2000 From: fig@oreilly.com (Stephen R. Figgins) Date: Fri, 30 Jun 2000 07:20:00 -0700 Subject: [Edu-sig] beginner trouble, indexing starting w/"0" Message-ID: <200006301420.HAA09747@rock.west.ora.com> >While he understood the idea of indexing fine he didn't >understand the first element being indexed with "0". >When he taught vectors or matrices to the students they usually >indexed from 1 to N (vectors), or 1 to N by 1 to M (matrices). >The upper left element in a matrix was A(1,1) or something. This is true, but on the other hand, if he were to graph a vector, like say (4,3) he would start the vector from x and y coordinates (0,0). What he ran into is the same problem that every kid runs into when they start drawing the number line, and realize they need to start from 0, not 1. Most programming languages extend that concept to array indeces. It is a stumbling block, but a very small one, and you learn something in the stumble. Not all stumbles are bad ones. Stephen From senator@sgi.net Fri Jun 30 17:19:30 2000 From: senator@sgi.net (Bill Bradley) Date: Fri, 30 Jun 2000 12:19:30 -0400 Subject: [Edu-sig] beginner trouble, indexing starting w/"0" References: Message-ID: <395CC892.7A0614CD@sgi.net> When I was teaching C++ I just explained that it was an "offset" (which in reality it is in C, the location of each element is calculated by adding the offset*sizeof(type) to the pointer address of the array) which seemed to satisfy those asking why arrays start with zero, but are declared by size. Bill From pdx4d@teleport.com Fri Jun 30 23:43:46 2000 From: pdx4d@teleport.com (Kirby Urner) Date: Fri, 30 Jun 2000 15:43:46 -0700 Subject: [Edu-sig] sample PowerPoint presentation Message-ID: <3.0.3.32.20000630154346.0076fb78@pop.teleport.com> Greetings educators -- For those of you with PowerPoint and/or the requisite browser plug-ins, I've tossed a slide show on the web at: ftp://ftp.teleport.com/pub/users/pdx4d/images/synergeo.ppt This is my standard 'Beyond Flatland' curriculum, wherein I mix spatial geometry, virtual worlds, computer programming (these days Python), and synergetics. Given this is just an outline of a talk, there's not a lot of discussion (few words). To present this material effectively, you'd need to study the background readings e.g. http://www.inetarena.com/~pdx4d/ocn/cp4e.html (see 'Numeracy + Computer Literacy' series). Feedback welcome. Kirby 4D Solutions PS: the file is approx 625K