;ò kìÈ?c@sêdZdklZdkZdkZdkZdkZdkZdkZ dk Z ei ddfjo dk Tndk TdZd„Zdefd „ƒYZd fd „ƒYZd „Zed „Zeed„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z!d„Z"d„Z#d„Z$d„Z%ded„Z&d„Z'd „Z(d!„Z)d"„Z*ed#„Z+d$„Z,d%„Z-d&„Z.d'„Z/d(d)„Z0d*dfdd*fd+dfdd+fgZ1d,„Z2d-„Z3d.„Z4d/„Z5d0„Z6d1„Z7ed2„Z8d3„Z9d*d4„Z:d5„Z;d6„Z<d7„Z=d8„Z>ed9d:d;„Z?d<d=„Z@d<d>„ZAd?fd@„ƒYZBdA„ZCdBeBfdC„ƒYZDdDeBfdE„ƒYZEhZFdFZGdS(GsEProvide some widely useful utilities. Safe for "from utils import *".(s generatorsNii(s*finfcKs|SdS(siCreate a dict out of the argument=value arguments. Ex: Dict(a=1, b=2, c=3) ==> {'a':1, 'b':2, 'c':3}N(sentries(sentries((sutils.pysDictss DefaultDictcBs)tZdZd„Zd„Zd„ZRS(s®Dictionary with a default value for unknown keys. Ex: d = DefaultDict(0); d['x'] += 1; d['x'] ==> 1 d = DefaultDict([]); d['x'] += [1]; d['y'] += [2]; d['x'] ==> [1]cCs ||_dS(N(sdefaultsself(sselfsdefault((sutils.pys__init__scCs>||jo|i|ƒSn|i|ti|iƒƒSdS(N(skeysselfsgets setdefaultscopysdeepcopysdefault(sselfskey((sutils.pys __getitem__s cCs$t|iƒ}|i|ƒ|SdS(N(s DefaultDictsselfsdefaultscopysupdate(sselfscopy((sutils.pys__copy__ s (s__name__s __module__s__doc__s__init__s __getitem__s__copy__(((sutils.pys DefaultDicts   sStructcBs)tZdZd„Zd„Zd„ZRS(s¾Create an instance with argument=value slots. This is for making a lightweight object whose class doesn't matter. Ex: s = Struct(a=1, b=2); s.a ==> 1; s.a = 3; s ==> Struct(a=3, b=2)cKs|ii|ƒdS(N(sselfs__dict__supdatesentries(sselfsentries((sutils.pys__init__)scCs;t|tƒot|i|iƒSnt|i|ƒSdS(N(s isinstancesothersStructscmpsselfs__dict__(sselfsother((sutils.pys__cmp__,scCs^gi}t|ƒiƒD]&\}}|d|t|ƒfƒq~}ddi |ƒSdS(Ns%s=%ss Struct(%s)s, ( sappends_[1]svarssselfsitemssksvsreprsargssjoin(sselfsargss_[1]svsk((sutils.pys__repr__2sI(s__name__s __module__s__doc__s__init__s__cmp__s__repr__(((sutils.pysStruct%s   cKs9t|tƒo|i|ƒn|ii|ƒ|SdS(s´Update a dict, or an object with slots, according to entries. Ex: update({'a': 1}, a=10, b=20) ==> {'a': 10, 'b': 20} update(Struct(a=1), a=10, b=20) ==> Struct(a=10, b=20)N(s isinstancesxsdictsupdatesentriess__dict__(sxsentries((sutils.pysupdate6s cCsbt|tƒo"ditt|ƒ|ƒƒ}n)|tjo|iƒn|i|ƒ|SdS(sÈSort seq (mutating it) and return it. compare is the 2nd arg to .sort. Ex: sort([3, 1, 2]) ==> [1, 2, 3]; reverse(sort([3, 1, 2])) ==> [3, 2, 1] sort([-3, 1, 2], comparer(abs)) ==> [1, 2, -3]sN(s isinstancesseqsstrsjoinssortslistscomparescmp(sseqscompare((sutils.pyssortEs"  cs&ˆtjoˆSn‡‡d†SdS(s„Build a compare function suitable for sort. The most common use is to specify key, meaning compare the values of key(x), key(y).csˆˆ|ƒˆ|ƒƒS(N(scmpskeysxsy(sxsy(skeyscmp(sutils.pysXsN(skeysNonescmp(skeyscmp((skeyscmpsutils.pyscomparerRs cCs^t|tƒo|i|dƒSn7gi}|D]!}||jo||ƒq2q2~SdS(s¬Return a copy of seq (or string) with all occurences of item removed. Ex: removeall(3, [1, 2, 3, 3, 2, 1, 3]) ==> [1, 2, 2, 1] removeall(4, [1, 2, 3]) ==> [1, 2, 3]sN(s isinstancesseqsstrsreplacesitemsappends_[1]sx(sitemsseqs_[1]sx((sutils.pys removeallZscCsit|tƒoditt|ƒƒƒSn9t|tƒottt|ƒƒƒSn|iƒ|SdS(s…Return the reverse of a string or list or tuple. Mutates the seq. Ex: reverse([1, 2, 3]) ==> [3, 2, 1]; reverse('abc') ==> 'cba'sN(s isinstancesseqsstrsjoinsreversesliststuple(sseq((sutils.pysreversecs cCstt|ƒƒSdS(s}Remove duplicate elements from seq. Assumes hashable elements. Ex: unique([1, 2, 3, 2, 1]) ==> [1, 2, 3] # order may varyN(slistsSetsseq(sseq((sutils.pysuniquenscs ‡d†}t||dƒSdS(swCount the number of elements of seq for which the predicate is true. count_if(callable, [42, None, max, min]) ==> 2cs|ˆ|ƒ S(N(scounts predicatesx(scountsx(s predicate(sutils.pyswsiN(sfsreducesseq(s predicatesseqsf((s predicatesutils.pyscount_ifts cCs.x#|D]}||ƒo|SqqWtSdS(sIf there is an element of seq that satisfies predicate, return it. Ex: find_if(callable, [3, min, max]) ==> min find_if(callable, [1, 2, 3]) ==> NoneN(sseqsxs predicatesNone(s predicatesseqsx((sutils.pysfind_ifzs  cCs/x$|D]}||ƒ otSqqWtSdS(s|True if every element of seq satisfies predicate. Ex: every(callable, [min, max]) ==> 1; every(callable, [min, 3]) ==> 0N(sseqsxs predicatesFalsesTrue(s predicatesseqsx((sutils.pysevery‚s  cCs4x)|D]!}||ƒ}|o|SqqWtSdS(sŠIf some element x of seq satisfies predicate(x), return predicate(x). Ex: some(callable, [min, 3]) ==> 1; some(callable, [2, 3]) ==> 0N(sseqsxs predicatespxsFalse(s predicatesseqsxspx((sutils.pyssome‰s  cCs.x#|D]}||jotSqqWtSdS(s{Like (elt in seq), but compares with is, not ==. Ex: e = []; isin(e, [1, e, 3]) ==> True; isin(e, [1, [], 3]) ==> FalseN(sseqsxseltsTruesFalse(seltsseqsx((sutils.pysisin‘s  cCs^|d}||ƒ}x=|D]5}||ƒ}||jo||f\}}qqW|SdS(s|Return an element with lowest fn(seq[i]) score; tie goes to first one. Ex: argmin(['one', 'to', 'three'], len) ==> 'to'iN(sseqsbestsfns best_scoresxsx_score(sseqsfnsx_scores best_scoresxsbest((sutils.pysargmin¡s  cCs…||dƒgf\}}x^|D]V}||ƒ}||jo|g|f\}}q#||jo|i|ƒq#q#W|SdS(sReturn a list of elements of seq[i] with the lowest fn(seq[i]) scores. Ex: argmin_list(['one', 'to', 'three', 'or'], len) ==> ['to', 'or']iN(sfnsseqs best_scoresbestsxsx_scoresappend(sseqsfnsx_scores best_scoresxsbest((sutils.pys argmin_list«s   cCsŸ||dƒ}d}x~|D]v}||ƒ}||jo||f\}}d}q||jo.|d7}ti|ƒdjo |}q“qqW|SdS(s‰Return an element with lowest fn(seq[i]) score; break ties at random. Thus, for all s,f: argmin_random_tie(s, f) in argmin_list(s, f)iiN( sfnsseqs best_scoresnsxsx_scoresbestsrandoms randrange(sseqsfnsx_scoresnsbestsxs best_score((sutils.pysargmin_random_tie·s    cst|‡d†ƒSdS(sReturn an element with highest fn(seq[i]) score; tie goes to first one. Ex: argmax(['one', 'to', 'three'], len) ==> 'three'cs ˆ|ƒ S(N(sfnsx(sx(sfn(sutils.pysÈsN(sargminsseq(sseqsfn((sfnsutils.pysargmaxÅscst|‡d†ƒSdS(s’Return a list of elements of seq[i] with the highest fn(seq[i]) scores. Ex: argmax_list(['one', 'three', 'seven'], len) ==> ['three', 'seven']cs ˆ|ƒ S(N(sfnsx(sx(sfn(sutils.pysÍsN(s argmin_listsseq(sseqsfn((sfnsutils.pys argmax_listÊscst|‡d†ƒSdS(sFReturn an element with highest fn(seq[i]) score; break ties at random.cs ˆ|ƒ S(N(sfnsx(sx(sfn(sutils.pysÑsN(sargmin_random_tiesseq(sseqsfn((sfnsutils.pysargmax_random_tieÏsicCs€|ot||ƒ}nh}x(|D] }|i|dƒd|| [(100, 1), (110, 2), (160, 2), (200, 3), (220, 1)] histogram(vals, 1) ==> [(200, 3), (160, 2), (110, 2), (100, 1), (220, 1)] histogram(vals, 1, lambda v: round(v, -2)) ==> [(200.0, 6), (100.0, 3)]iicCst|d|dƒS(Ni(scmpsysx(sxsy((sutils.pysâsN( s bin_functionsmapsvaluessbinssvalsgetsmodessortsitems(svaluessmodes bin_functionsvalsbins((sutils.pys histogramÕscCsti|ƒtidƒSdS(s^Base 2 logarithm. Ex: log2(1024) ==> 10.0; log2(1.0) ==> 0.0; log2(0) raises OverflowErroriN(smathslog10sx(sx((sutils.pyslog2æscCst|ddƒddSdS(sTReturn the most common value in the list of values. Ex: mode([1, 2, 3, 2]) ==> 2smodeiiN(s histogramsvalues(svalues((sutils.pysmodeëscCsŒt|ƒ}t|ƒ}|ddjo||dSnO||dd|dd!}yt|ƒSWn tj oti|ƒSnXdS(sReturn the middle value, when the values are sorted. If there are an odd number of elements, try to average the middle two. If they can't be averaged (e.g. they are strings), choose one at random. Ex: median([10, 100, 11]) ==> 11; median([1, 2, 3, 4]) ==> 2.5iiN( slensvaluessnssortsmiddle2smeans TypeErrorsrandomschoice(svaluessnsmiddle2((sutils.pysmedianðs  cCst|ƒtt|ƒƒSdS(s,Return the arithmetic average of the values.N(ssumsvaluessfloatslen(svalues((sutils.pysmeanscCs]|tjot|ƒ}ntitgi}|D]}|||dƒq4~ƒƒSdS(sWThe standard deviation of a set of values. Pass in the mean if you already know it.iN( smeanvalsNonesmeansvaluessmathssqrtssumsappends_[1]sx(svaluessmeanvals_[1]sx((sutils.pysstddevs cCsBtgi}t||ƒD]\}}|||ƒq~ƒSdS(svReturn the sum of the element-wise product of vectors x and y. Ex: dotproduct([1, 2, 3], [1000, 100, 10]) ==> 1230N(ssumsappends_[1]szipsXsYsxsy(sXsYs_[1]sysx((sutils.pys dotproduct scCsttti||ƒƒSdS(sVComponent-wise addition of two vectors. Ex: vector_add((0, 1), (8, 9)) ==> (8, 10)N(stuplesmapsoperatorsaddsasb(sasb((sutils.pys vector_addscCs|tiddƒjSdS(sReturn true with probability p.f0.0f1.0N(spsrandomsuniform(sp((sutils.pys probabilityscCsqt|ƒo|Snyt|ƒSWnGtj o;yt|ƒSWqmtj ot|ƒiƒSqmXnXdS(s‡The argument is a string; convert to a number if possible, or strip it. Ex: num_or_str('42') ==> 42; num_or_str(' 42x ') ==> '42x' N(sisnumbersxsints ValueErrorsfloatsstrsstrip(sx((sutils.pys num_or_strs f1.0cCs=|t|ƒ}gi}|D]}|||ƒq~SdS(sxMultiply each number by a constant such that the sum is 1.0 (or total). Ex: normalize([1,2,1]) ==> [0.25, 0.5, 0.25]N(stotalssumsnumberssksappends_[1]sn(snumbersstotalsksns_[1]((sutils.pys normalize$siiÿÿÿÿcCstti|ƒdSdS(Ni(s orientationssindexs orientation(s orientation((sutils.pys turn_right0scCs#tti|ƒdttƒSdS(Ni(s orientationssindexs orientationslen(s orientation((sutils.pys turn_left3scCs4|\}}|\}}ti||||ƒSdS(s'The distance between two (x, y) points.N(saxsaysbxsbysmathshypot(s.0s.2saxsaysbxsby((sutils.pysdistance6scCs4|\}}|\}}||d||dSdS(s5The square of the distance between two (x, y) points.iN(saxsaysbxsby(s.0s.2saxsaysbxsby((sutils.pys distance2:scCs,t|ƒtttt||ƒ|ƒƒSdS(sÐReturn vector, except if any element is less than the corresponding value of lowest or more than the corresponding value of highest, clip to those values. Ex: clip((-1, 10), (0, 0), (9, 9)) ==> (0, 9)N(stypesvectorsmapsminsmaxslowestshighest(svectorslowestshighest((sutils.pysclip>scGs2tiit|ƒ|ƒt||d|ƒSdS(s€Format args with the first argument as format string, and write. Return the last arg, or format itself if there are no args.iÿÿÿÿN(ssyssstdoutswritesstrsformatsargssif_(sformatsargs((sutils.pysprintfFscs:ˆo‡‡d†‰n‡‡d†‰hˆ_ˆSdS(sUMemoize fn: make it remember the computed value for any argument list. If slot is specified, store result in that slot of first argument. If slot is false, store results in a dictionary. Ex: def fib(n): return (n<=1 and 1) or (fib(n-1) + fib(n-2)); fib(9) ==> 55 # Now we make it faster: fib = memoize(fib); fib(9) ==> 55csHt|ˆƒot|ˆƒSn$ˆ||Œ}t|ˆ|ƒ|SdS(N(shasattrsobjsslotsgetattrsfnsargssvalssetattr(sobjsargssval(sslotsfn(sutils.pys memoized_fnTs cs:ˆii|ƒ oˆ|Œˆi| 'caller'; def f(): return caller(); f() ==> 'f'Ni(sinspectsgetouterframess currentframesn(snsinspect((sutils.pyscalleris cCsG|o t|ƒo |ƒSn|Snt|ƒo |ƒSn|SdS(sFLike C++ and Java's (test ? result : alternative), except both result and alternative are always evaluated. However, if either evaluates to a function, it is applied to the empty arglist, so you can delay execution by putting it in a lambda. Ex: if_(2 + 2 == 4, 'ok', lambda: expensive_computation()) ==> 'ok' N(stestscallablesresults alternative(stestsresults alternative((sutils.pysif_os  cCsSt|ddƒp<t|ddƒp)tt|ddƒddƒp t|ƒSdS(s0Try to find some reasonable name for the object.snameis__name__s __class__N(sgetattrsobjectsstr(sobject((sutils.pysname|scCst|dƒSdS(s7Is x a number? We say it is if it has a __int__ method.s__int__N(shasattrsx(sx((sutils.pysisnumber‚scCst|dƒSdS(s=Is x a sequence? We say it is if it has a __getitem__ method.s __getitem__N(shasattrsx(sx((sutils.pys issequence†ss s%gc sYgi} |dD]"‰| ttˆƒddƒƒq~ }|o|g|}ngi} |D]L}| gi}|D]+‰|ttˆƒ‡‡d†ˆƒƒqz~ƒqc~ }d„} t | t gi} |D]}| t t |ƒƒqØ~ Œƒ} xR|D]J}x@t || |ƒD],\}}‰tt ˆƒ|ƒ|ƒG|Gq WHqWdS(s>Print a list of lists as a table, so that columns line up nicely. header, if specified, will be printed as the first row. numfmt is the format for all numbers; you might want e.g. '%6.2f'. (If you want different formats in differnt columns, don't use print_table.) sep is the separator between columns.isrjustsljustcsˆˆS(N(snumfmtsx((sxsnumfmt(sutils.pys“scCsttt|ƒƒS(N(smaxsmapslensseq(sseq((sutils.pys•sN(sappends_[1]stablesxsif_sisnumbersjustssheadersrows_[2]smaxlensmapszipsstrssizessjssizesgetattrssep( stablesheaderssepsnumfmtssizesjustssjsrows_[2]smaxlens_[1]ssizessx((snumfmtsxsutils.pys print_tableŠs=c ?!srcCsEdk}tii|iƒ}tttii|g|ƒ|ƒSdS(s-Open a file based at the AIMA root directory.N( sutilssosspathsdirnames__file__sdirsopensapplysjoins componentssmode(s componentssmodesutilssdir((sutils.pysAIMAFileœs cCstdd|g|ƒSdS(s*Return a file in the AIMA /data directory.s..sdataN(sAIMAFilesnamesmode(snamesmode((sutils.pysDataFile¢ssQueuecBs tZdZd„Zd„ZRS(sºQueue is an abstract class/interface. There are three types: Stack(): A Last In First Out Queue. FIFOQueue(): A First In First Out Queue. PriorityQueue(lt): Queue where items are sorted by lt, (default <). Each type supports the following methods and functions: q.append(item) -- add an item to the queue q.extend(items) -- equivalent to: for item in items: q.append(item) q.pop() -- return the top item from the queue len(q) -- number of items in q (also q.__len()) Note that isinstance(Stack(), Queue) is false, because we implement stacks as lists. If Python ever gets interfaces, Queue will be an interface.cCs tƒdS(N(sabstract(sself((sutils.pys__init__·scCs"x|D]}|i|ƒqWdS(N(sitemssitemsselfsappend(sselfsitemssitem((sutils.pysextend¹s(s__name__s __module__s__doc__s__init__sextend(((sutils.pysQueueªs  cCsgSdS(s‡Return an empty list, suitable as a Last-In-First-Out Queue. Ex: q = Stack(); q.append(1); q.append(2); q.pop(), q.pop() ==> (2, 1)N((((sutils.pysStack¼ss FIFOQueuecBs;tZdZd„Zd„Zd„Zd„Zd„ZRS(shA First-In-First-Out Queue. Ex: q = FIFOQueue();q.append(1);q.append(2); q.pop(), q.pop() ==> (1, 2)cCsg|_d|_dS(Ni(sselfsAsstart(sself((sutils.pys__init__ÄscCs|ii|ƒdS(N(sselfsAsappendsitem(sselfsitem((sutils.pysappendÆscCst|iƒ|iSdS(N(slensselfsAsstart(sself((sutils.pys__len__ÈscCs|ii|ƒdS(N(sselfsAsextendsitems(sselfsitems((sutils.pysextendÊscCst|i|i}|id7_|idjo|it|iƒdjo |i|i|_d|_n|SdS(Niiii(sselfsAsstartseslen(sselfse((sutils.pyspopÌs - (s__name__s __module__s__doc__s__init__sappends__len__sextendspop(((sutils.pys FIFOQueueÁs     s PriorityQueuecBs;tZdZed„d„Zd„Zd„Zd„ZRS(sâA queue in which the minimum (or maximum) element (as determined by f and order) is returned first. If order is min, the item with minimum f(x) is returned first; if order is max, then it is the item with maximum f(x).cCs|S(N(sx(sx((sutils.pysØscCs t|dgd|d|ƒdS(NsAsordersf(supdatesselfsordersf(sselfsordersf((sutils.pys__init__ØscCs&ti|i|i|ƒ|fƒdS(N(sbisectsinsortsselfsAsfsitem(sselfsitem((sutils.pysappendÚscCst|iƒSdS(N(slensselfsA(sself((sutils.pys__len__ÜscCs=|itjo|iidƒdSn|iiƒdSdS(Nii(sselfsordersminsAspop(sself((sutils.pyspopÞs(s__name__s __module__s__doc__smins__init__sappends__len__spop(((sutils.pys PriorityQueueÔs   sà def is_even(x): return x % 2 == 0 sort([1, 2, -3]) ==> [-3, 1, 2] sort(range(10), comparer(key=is_even)) ==> [1, 3, 5, 7, 9, 0, 2, 4, 6, 8] sort(range(10), lambda x,y: y-x) ==> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] removeall(4, []) ==> [] removeall('s', 'This is a test. Was a test.') ==> 'Thi i a tet. Wa a tet.' removeall('s', 'Something') ==> 'Something' removeall('s', '') ==> '' reverse([]) ==> [] reverse('') ==> '' count_if(is_even, [1, 2, 3, 4]) ==> 2 count_if(is_even, []) ==> 0 argmax([1], lambda x: x*x) ==> 1 argmin([1], lambda x: x*x) ==> 1 argmax([]) raises TypeError argmin([]) raises TypeError # Test of memoize with slots in structures countries = [Struct(name='united states'), Struct(name='canada')] # Pretend that 'gnp' was some big hairy operation: def gnp(country): return len(country.name) * 1e10 gnp = memoize(gnp, '_gnp') map(gnp, countries) ==> [13e10, 6e10] countries # note the _gnp slot. # This time we avoid re-doing the calculation map(gnp, countries) ==> [13e10, 6e10] # Test Queues: nums = [1, 8, 2, 7, 5, 6, -99, 99, 4, 3, 0] def qtest(q): return [q.extend(nums), [q.pop() for i in range(len(q))]][1] qtest(Stack()) ==> reverse(nums) qtest(FIFOQueue()) ==> nums qtest(PriorityQueue(min)) ==> [-99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 99] qtest(PriorityQueue(max)) ==> [99, 8, 7, 6, 5, 4, 3, 2, 1, 0, -99] qtest(PriorityQueue(min, abs)) ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, -99, 99] qtest(PriorityQueue(max, abs)) ==> [99, -99, 8, 7, 6, 5, 4, 3, 2, 1, 0] (Hs__doc__s __future__s generatorssoperatorsmathsrandomscopyssyssos.pathsossbisects version_infossetsspython23sinfinitysDictsdicts DefaultDictsStructsupdatescmpssortsNonescomparers removeallsreversesuniquescount_ifsfind_ifseveryssomesisinsargmins argmin_listsargmin_random_tiesargmaxs argmax_listsargmax_random_ties histogramslog2smodesmediansmeansstddevs dotproducts vector_adds probabilitys num_or_strs normalizes orientationss turn_rights turn_leftsdistances distance2sclipsprintfsmemoizesabstractscallersif_snamesisnumbers issequences print_tablesAIMAFilesDataFilesQueuesStacks FIFOQueues PriorityQueuesFigs_docex(?ssortsStructs probabilitysargmaxsabstractsrandomssomesQueuesDictsFigs num_or_strsprintfsoperatorslog2sfind_ifsisnumbers normalizescopysclipsargmin_random_ties turn_leftsargmax_random_ties generatorsscomparers distance2s FIFOQueuesmemoizesStacksmaths DefaultDictsinfinityscount_ifs_docexsdistances argmin_listsif_s turn_rightsupdates histogramssysseverys orientationss argmax_listsuniques PriorityQueuesnames removeallsAIMAFiles vector_addsreversesargminsbisectscallersmedians issequences print_tablesDataFilesmodesstddevs dotproductsisinsmeansos((sutils.pys?sx ?                       *