My "arc" (trajectory) for teaching Python is something like: >>> dir() >>> dir(__builtins__) >>> type(3) >>> type('A') >>> import math
... using Python as a calculator and wordprocessor, including file i/o (open, close, 'r' 'w' 'a') >>> list, tuple, dict >>> immutability vs. mutability, explaining how ([], []) is an immutable "containing" mutables. >>> import collections.namedtuple ... dot notation access to Atom(protons=, symbol=, long_name=, mass=) talk about APIs as: car dashboard (driverless car controversies); web APIs (point to API companies like Apigee, Google, programmable web). Linking Object.verb() and Object.noun to API concept also (docstrings = owner's manual / user's manaul -- but not a repair manual, which is for #comments in source code and tests). tell stories about Browser Wars, emergence of browser as universal client, HTTP as API, RESTful vs SOAP web services, play with existing APIs that return JSON >>> string formatting with new mini-language feature set >>> def function() notation, arguments vs parameters *args, **kwargs as either >>> save function objects to a list, show functions as top-level, lambda syntax >>> class Element: that mimics namedtuple Atom. Compare side-by-side >>> composer.py (introduce operator overloading) now show how "namedtuple" API may be duplicated using __getitem__ >From here on, we're prepared to use special names (or "__ribs__" as I sometimes call them) as a way to talk about APIs. E.g. * the iterator protocol around __next__ and __iter__ may now be presented using classes. * Context managers (__enter__, __exit__) * Descriptors (__set__ and __get__) We'll get to some of these below, after decorator syntax... >>> inheritance, MRO (method resolution order) >>> old fashioned menu-driven API based in input() to do CRUD against all_elements # <--- this is where I'm at in the current 5-week course I'm teaching >>> annotations What I call "grand unification" is up ahead where we show how a context manager mayb be built with generator as a decorator. Haven't gotten there yet with this class. That's almost black belt, like maybe brown. ==== Looking ahead to tonight's class, reviewing the bridge we've just crossed... # -*- coding: utf-8 -*- """ Created on Thu Jul 21 12:47:03 2016 @author: Kirby Urner side-by-side namedtuple and class Atom (namedtuple) and Element (a non-builtin class) work as clones of one another, meaning the loader function and reporting function are agnostic as to which type to use when building all_elements, a global dictionary of Periodic Table information. """ from collections import namedtuple import json Atom = namedtuple("Atom", "protons symbol long_name mass series") # imagine # http://inventory.earth/elements?symbol="He" # pulling from a DB # using a 'rich data structure' # http://grokbase.com/t/python/edu-sig/0676rrx2n0/rich-data-structure # https://mail.python.org/pipermail/edu-sig/2006-June/006609.html json_data = """{ "He": [2, "He", "Helium", 4.002602, "Nobel gas"], "C": [6, "C", "Carbon", 12.0107, "Noble gas"], "Na": [11, "Na", "Sodium", 22.98976928, "Alkali metal"], "H": [1, "H", "Hydrogen", 1.00794, "Other nonmetal"], "Ne": [10, "Ne", "Neon", 20.1797, "Noble gas"], "Si": [14, "Si", "Silicon", 28.0855, "Metalloid"], "Li": [3, "Li", "Lithium", 6.941, "Alkali metnal"], "F": [9, "F", "Fluorine", 18.9984032, "Metalloid"], "Be": [4, "Be", "Beryllium", 9.012182, "Alkaline earth metal"], "O": [8, "O", "Oxygen", 15.9994, "Other nonmetal"], "Mg": [12, "Mg", "Magnesium", 24.3050, "Alkaline earth metal"], "Al": [13, "Al", "Aluminum", 26.9815386, "Post-transition metal"], "N": [7, "N", "Nitrogen", 14.0067, "Other nonmetal"], "B": [5, "B", "Boron", 10.811, "Metalloid"] }""" class Element: fields = "protons symbol long_name mass series" repstr = ("Atom(protons={protons}, symbol='{symbol}', " "long_name='{long_name}', " "mass={mass}, series='{series}')") def __init__(self, protons: int, symbol: str, long_name: str, mass: float, series: str): # build self.__dict__ self.protons = protons self.symbol = symbol self.long_name = long_name self.__dict__['mass'] = mass # same idea self.series = series def __getitem__(self, idx): return self.__dict__[self.fields[idx]] def __repr__(self): return self.repstr.format(**self.__dict__) def loader(target): """ create a dict all_elements of either: target = "tuples" : namedtuples of type Atom or... target = "instances" : instances of Element class """ global all_elements all_elements = {} the_dict = json.loads(json_data) # json_data is a global for key, value in the_dict.items(): if target == "tuples": all_elements[key] = Atom(*value) # explode list object if target == "instances": all_elements[key] = Element(*value) # explode list object def print_periodic_table(): """ sort all_elements by number of protons, ordered_elements local only What about series? """ ordered_elements = sorted(all_elements.values(), key = lambda k: k.protons) print("PERIODIC TABLE OF THE ELEMENTS") print("-" * 70) print("Symbol |Long Name |Protons |Mass |Series " ) print("-" * 70) for the_atom in ordered_elements: print("{:6} | {:20} | {:6} | {:5.2f} | {:15}".format(the_atom.symbol, the_atom.long_name, the_atom.protons, the_atom.mass, the_atom.series)) if __name__ == "__main__": # loader("tuples") loader("instances") print_periodic_table() OUTPUT in REPL: >>> boron = all_elements["B"] >>> type(boron) __main__.Element >>> boron Atom(protons=5, symbol='B', long_name='Boron', mass=10.811, series='Metalloid') >>> print_periodic_table() PERIODIC TABLE OF THE ELEMENTS ---------------------------------------------------------------------- Symbol |Long Name |Protons |Mass |Series ---------------------------------------------------------------------- H | Hydrogen | 1 | 1.01 | Other nonmetal He | Helium | 2 | 4.00 | Nobel gas Li | Lithium | 3 | 6.94 | Alkali metnal Be | Beryllium | 4 | 9.01 | Alkaline earth metal B | Boron | 5 | 10.81 | Metalloid C | Carbon | 6 | 12.01 | Noble gas N | Nitrogen | 7 | 14.01 | Other nonmetal O | Oxygen | 8 | 16.00 | Other nonmetal F | Fluorine | 9 | 19.00 | Metalloid Ne | Neon | 10 | 20.18 | Noble gas Na | Sodium | 11 | 22.99 | Alkali metal Mg | Magnesium | 12 | 24.30 | Alkaline earth metal Al | Aluminum | 13 | 26.98 | Post-transition metal Si | Silicon | 14 | 28.09 | Metalloid
_______________________________________________ Edu-sig mailing list Edu-sig@python.org https://mail.python.org/mailman/listinfo/edu-sig