Russell and Norvig, AIMA : Chapter 15 Part B – 15.3, 15.4 1.
Norvig Style
Click here to load reader
-
Upload
magesmail7563 -
Category
Documents
-
view
215 -
download
1
Transcript of Norvig Style
![Page 1: Norvig Style](https://reader038.fdocuments.in/reader038/viewer/2022100513/577ccd6f1a28ab9e788c62c2/html5/thumbnails/1.jpg)
The Norvig Style of Programming
PAIP
pg 42: two alternate approaches to developing programs
(1) use most straightforward mapping of problem description to lisp code(2) use most natural notation available to solve problem. Write interpreter for this notation. (sa: cheat if reqd by using lisp notation as a halfway house and reuse reader). The idea is to work with problem as much as possible. "data driven programming"
pg: 110 five stages of programming(1) Describe: vague understanding/english description -> 'notions'
eg: hand, hand_rank, card_rank, (GPS) problem, precondition, appropriate action, effect
(2) Specify: notions -> datastructures,operation names,type signaturesrepresentation of each 'notion'eg: world_state = sets of conditions, condition = symbol,operator = struct{action, precondition, effects}, (design decision) operator adds or deletes conditions from present state
,
In PAIP Glossary comes hereGlossary of impl artifactsGlossary: mapof: name of program construct -> english description. top-level-functionglobal variablesdata types -> constructors, predicates, extractorsdomain-functions - major and auxiliarylanguage built in functionslibrary functions from previous code
poker: [hands] -> hand, card_rank: card-> number card:(suit X value)
(3) Implement: spec -> + implementation code
Implementation code, for each artifact in glossary
(4) Test: sample data, problems, input -> program output
run on sample data. explore.
(5) Analyze: Working program -> bugs, limitations, efficiency insights
classify bugs/limitations : e.g: running-around-the-block-problem, clobbered-sibling-goal-problemmake/measure efficiency
(6) Goto 2 for next version
(7) examine successive programs and extract tools and libraries. rewrite original programs as necessary
![Page 2: Norvig Style](https://reader038.fdocuments.in/reader038/viewer/2022100513/577ccd6f1a28ab9e788c62c2/html5/thumbnails/2.jpg)
e.g: interactive interpreter from GPS and Eliza generalized pattern matching from Eliza
CS 212 class:
Step 1 as is.
2 more or less as is but very lightly touched on , since required functions are discovered "at runtime" . still, type signatures etc are present.
glossary disappears. description added to step 2.
implementation happens Top Down , write the main function first, assuming subfunctions are implemented, then implement those.
when you have 'some minimial working code', use tests to drive implementationfrom then on. (note: not compulsive TDD, though *sometimes* Test Driven is used, though focus is still on error catching, not 'driving design')
'each part of the spec needs some code implementing in it, and a piece of codethat tests it. That said, not too much focus on being exhaustive or using standard frameworks -just a method in the same file with asserts. test for extreme values.
start with tests and code for top level function and work top down
use basic datastructures to represent domain concepts lists, hashes etc.e.g: hand represented by tuple of kind, high card, other cards etcfull house eight over kings = (6, 8, 13)flush 10 over 8 = (5, [10,8,5,7,3])
This focus on/modification of *representations* carries thru to the end
vs Class Hand etc Use direct data structure manipulating operatons (eg: slicing lists) to get required domain operations.
use builtins to match domain operations amap. eg: max. change (to all_max ) only when compelled to by evolving requirements
principle of proportionate change: the change (to code) required should be proportional to change required to concept. One change in concept = (ideally) one change in code.practice: keep watch for change across functions, multilines
generalize functions (slightly? to what degree? what is the 'right level' of generalization?): eg: "deal" generalizes number of hands, number of cards and the deck itself!! thus becoming highly generic.
proto thoughts = generalize any constants that occur. e.g: instead of dealing out 5 cards, as for standard poker, deal out n sized handse.g: instead of dealing for 4 players, deal for m playerse.g: instead of dealing from one deck of 52 cards, deal from p decks of whatevercollection of cards.
![Page 3: Norvig Style](https://reader038.fdocuments.in/reader038/viewer/2022100513/577ccd6f1a28ab9e788c62c2/html5/thumbnails/3.jpg)
probability calculation of each category of hand similairly generalized!
Dimensions of programming.
imagine a multi dimensional space, with one axis each for correctness, reliability, efficiency, features, elegance etc.
moving up only on the elegance axis, while keeping program stationary wrt other axis == 'refactoring'
make engineering tradeoffs of one axis vs another.
DRY etc BUT here Norvig changed *REPRESENTATION* to avoid RY!!! This careful consideration of representation
representation of hands from [7,9,7,10,7] to ((3,1,1) (7,10,9))(and driving it towards more and more succinctness and elegance) is characteristic of Norvig's code!!
REFLECT on changes (eg: partition of the number 5 reflected in the rules of the game of poker)
REUSE standard pieces in *both* specification AND code.
Lesson 2: Major focus = 'back of envelope' calculations about if a solution is 'sufficient' wrt efficiency etc
specific example = zebra puzzle
'concept inventory' = houses, properties, nationalities, pets, smokes, colorsassignment-of-properties-to-things (covers lives-in, next-to etc)locations, next-to, left-to, right-to
assignment seems to roughly cover 'unification'
red assigned-to house#2 => blue cannot be assigned to house#2therefore there needs to be 'groups of properties' == say color
first approach: try assigning all combinations, test out if all predicates hold5! ways to assign colors to houses
5!^5 ways to assign five properties (color, nationality etc) to five houses
def timedcall(fn, *args)t0 = time.clockfn(*args)t1 = time.clockreturn t1-t0
when you start measurements, you have transitioned from CS as mathematics toCS to experimental science
def timedcalls (n, fn,*args)times = [timedcall(fn, *args)[0]) for _ in range(n)]return min(times), average(times), max(times)
![Page 4: Norvig Style](https://reader038.fdocuments.in/reader038/viewer/2022100513/577ccd6f1a28ab9e788c62c2/html5/thumbnails/4.jpg)
int-float trick
we think of different aspects of the program when we write programs.correctness, efficiency, ease of debugging
AOP == separate out all the aspects - ideal often not reached.
def instrument_fn(fn, *args)c.starts, c.items = 0,0result = fn(*args)print "%s got %s with %5d iters over %7d items" % (fn.__name__, result, c.starts, c.items)
use generator functions for implementing cthus
def c(sequence):c.starts += 1for item in sequence:
c.items += 1yield item
key concept (also in PAIP) know how to write a profile(fn-name) function(or as near to it as possible) which both counts number of invocations of fn-name AND also times fn-name's fn (and reports max,min,avg,std-dev(?))
Learned from Zebra puzzleconcept inventory build tools - here count
s,timingrefine ideas aspectsimple implementationback of envelope calcsrefine code