From kirby.urner at gmail.com Thu Dec 3 13:47:12 2015 From: kirby.urner at gmail.com (kirby urner) Date: Thu, 3 Dec 2015 10:47:12 -0800 Subject: [Edu-sig] relevant blog posting re pre-college CS topics & Python Message-ID: http://controlroom.blogspot.com/2015/12/mathy-memes.html Kirby -------------- next part -------------- An HTML attachment was scrubbed... URL: From kirby.urner at gmail.com Thu Dec 3 20:23:34 2015 From: kirby.urner at gmail.com (kirby urner) Date: Thu, 3 Dec 2015 17:23:34 -0800 Subject: [Edu-sig] time passing: ramanujan and pi Message-ID: Looking back: https://mail.python.org/pipermail/edu-sig/2006-September/006963.html shows me still importing __division__ and relying on some factorial off state. Tonight, preparing for class, I'm able to rely on math.factorial, introduce other improvements. # -*- coding: utf-8 -*- """ Created on Thu Dec 3 16:40:46 2015 See: https://crypto.stanford.edu/pbc/notes/pi/ramanujan.html @author: kurner LAB: Write a unittest to confirm convergence to: '3.141592653589793238462643383279502884197169 39937510582097494459230781640628620899862803 48253421170' after n steps (this is the answer key version) """ import unittest from decimal import * from math import factorial as fact def pieinsky(): c1 = Decimal(4) c2 = Decimal(1103) c3 = Decimal(26390) c4 = Decimal(396) c5 = Decimal(9801) # code formatted for readability (make it be one line) root8 = Decimal('2.82842712474619009760337744841939615' '7139343750753896146353359475981464956' '9242140777007750686552831454700276') i = Decimal(0) thesum = Decimal(0) while True: term = (fact(c1*i)*(c2 + c3*i))/(pow(fact(i),4)*pow(c4,4*i)) thesum = thesum + term yield 1/((root8/c5)*thesum) i += 1 class TestPi(unittest.TestCase): def test_outcome(self): expected = ('3.141592653589793238462643383' '2795028841971693993751058209749445923078' '164062862089986280348253421170') with localcontext() as c: c.prec = 100 the_gen = pieinsky() for _ in range(20): next(the_gen) self.assertEqual(str(next(the_gen))[:len(expected)], expected) if __name__ == "__main__": unittest.main() -------------- next part -------------- An HTML attachment was scrubbed... URL: From kirby.urner at gmail.com Thu Dec 3 21:03:51 2015 From: kirby.urner at gmail.com (kirby urner) Date: Thu, 3 Dec 2015 18:03:51 -0800 Subject: [Edu-sig] introducing euler's number Message-ID: Again from tonight's class prep. Such scripts might be useful exhibits if you're still trying to get approval to move beyond a TI calculator in math class. Playing with extended precision helps bring the concepts of limits and convergence alive. My students are employed adults so winning such approval is a non-issue. But then I ask them to imagine themselves back in school, with Python a tool of choice in math class. Wouldn't that have been great!? Kirby # -*- coding: utf-8 -*- """ Created on Thu Dec 3 16:40:46 2015 See: http://www.miniwebtool.com/first-n-digits-of-e/?number=300 @author: kurner LAB: Write a unittest to confirm convergence to e to 300 places. after n steps. """ import unittest from decimal import * def euler(n): n = Decimal(n) one = Decimal(1) return (one + one/n) ** n class Test_e(unittest.TestCase): def test_outcome(self): expected = ('2.718281828459045235360287471352662' '49775724709369995957496696762772407' '66303535475945713821785251664274274' '66391932003059921817413596629043572' '90033429526059563073813232862794349' '07632338298807531952510190115738341' '87930702154089149934884167509244761' '46066808226480016847741185374234544' '2437107539077744992069') with localcontext() as c: c.prec = 400 result = euler('1' + '0' * 301) self.assertEqual(str(result)[:len(expected)], expected) if __name__ == "__main__": unittest.main() -------------- next part -------------- An HTML attachment was scrubbed... URL: From kirby.urner at gmail.com Fri Dec 4 21:36:08 2015 From: kirby.urner at gmail.com (kirby urner) Date: Fri, 4 Dec 2015 18:36:08 -0800 Subject: [Edu-sig] generating phi as continued fraction (inefficient version) Message-ID: Inefficient, but still kinda fun. I used it last night as an introduction to eval( ). First I take the eval away and show the expression (growing) being generated (it's a generator). 1 + 1/(1) 1 + 1/(1+ 1/(1)) 1 + 1/(1+ 1/(1+ 1/(1))) 1 + 1/(1+ 1/(1+ 1/(1+ 1/(1)))) 1 + 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1))))) 1 + 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1)))))) 1 + 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1))))))) 1 + 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1+ 1/(1)))))))) and so on. Then I switch to eval-ing the expression and, lo and behold, we're approaching phi aren't we. 2.0 1.5 1.6666666666666665 1.6 1.625 1.6153846153846154 1.619047619047619 1.6176470588235294 1.6181818181818182 1.6179775280898876 1.6180555555555556 1.6180257510729614 1.6180371352785146 1.6180327868852458 1.618034447821682 1.618033813400125 1.6180340557275543 1.6180339631667064 1.6180339985218035 1.618033985017358 Way back in the annals of edu-sig, early years, we were digging into HOW-TO re continued fractions and exploring the more optimized algorithms. Sometimes though, it's just the concepts you need -- optimization in another sense. eval( ) and exhibiting a sequence of generators was the theme. I used the pi-digits generator we talked about this September (here on edu-sig), and that one of Ramanujan's, the latter posted here yesterday in Python 3.5 version. Kirby # -*- coding: utf-8 -*- """ Created on Thu Dec 3 16:08:49 2015 @author: kurner Another generator example: converging to Phi Shows eval( ) in action """ def continued(): patt = "+ 1/(1" the_expr = '' # empty n = 1 while True: the_expr = the_expr + patt the_frac = "1 " + the_expr + ")" * n yield eval(the_frac) # or show the_frac n += 1 the_gen = continued() for _ in range(20): print(next(the_gen)) -------------- next part -------------- An HTML attachment was scrubbed... URL: From kirby.urner at gmail.com Thu Dec 10 04:39:29 2015 From: kirby.urner at gmail.com (kirby urner) Date: Thu, 10 Dec 2015 01:39:29 -0800 Subject: [Edu-sig] more from my classroom Message-ID: Here's some more code from the night class I'm teaching, invisibly in the sense it's all virtual, but in real time, different from my usual asynchronous gig based on evaluating student work. About twenty login and we have our private session, company tech support listening in for Q/A. Complementary synchronous work, with students off the hook but welcome and often eager to dive in (I don't see their desktops usually, though they're free to share). The code below started out as a Lab where I just suggested using trial by division (I described the approach) in the context of an iterator. We're just at that point where "iterator" (versus iterable) is coming together with these new grammatical constructs, these new underscore names. We're also tackling decorators and context managers around this same time. # -*- coding: utf-8 -*- """ Created on Tue Dec 8 17:39:27 2015 @author: Kirby Urner, 4Dsolutions.net (copyleft) MIT License, 2015 Two models of iterator that do the same thing. All primes found so far will be a list of all primes <= n without any missing. Algorithm: trial by division. """ def next_prime(): """ creates an iterator that spits out successive prime numbers """ so_far = [2] yield 2 n = 2 while True: n += 1 for divisor in so_far: if divmod(n, divisor)[1] == 0: # goes evenly break if divisor ** 2 > n: yield n so_far.append(n) break class Primes: """ creates an iterator that spits out successive prime numbers """ def __init__(self): self.so_far = [2] self.n = 2 def __iter__(self): return self def __next__(self): if self.n == 2: self.n += 1 return 2 while True: for divisor in self.so_far: if divmod(self.n, divisor)[1] == 0: # goes evenly break if divisor ** 2 > self.n: self.so_far.append(self.n) self.n += 1 return self.so_far[-1] self.n += 1 There's a license on it not because I think I'm being all that original i.e. these is not genius math or anything. I've been told people are more comfortable sharing if there's at least some explicit attention to sharing rights. The point for purposes of my class was to show two ways to write an iterator, using function generator syntax or a class with the __next__, __iter__ protocol. The latter is a refactoring of the former, or vice versa. However, putting on my "used to be a high school math teacher" hat, I really like this naive ramping up into Primeville. As an algorithm it sputters if your goal is working with uber-primes ala RSA or whatever, but this is not about dissing algorithms its about learning what "algorithm" means. Also the difference between prime and composite. I found myself bringing up the Fundamental Theorem of Arithmetic again, just like the old days (I haven't been a full time high school math teach since the early 1980s, spent a lot more years coding in FoxPro :-D). >>> g = next_prime() >>> [next(g) for _ in range(20)] [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] >>> g = Primes() >>> [next(g) for _ in range(20)] [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] Other news from my angle... We're enjoying lots of action on python-cuba (a workgroup) -- some planning conference coming up on the 12th. Public archive, check it out. https://mail.python.org/mailman/listinfo/python-cuba Also I'm sometimes chiming in on the Chipy listserv, one of my favorites. Portland's is quiet by contrast (I'm in Portland -- born in Chicago though). Kirby -------------- next part -------------- An HTML attachment was scrubbed... URL: From chalmer.lowe at gmail.com Thu Dec 10 12:49:59 2015 From: chalmer.lowe at gmail.com (Chalmer Lowe) Date: Thu, 10 Dec 2015 17:49:59 +0000 Subject: [Edu-sig] Python Education Summit 2016 In-Reply-To: References: Message-ID: Team: The Python Education Summit is on again this year at the PyCon in Portland. A couple of things are the same, a couple of things are gonna change... 0) *Keeping the conversation going*: last year, we talked about ways to keep the conversation going through out the year and many of the ideas we suggested never took off. Please join us on the new *PythonEDU Slack Team* (see below) so we can revisit those ideas and see what we can do to increase and improve how we share data and ideas on education and Python. 1) *Slack Team: PythonEDU* - All work by the Planning Committee for the Summit as well as general conversations about the Summit are gonna run through a Slack Team (if you want an invite, let me know... *I have to manually invite folks - weakness of slack, not my preference*). 2) *Volunteer*: we need participants on the Planning Committee >>> if you want to be included in the conversation, let me know so I can add you to the Slack Team. 3) *Call for Papers:* Talk submissions go through the same talk submission process as any other PyCon talk. While I loved the idea of using moderator, as we looked at the logisitics, there were too many weaknesses in that process to continue. You only have til January 3rd to submit talks. Get in there and do it! https://goo.gl/iCKOWY 4) *What to include in the Summit*: We are brainstorming ideas for what to include in the edusummit. The ideas will be hashed out by the Planning Committee. Let us know what you want to see! 5) *Twitter*: our twitter hashtag will be #pythonedu 6) *Registration for the Summit:* There are some glitches that need to be worked out in regards to getting folks registered to participate in the Summit. I am looking into that. More to come. Respectfully, Chalmer Lowe Chairman of the Python Education Summit -- Chalmer Lowe, MS PyHawaii Dark Art of Coding Booz Allen Hamilton -------------- next part -------------- An HTML attachment was scrubbed... URL: From kirby.urner at gmail.com Thu Dec 10 15:18:02 2015 From: kirby.urner at gmail.com (kirby urner) Date: Thu, 10 Dec 2015 12:18:02 -0800 Subject: [Edu-sig] Python Education Summit 2016 In-Reply-To: References: Message-ID: On Thu, Dec 10, 2015 at 9:49 AM, Chalmer Lowe wrote: > Team: > > The Python Education Summit is on again this year at the PyCon in Portland. > > Greetings Chalmer, please send me an invitation if you would. I missed the two Montreal Pycons however I'm a resident of Portland and already registered for the coming one, so it'd be a missed opportunity to miss out on your PythonEDU Slack Team planning. I've not submitted any talk proposals so far. Having been fortunate enough to present quite a bit in the past, at Pycons and OSCONs in particular, I'm still referencing / footnoting those presentations as evidence of what I'm up to and where I'm going -- in case collaboration is an option. These days, I think in terms of "lambda and delta calculus" as the two flavors of math we offer to teens, but we don't brand that way (with the Greek letters). Delta Calc is regular Calculus, which dominates the high school math experience whereas Lambda Calc is "computer science" (or "gnu math" as I sometimes call it). Some students might appreciate more sense of at least two ways to go, with the option to swirl them together. I'd like to get to know more of the people planning on coming to Portland in 2016. What I was saying on Chipy last night, where we were talking about LISP family languages, is I don't see FP (functional programming) and OO (object oriented) as either / or, and would myself like to keep spiraling deeper into a Python - Jython - Java - Clojure circle that eats its own tail. One needs a lot of marbles for all that and I've maybe lost one or two over the years -- but I believe that even late in life, new marbles may be acquired. :-D I've been on edu-sig a long time, having hopped on the Python bandwagon around version 1.6. I'm interested in 3D graphics from a philosophical point of view and was drawn, like the late Arthur Siegel of PyGeo fame [1], to Visual Python (vpython.org). Quite a bit of my Python-in-education writing is been in that domain (VRML, ray tracing... this new book by Popko called Divided Spheres, billed as a primer, nails the domain pretty well ). Here in Portland we have an institution called Saturday Academy for highly motivated kids wanting to do extra-curricular work, and my blogs are have lots of first person accounts of my sharing Python through that school (not a full time job, pays a pittance). In that context, I developed a course called Martian Math [2] which is core to a four-aspect curriculum I share as Digital Mathematics, though I've come nowhere close to achieving the fame of some others doing that. [3] I look forward to meeting you in 2016. Kirby [1] http://python.6.x6.nabble.com/arthur-siegel-has-passed-away-td2108619.html [2] http://www.4dsolutions.net/satacad/martianmath/toc.html [3] https://newrepublic.com/article/124750/man-will-save-math -------------- next part -------------- An HTML attachment was scrubbed... URL: From kirby.urner at gmail.com Thu Dec 17 14:34:46 2015 From: kirby.urner at gmail.com (kirby urner) Date: Thu, 17 Dec 2015 11:34:46 -0800 Subject: [Edu-sig] genetic_code.py (another rich data structure) Message-ID: # -*- coding: utf-8 -*- """ Created on Wed Dec 16 10:07:57 2015 @author: kurner, 4dsolutions (.net) (copyleft MIT license, 2015) Example: Rich Data Structures (for learning Python, including sqlite3) Source: http://www.soc-bdr.org/rds/authors/unit_tables_conversions_and_genetic_dictionaries/e5202/index_en.html Any errors you discover in transcribing will be mine, please let me know and I'll correct my copy as well. kirby.urner at gmail.com Re: "Rich Data Structures" https://mail.python.org/pipermail/edu-sig/2006-June/006608.html (a more obvious need now that "big data" examples are in demand, for learning map/reduce techniques etc.). Indeed, we have many public raw data sets. A goal is to have some already in Python, as ready-to-go native data types. As here. This is not "big data", just data. Another experiment: https://mail.python.org/pipermail/edu-sig/2012-December/010709.html (same caveats about errors) """ amino_acid_abbrevs = \ dict( Phe = 'Phenyalinine', Leu = 'Leucine', Ser = 'Serine', Tyr = 'Tyrosine', Cys = 'Cysteine', Trp = 'Tryptophan', Pro = 'Proline', His = 'Histidine', Gln = 'Glutamine', Arg = 'Arginine', Ile = 'Isoleucine', Met = 'Methionine', Thr = 'Threonine', Asn = 'Asparagine', Lys = 'Lysine', Val = 'Valine', Ala = 'Alanine', Asp = 'Aspartate', Glu = 'Glutamate', Cly = 'Glycine') combos = [(a, b, c) for a in ('G','U','A','C') for b in ('G','U','A','C') for c in ('G','U','A','C')] # Also see: # https://flic.kr/p/BeVwN2 # (American Scientist Vol. 97) mRNA = \ { ('G', 'G', 'G') : 'Gly', ('G', 'G', 'U') : 'Gly', ('G', 'G', 'A') : 'Gly', ('G', 'G', 'C') : 'Gly', ('G', 'U', 'G') : 'Val', ('G', 'U', 'U') : 'Val', ('G', 'U', 'A') : 'Val', ('G', 'U', 'C') : 'Val', ('G', 'A', 'G') : 'Glu', ('G', 'A', 'U') : 'Asp', ('G', 'A', 'A') : 'Glu', ('G', 'A', 'C') : 'Asp', ('G', 'C', 'G') : 'Ala', ('G', 'C', 'U') : 'Ala', ('G', 'C', 'A') : 'Ala', ('G', 'C', 'C') : 'Ala', ('U', 'G', 'G') : 'Trp', ('U', 'G', 'U') : 'Cys', ('U', 'G', 'A') : 'STOP', ('U', 'G', 'C') : 'Cys', ('U', 'U', 'G') : 'Leu', ('U', 'U', 'U') : 'Phe', ('U', 'U', 'A') : 'Leu', ('U', 'U', 'C') : 'Phe', ('U', 'A', 'G') : 'STOP', ('U', 'A', 'U') : 'Tyr', ('U', 'A', 'A') : 'STOP', ('U', 'A', 'C') : 'Tyr', ('U', 'C', 'G') : 'Ser', ('U', 'C', 'U') : 'Ser', ('U', 'C', 'A') : 'Ser', ('U', 'C', 'C') : 'Ser', ('A', 'G', 'G') : 'Arg', ('A', 'G', 'U') : 'Ser', ('A', 'G', 'A') : 'Arg', ('A', 'G', 'C') : 'Ser', ('A', 'U', 'G') : 'Met', ('A', 'U', 'U') : 'Ile', ('A', 'U', 'A') : 'Ile', ('A', 'U', 'C') : 'Ile', ('A', 'A', 'G') : 'Lys', ('A', 'A', 'U') : 'Asn', ('A', 'A', 'A') : 'Lys', ('A', 'A', 'C') : 'Asn', ('A', 'C', 'G') : 'Thr', ('A', 'C', 'U') : 'Thr', ('A', 'C', 'A') : 'Thr', ('A', 'C', 'C') : 'Thr', ('C', 'G', 'G') : 'Arg', ('C', 'G', 'U') : 'Arg', ('C', 'G', 'A') : 'Arg', ('C', 'G', 'C') : 'Arg', ('C', 'U', 'G') : 'Leu', ('C', 'U', 'U') : 'Leu', ('C', 'U', 'A') : 'Leu', ('C', 'U', 'C') : 'Leu', ('C', 'A', 'G') : 'Gln', ('C', 'A', 'U') : 'His', ('C', 'A', 'A') : 'Gln', ('C', 'A', 'C') : 'His', ('C', 'C', 'G') : 'Pro', ('C', 'C', 'U') : 'Pro', ('C', 'C', 'A') : 'Pro', ('C', 'C', 'C') : 'Pro'} # [Ibid, www.soc-bdr.org] from Table 5. Genetic Code: # mRNA condon -> tRNA anti-codon # DNA column dropped (computable, replace mRNA U with T) # last column also not included. tRNA = \ { ('U','U','U'):(('A','A','A'), ('A','A','G')), ('U','U','C'):(('A','A','G'),), ('U','U','A'):(('A','A','U'),), ('U','U','G'):(('A','A','U'),('A','A','C')), ('U','C','U'):(('A','G','I'),('A','G','G'), ('A','G','A')), ('U','C','C'):(('A','G','I'),('A','G','G')), ('U','C','A'):(('A','G','I'),('A','G','U')), ('U','C','G'):(('A','G','C'),('A','G','U')), ('U','A','U'):(('A','U','A'),('A','U','G'),), ('U','A','C'):(('A','U','G'),), ('U','A','A'):(('A','U','U'),), ('U','A','G'):(('A','U','C'),('A','U','U')), ('U','G','U'):(('A','C','A'),('A','C','G')), ('U','G','C'):(('A','C','G'),), ('U','G','A'):(('A','C','U'),), ('U','G','G'):(('A','C','C'),), ('C','U','U'):(('G','A','I'),('G','A','G'),('G','A','A')), ('C','U','C'):(('G','A','I'),('G','A','G')), ('C','U','A'):(('G','A','I'),('G','A','U')), ('C','U','G'):(('G','A','C'),('G','A','U')), ('C','C','U'):(('G','G','I'),('G','G','G'),('G','G','A')), ('C','C','C'):(('G','G','I'),('G','G','G')), ('C','C','A'):(('G','G','I'),('G','G','U')), ('C','C','G'):(('G','G','C'),('G','G','U')), ('C','A','U'):(('G','U','A'),('G','U','G')), ('C','A','C'):(('G','U','G'),), ('C','A','A'):(('G','U','U'),), ('C','A','G'):(('G','U','C'),('G','U','U')), ('C','G','U'):(('G','C','I'),('G','C','G'),('G','C','A')), ('C','G','C'):(('G','C','I'),('G','C','G')), ('C','G','A'):(('G','C','I'),('G','C','U')), ('C','G','G'):(('G','C','C'),('G','C','U')), ('A','U','U'):(('U','A','I'),('U','A','G'),('U','A','A')), ('A','U','C'):(('U','A','I'),('U','A','G')), ('A','U','A'):(('U','A','I'),('U','A','U')), ('A','U','G'):(('U','A','C'),), ('A','C','U'):(('U','G','I'),('U','G','G'),('U','G','A')), ('A','C','C'):(('U','G','I'),('U','G','G')), ('A','C','A'):(('U','G','I'),('U','G','U')), ('A','C','G'):(('U','G','C'),('U','G','U')), ('A','A','U'):(('U','U','A'),('U','U','G')), ('A','A','C'):(('U','U','G'),), ('A','A','A'):(('U','U','U'),), ('A','A','G'):(('U','U','C'),('U','U','U')), ('A','G','U'):(('U','C','A'),('U','C','G')), ('A','G','C'):(('U','C','G'),), ('A','G','A'):(('U','C','U'),), ('A','G','G'):(('U','C','C'),('U','C','U')), ('G','U','U'):(('C','A','I'),('C','A','G'),('C','A','A')), ('G','U','C'):(('C','A','I'),('C','A','G')), ('G','U','A'):(('C','A','I'),('C','A','U')), ('G','U','G'):(('C','A','C'),('C','A','U')), ('G','C','U'):(('C','G','I'),('C','G','G'),('C','G','A')), ('G','C','C'):(('C','G','I'),('C','G','G')), ('G','C','A'):(('C','G','I'),('C','G','U')), ('G','C','G'):(('C','G','C'),('C','G','U')), ('G','A','U'):(('C','U','G'),('C','U','A')), ('G','A','C'):(('C','U','G'),), ('G','A','A'):(('C','U','U'),), ('G','A','G'):(('C','U','U'),('C','U','C')), ('G','G','U'):(('C','C','I'),('C','C','G'),('C','C','A')), ('G','G','C'):(('C','C','I'),('C','C','G')), ('G','G','A'):(('C','C','I'),('C','C','U')), ('G','G','G'):(('C','C','C'),('C','C','U')) } -------------- next part -------------- An HTML attachment was scrubbed... URL: