A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.md 426KB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663
  1. title: Programming for kids
  2. url: https://github.com/jackdoe/programming-for-kids
  3. hash_url: 62f9f5083de61124ed4d9fe1b458d505
  4. ```
  5. ┌─┐┬─┐┌─┐┌─┐┬─┐┌─┐┌┬┐┌┬┐┬┌┐┌┌─┐
  6. ├─┘├┬┘│ ││ ┬├┬┘├─┤│││││││││││ ┬
  7. ┴ ┴└─└─┘└─┘┴└─┴ ┴┴ ┴┴ ┴┴┘└┘└─┘
  8. ┌─┐┌─┐┬─┐
  9. ├┤ │ │├┬┘
  10. └ └─┘┴└─
  11. ┬┌─┬┌┬┐┌─┐
  12. ├┴┐│ ││└─┐
  13. ┴ ┴┴─┴┘└─┘
  14. > by: Borislav Nikolov
  15. > year: 2021
  16. The parent has to know how to program.
  17. Spend 30 minutes per day. Every day.
  18. "Anything worth doing is worth doing badly." — G. K. Chesterton
  19. ```
  20. <br>
  21. <br>
  22. <br>
  23. <br>
  24. <div style="page-break-before:always"></div>
  25. # Hello World
  26. ::: warning
  27. *This chapter is for parents, kids skip to the next one.* [day 0 - the computer](https://github.com/jackdoe/programming-for-kids#day-0-the-computer)
  28. :::
  29. ## Why
  30. I think modern education treats programming as 'career path', I think of that to be wrong. I treat it as literacy. Being literate lets to experience a different world than those who aren't. It is not about having a job, I can't even explain it, being literate just allows you to see the fabric of what everything is made of.
  31. Imagine schools were teaching violin en masse, how would that go? How many kids will be able to make a decent sound? How many will drop out because they are stuck and the rest have to move on because the tests say so?
  32. Sometimes my daughter doesn't like to code, or to read for that matter, of course the rest of the internet is so much more interesting. We are competing with hundreds of thousands of developers in Supercell and Facebook and TikTok and Netflix that train billion parameters models so they can squeeze every last bit of attention from our kids. Of course it is going to be difficult. But, I thought to myself, does that mean I should not try? So a change of approach is needed, completely individualistic and personal approach.
  33. Maybe she will grow hating it, or even hating me. Parenting is difficult.
  34. We are 7 months in, and so far she doesn't hate me.
  35. ## About the book
  36. This book is for parents who know how to code and for kids who don't, but especially for parents and kids who can spend 30 minutes per day, _every day_. I am writing this book as I am teaching my daughter (10), and you know how in some cooking shows, they skip the part where the food is cooking? I wont do that. The book will be longer than it should.
  37. Again, if your children are older, or younger, this book might not work, you could of course still find pieces that work for you.
  38. This is more of a log of my experience so far. I am writing it as if I am talking to my daughter, so the style might be weird, but for you it should be more of an pool of examples you could use, and maybe just get ideas from the text. Try to avoid giving the book to your child and say "do this chapter", but in is also good experience to be able to do something alone.
  39. Also its nice to print a copy so they don't just copy paste.
  40. What you need:
  41. * Computer
  42. * Patience
  43. * Internet
  44. * Patience
  45. If you don't have a you can buy raspberry pi 400 for 70$ or so, or something similar that you attach to your TV. If you don't have patience, buy some chamomile tea. You don't need internet subscription, but you would need a bit of internet to download python and do few google searches.
  46. In most of the weeks you also go back, waaay back, every day you re-iterate variables and for loops, print the numbers from one to 10 forever, ask how many times to be printed, etc.
  47. The emphasis on HTML helps with understanding hierarchy, `tr` is child of `table`, `table` is child of `body` body is child of `html`, `td` is a sister to `td` and both are children of `tr` etc, it helped a lot with my daughter understanding how the `else` is sibling to the `if` and how both are children to `while`.
  48. Also it is very easy to debug, and inspect, and get immediate feedback. There are many 'hackers' now on tiktok or youtube that shows you how to get a lot robux(money) in roblox by inspecting the page and modifying the HTML, so I think HTML is very important to be understood, not only because it teaches hierarchy, but also it is the canvas of the web.
  49. ## Other materials
  50. Play other games as well, https://tomorrowcorporation.com/ has some brilliant games, Human Resource Machine is great way to learn loops and conditional jumps, and 7 Billion Humans is amazing for high level concepts, including variables, recursion and sorting. Before we started with HTML we spent about 1 month with those games. They are just incredible and well worth their money.
  51. The Robot Turtles game is amazing as well, you can find it here: https://www.thinkfun.com/products/robot-turtles/
  52. Scratch works for some kids, mine didn't enjoy it much.
  53. Buy few Arduino NANOs (cheap clones from amazon work as well, but you need to install ch340 driver), and some servo motors and write few super basic programs that turn the servo slowly in one direction or another. Connect `black/brown wire to gnd, red wire to 5v and orange wire to D9`, and run:
  54. ```
  55. #include <Servo.h>
  56. #define SERVO_PIN 9
  57. Servo s;
  58. void setup() {
  59. s.attach(SERVO_PIN, 1000, 2000);
  60. }
  61. void loop() {
  62. s.write(0);
  63. delay(500);
  64. s.write(60);
  65. delay(500);
  66. s.write(120);
  67. delay(500);
  68. }
  69. ```
  70. ## Motivation
  71. Sometimes there is very little motivation. Kids are super tired from school and playdates and extracurricular activities, makes it hard to spend 30 minutes per day on something. Netflix and YouTube and etc are so much more interesting than what I have to offer, it is a rigged game.. Sad that I have to compete with billion parameter models, but here we are.
  72. Anything worth doing, is worth doing poorly. If you cant spend 30 minutes, spend 15, spend 5 minutes if you have to, or even 1. It is all worth it.
  73. I try to spend time in the morning, at least on the weekends, and first thing after school on school days. Luckily now it is a bit easier while we work from home during the pandemic. We tried to setup time before or after dinner, and it doesn't go well.
  74. Sometimes material incentives are also very helpful, e.g. a promise 5$ gift card, but I think you will have to find out what works for your kids.
  75. <div style="page-break-before:always"></div>
  76. ## week - 0
  77. ## week - 000
  78. [day-0 the computer](#day-0-the-computer)
  79. [day-0 files](#day-0-files)
  80. [day-0 ascii](#day-0-ascii)
  81. [day-0 magic](#day-0-magic)
  82. [day-0 how to google](#day-0-how-to-google)
  83. [day-1 touch typing](#day-1-touch-typing)
  84. [day-2 install python](#day-2-install-python)
  85. [day-2 make a useful program](#day-2-make-a-useful-program)
  86. [day-3 touch typing using your program](#day-3-touch-typing-using-your-program)
  87. [day-4 html - basics](#day-4-html---basics)
  88. [day-5 html - basics](#day-5-html---basics)
  89. [day-6 touch typing](#day-6-touch-typing)
  90. ## week - 001
  91. [day-7 new touch typing program](#day-7-new-touch-typing-program)
  92. [day-8 touch typing](#day-8-touch-typing)
  93. [day-9 touch typing using your program](#day-9-touch-typing-using-your-program)
  94. [day-10 html - basics](#day-10-html---basics)
  95. [day-11 html - basics](#day-11-html---basics)
  96. [day-12 touch typing](#day-12-touch-typing)
  97. [day-13 html](#day-13-html)
  98. ## week - 002
  99. [day-14 html - tables](#day-14-html---tables)
  100. [day-15 html - more tables](#day-15-html---more-tables)
  101. [day-16 html - multiplication table](#day-16-html---multiplication-table)
  102. [day-17 html - multiplication table](#day-17-html---multiplication-table)
  103. [day-18 touch typing](#day-18-touch-typing)
  104. [day-19 html - links](#day-19-html---links)
  105. [day-20 html - tree](#day-20-html---tree)
  106. ## week - 003
  107. [day-21 html - view source](#day-21-html---view-source)
  108. [day-22 html - inspect](#day-22-html---inspect)
  109. [day-23 html - images](#day-23-html---images)
  110. [day-24 licenses](#day-24-licenses)
  111. [day-25 touch typing](#day-25-touch-typing)
  112. [day-26 html - title](#day-26-html---title)
  113. [day-27 html - fun (js)](#day-27-html---fun-(js))
  114. ## week - 004
  115. [day-28 print; functions; while; variables; conditions](#day-28-print-functions-while-variables-conditions)
  116. [day-29 print; if](#day-29-print-if)
  117. [day-30 functions; lists](#day-30-functions-lists)
  118. [day-31 functions; if; random; lists](#day-31-functions-if-random-lists)
  119. [day-32 lists; while](#day-32-lists-while)
  120. [day-33 for](#day-33-for)
  121. [day-34 love tester](#day-34-love-tester)
  122. [day-34 touch typing](#day-34-touch-typing)
  123. ## week - 005
  124. [day-35 lists; while; continue](#day-35-lists-while-continue)
  125. [day-36 while; range; functions](#day-36-while-range-functions)
  126. [day-37 while; functions](#day-37-while-functions)
  127. [day-38 strings](#day-38-strings)
  128. [day-39 touch typing](#day-39-touch-typing)
  129. [day-40 functions; strings; range](#day-40-functions-strings-range)
  130. [day-41 basics of basics](#day-41-basics-of-basics)
  131. ## week - 006
  132. [day-41 lists; if; while](#day-41-lists-if-while)
  133. [day-42 lists; functions; grid; while](#day-42-lists-functions-grid-while)
  134. [day-43 if; range](#day-43-if-range)
  135. [day-44 lists](#day-44-lists)
  136. [day-45 lists; functions](#day-45-lists-functions)
  137. [day-46 basic turtle](#day-46-basic-turtle)
  138. [day-47 range; while](#day-47-range-while)
  139. ## week - 007
  140. [day-48 strings; functions](#day-48-strings-functions)
  141. [day-49 list; dictionaries](#day-49-list-dictionaries)
  142. [day-50 lists; if](#day-50-lists-if)
  143. [day-51 internet awareness - scams/viruses](#day-51-internet-awareness---scamsviruses)
  144. [day-52 internet awareness - how login works](#day-52-internet-awareness---how-login-works)
  145. [day-53 basics of the internet - ip/dns](#day-53-basics-of-the-internet---ipdns)
  146. [day-54 touch typing](#day-54-touch-typing)
  147. ## week - 008
  148. [day-55 lists; functions](#day-55-lists-functions)
  149. [day-56 functions; if; random](#day-56-functions-if-random)
  150. [day-57 lists; functions; grid](#day-57-lists-functions-grid)
  151. [day-58 continue previous day](#day-58-continue-previous-day)
  152. [day-59 tuples; lists](#day-59-tuples-lists)
  153. [day-60 go back in time](#day-60-go-back-in-time)
  154. ## week - 009
  155. [day-61 pygame; pygamezero; coordinates](#day-61-pygame-pygamezero-coordinates)
  156. [day-62 collisions; callbacks](#day-62-collisions-callbacks)
  157. [day-63 functions](#day-63-functions)
  158. [day-64 lists; functions](#day-64-lists-functions)
  159. [day-65 functions; collisions](#day-65-functions-collisions)
  160. [day-66 schedule; callbacks; functions](#day-66-schedule-callbacks-functions)
  161. [day-67 lists; functions](#day-67-lists-functions)
  162. ## week - 010
  163. [day-68 lists; functions](#day-68-lists-functions)
  164. [day-69 sockets; functions; callbacks](#day-69-sockets-functions-callbacks)
  165. [day-70 lists; functions](#day-70-lists-functions)
  166. [day-71 strings; integers; while; functions](#day-71-strings-integers-while-functions)
  167. [day-72 reading code](#day-72-reading-code)
  168. [day-73 reading code](#day-73-reading-code)
  169. [day-74 strings; while; lists](#day-74-strings-while-lists)
  170. ## week - 011
  171. [day-75 functions; callbacks; lists; encoding](#day-75-functions-callbacks-lists-encoding)
  172. [day-76 functions; callbacks; lists](#day-76-functions-callbacks-lists)
  173. [day-77 lists; encode/decode](#day-77-lists-encodedecode)
  174. [day-78 coordinates; functions; callbacks](#day-78-coordinates-functions-callbacks)
  175. [day-79 lists; encoding](#day-79-lists-encoding)
  176. [day-80 lists; functions](#day-80-lists-functions)
  177. [day-81 lists; encoding](#day-81-lists-encoding)
  178. ## week - 012
  179. [day-82 lists; strings](#day-82-lists-strings)
  180. [day-83 lists; functions](#day-83-lists-functions)
  181. [day-84 lists](#day-84-lists)
  182. [day-85 list; functions](#day-85-list-functions)
  183. [day-86 lists](#day-86-lists)
  184. [day-87 read/write files](#day-87-readwrite-files)
  185. [day-88 flask](#day-88-flask)
  186. ## week - 013
  187. [day-89 files; strings; lists](#day-89-files-strings-lists)
  188. [day-90 strings](#day-90-strings)
  189. [day-91 lists](#day-91-lists)
  190. [day-92 command line; command line arguments; files](#day-92-command-line-command-line-arguments-files)
  191. [day-93 pydoc](#day-93-pydoc)
  192. [day-94 editors - ed/nano/vi/emacs..](#day-94-editors---ednanoviemacs..)
  193. [day-95 memory; virtual computer; instructions; strings; lists](#day-95-memory-virtual-computer-instructions-strings-lists)
  194. ## week - 014
  195. [day-95 memory; machine code; virtual computer](#day-95-memory-machine-code-virtual-computer)
  196. [day-96 binary; ascii; memory](#day-96-binary-ascii-memory)
  197. [day-97 lists; ](#day-97-lists-)
  198. [day-98 lists; read/write file](#day-98-lists-readwrite-file)
  199. [day-99 classes; lists; functions; cartesian coordinates](#day-99-classes-lists-functions-cartesian-coordinates)
  200. [day-100 touch typing; lists](#day-100-touch-typing-lists)
  201. [day-101 functions; strings](#day-101-functions-strings)
  202. ## week - 015
  203. [day-102 touch typing day](#day-102-touch-typing-day)
  204. [day-103 read file; command line arguments](#day-103-read-file-command-line-arguments)
  205. [day-104 read file; command line arguments; dictionary](#day-104-read-file-command-line-arguments-dictionary)
  206. [day-105 basics of basics](#day-105-basics-of-basics)
  207. [day-106 read/write file; lists](#day-106-readwrite-file-lists)
  208. [day-107 lists; dictionaries](#day-107-lists-dictionaries)
  209. [day-108 dictionaries](#day-108-dictionaries)
  210. ## week - 016
  211. [day-109 touch typing day](#day-109-touch-typing-day)
  212. [day-110 find code on tiktok](#day-110-find-code-on-tiktok)
  213. [day-111 lists; random](#day-111-lists-random)
  214. [day-112 use simple dictionary](#day-112-use-simple-dictionary)
  215. [day-113 discover pythontutor](#day-113-discover-pythontutor)
  216. [day-114 simple turtle](#day-114-simple-turtle)
  217. [day-115 practical coding, control roblox with python](#day-115-practical-coding-control-roblox-with-python)
  218. ## week - 017
  219. [day-116 many turtles](#day-116-many-turtles)
  220. [day-117 another text editor](#day-117-another-text-editor)
  221. [day-118 search lyrics](#day-118-search-lyrics)
  222. [day-119 facial recognition; move 78](#day-119-facial-recognition-move-78)
  223. [day-120 program on your own form a book](#day-120-program-on-your-own-form-a-book)
  224. [day-121 scam check list](#day-121-scam-check-list)
  225. [day-122 lists; random; mutate](#day-122-lists-random-mutate)
  226. ## week - 018
  227. [day-123 lists; callbacks](#day-123-lists-callbacks)
  228. [day-124 bmp format, images; encoding/decoding](#day-124-bmp-format-images-encodingdecoding)
  229. [day-125 lists; dictionaries](#day-125-lists-dictionaries)
  230. [day-126 read/write file](#day-126-readwrite-file)
  231. [day-127 callbacks; schedule interval](#day-127-callbacks-schedule-interval)
  232. [day-128 lists; cpu usage; resources](#day-128-lists-cpu-usage-resources)
  233. [day-129 eat your computer; memory; cpu](#day-129-eat-your-computer-memory-cpu)
  234. ## week - 019
  235. [day-130 turtle; lists; classes](#day-130-turtle-lists-classes)
  236. [day-131 lists; files; dictionaries](#day-131-lists-files-dictionaries)
  237. [day-132 lists; classes](#day-132-lists-classes)
  238. [day-133 touch typing; lists](#day-133-touch-typing-lists)
  239. [day-134 lists; methods](#day-134-lists-methods)
  240. [day-134 if](#day-134-if)
  241. [day-135 dictionary; for](#day-135-dictionary-for)
  242. ## week - 020
  243. [day-136 for; arrays; memory](#day-136-for-arrays-memory)
  244. [day-137 for; file; if](#day-137-for-file-if)
  245. [day-138 for; file; if](#day-138-for-file-if)
  246. [day-139 while; list; counter](#day-139-while-list-counter)
  247. [day-140 while; turtle; strings](#day-140-while-turtle-strings)
  248. [day-141 wiki; api](#day-141-wiki-api)
  249. [day-142 while](#day-142-while)
  250. ## week - 021
  251. [day-143 strings](#day-143-strings)
  252. [day-144 strings; lists](#day-144-strings-lists)
  253. [day-145 while](#day-145-while)
  254. [day-146 while; classes](#day-146-while-classes)
  255. [day-147 while](#day-147-while)
  256. [day-148 money](#day-148-money)
  257. [day-149 creators, consumers and ideas](#day-149-creators-consumers-and-ideas)
  258. ## week - 022
  259. [day-150 while; classes](#day-150-while-classes)
  260. [day-151 classes; while](#day-151-classes-while)
  261. [day-152 lists](#day-152-lists)
  262. [day-153 lists; dictionaries](#day-153-lists-dictionaries)
  263. [day-154 classes](#day-154-classes)
  264. [day-155 c++](#day-155-c++)
  265. [day-156 for; while](#day-156-for-while)
  266. ## week - 023
  267. [day-157 strings; cin](#day-157-strings-cin)
  268. [day-158 if; while](#day-158-if-while)
  269. [day-159 strings; sizeof](#day-159-strings-sizeof)
  270. [day-160 pointers](#day-160-pointers)
  271. [day-161 if; while; functions](#day-161-if-while-functions)
  272. [day-162 if; while; variables](#day-162-if-while-variables)
  273. [day-163 if; while; lists](#day-163-if-while-lists)
  274. ## week - 024
  275. [day-164 pointers](#day-164-pointers)
  276. [day-165 if; while](#day-165-if-while)
  277. [day-166 if; while](#day-166-if-while)
  278. [day-167 c; printf; scanf](#day-167-c-printf-scanf)
  279. [day-168 c; while; if](#day-168-c-while-if)
  280. [day-169 c; while; if](#day-169-c-while-if)
  281. [day-170 pointers](#day-170-pointers)
  282. ## week - 025
  283. [day-171 while; for; if; list](#day-171-while-for-if-list)
  284. [day-172 if](#day-172-if)
  285. [day-173 if; variables](#day-173-if-variables)
  286. [day-174 if; list](#day-174-if-list)
  287. [day-175 if](#day-175-if)
  288. [day-176 if](#day-176-if)
  289. [day-177 if](#day-177-if)
  290. ## week - 026
  291. [day-178 if; absolute](#day-178-if-absolute)
  292. [day-179 if; for](#day-179-if-for)
  293. [day-180 if](#day-180-if)
  294. [day-181 if](#day-181-if)
  295. [day-182 look back](#day-182-look-back)
  296. [day-183 generalization](#day-183-generalization)
  297. [day-184 generalization](#day-184-generalization)
  298. ## week - 027
  299. [day-185 generalization](#day-185-generalization)
  300. [day-186 if](#day-186-if)
  301. [day-187 if; while; functions](#day-187-if-while-functions)
  302. [day-188 oop](#day-188-oop)
  303. [day-189 keyword arguments; string methods](#day-189-keyword-arguments-string-methods)
  304. [day-190 while](#day-190-while)
  305. [day-191 while](#day-191-while)
  306. ## [DAY-0] The Computer
  307. All modern computers(laptops, phones, pc master race rgb monsters, etc) have somewhat similar components: Processor, Memory, Video Card, Disk and USB controller, WiFi card etc. Some of them are in one single chip and you cant even see them anymore, but they are there. For example there are chips that have Processor and Video Card together. The term for processor is actually CPU - Central processing unit, but we called it processors when we were kids and it kind of make sense, since it processes stuff.
  308. ```
  309. +------------------+
  310. | |
  311. | [ ] |
  312. | [ Processor ] |
  313. | [ ] |
  314. | |
  315. | [ Memory ] |
  316. | [ Memory ] |
  317. | |
  318. | [ Video Card ]--+------> monitor
  319. | |
  320. | [ Disk ] |
  321. | | +---> iphone
  322. | | +---> mouse
  323. | [ USB ]---------+--+---> keyboard
  324. | |
  325. | [ WiFi ] |
  326. | [ ... ] |
  327. +------------------+
  328. ```
  329. Memory (also called RAM), is the place where programs exist to be run by the CPU, it loads its instructions from there, and the instructions tells it what to do, it can write back to memory, or read from a different place or write something to the disk controller or to the video card, etc. Basically the most important stuff happens between the processor and the RAM (which stands for Random Access Memory). It is Random Access because the processor can just go and read or write to specific place, which is pretty cool.
  330. Everything in the RAM disappears when you turn off the computer, so usually the programs and all kinds of information is persistently stored on the Disk. Which is called disk because it used to be spinning, but now most computers have SSD disks which are not *disks* at all, google 'SSD versus spinning disk' if you want to find more. So when the computer starts it will load some information from the disk into memory and start the operating system, which is just a program, not very different than the one you wrote for the touch typing, it takes input, does something with it and then has some output.
  331. ## [DAY-0] Files
  332. When you store something to disk you usually store it as a file, files can be all kinds, only text, or images, or just raw binary data used for different purposes. Text files are literally that, file that contains text, later you will learn that there is no such thing as text to the computer, all is just bits of information, but we (the humans) decided it is quite useless to look at some numbers of information, so our programs display information in different way, for example the file can contain the number 97 in its raw form 01100001, and if seen from a text editor, it will show the letter 'a', but if seem from image editor it might use it to show some blue-ish color, colors are stored in 4 numbers: transparency(called alpha), red,green and blue, but different formats use different way to store the colors, so it will depend on which format does the program think it is going to display.
  333. See it is all in the eye of the beholder, the file still contains only 97 (01100001), but each program will decide what to do with it.
  334. There are also Directories(also called Folders) (which in many file systems are also files.. but we will get to that later), that can contain files or other directories. Example structure looks like:
  335. ```
  336. /
  337. ├─ home/
  338. │ ├─ jack/
  339. │ | ├─ type.py
  340. │ | ├─ example.txt
  341. │ | ├─ image.jpg
  342. ```
  343. The word File is used because people that made those things up were thinking of filing cabinet, with lots of folders that contains pieces of paper.
  344. ```
  345. /
  346. /
  347. /____________________
  348. |________ __________
  349. /_____ /|| |
  350. |".___."| || |
  351. |_______|/ | |
  352. || .___."|| /
  353. ||_______|| /
  354. |_________|/ Felix Lee
  355. ```
  356. > See how those pictures have sometimes names attached to them. Those are their creators, some pictures are from the 80s, so it is amazing we can still find out who made them. You should always attribute the work of an artist.
  357. So the name 'File' and 'Folder' is used. If people were thinking of libraries I guess we would've been using Book for a file and Shelve for Folder? Anyway, my point is: all things have names, some of the names are strange and old, so don't worry if they make no sense.
  358. ## [DAY-0] ASCII
  359. Computers do not understand text, so when you see text it is usually some number that is displayed as a character, for example 65 is A, 66 is B, and so on. About 60 years ago some people agreed on a common way to map number to character, called THE ASCII STANDARD, super fancy name, for such a simple thing.
  360. ```
  361. 32 SPC 64 @ 96 `
  362. 33 ! 65 A 97 a
  363. 34 " 66 B 98 b
  364. 35 # 67 C 99 c
  365. 36 $ 68 D 100 d
  366. 37 % 69 E 101 e
  367. 38 & 70 F 102 f
  368. 39 ' 71 G 103 g
  369. 40 ( 72 H 104 h
  370. 41 ) 73 I 105 i
  371. 42 * 74 J 106 j
  372. 43 + 75 K 107 k
  373. 44 , 76 L 108 l
  374. 45 - 77 M 109 m
  375. 46 . 78 N 110 n
  376. 47 / 79 O 111 o
  377. 48 0 80 P 112 p
  378. 49 1 81 Q 113 q
  379. 50 2 82 R 114 r
  380. 51 3 83 S 115 s
  381. 52 4 84 T 116 t
  382. 53 5 85 U 117 u
  383. 54 6 86 V 118 v
  384. 55 7 87 W 119 w
  385. 56 8 88 X 120 x
  386. 57 9 89 Y 121 y
  387. 58 : 90 Z 122 z
  388. 59 ; 91 [ 123 {
  389. 60 < 92 \ 124 |
  390. 61 = 93 ] 125 }
  391. 62 > 94 ^ 126 ~
  392. 63 ? 95 _
  393. ```
  394. Try to decode: 110 105 99 101 32 119 111 114 107 33
  395. ## [DAY-0] Magic
  396. ```
  397. ______________ _ _,-----------._ ___
  398. | | (_,.- _,-'_,-----------._`-._ _)_)
  399. | THE _ _ _ | | ,'_,-' ___________ `-._`.
  400. | | / \|_)| \ | `' ,',' _,-'___________`-._ `.`.
  401. | |__\_/| \|_/ | ,',' ,'_,-' . `-._`. `.`.
  402. | | /,' ,',' >|< `.`. `.\
  403. | OF THE _ _ | // ,',' >< ,^. >< `.`. \\
  404. | |_)||\|/_(_ | // /,' >< / | \ >< `.\ \\
  405. | | \|| |\_|_) | // // >< \/\^/\/ >< \\ \\
  406. |______________| ;; ;; `---' :: ::
  407. || || (____ || ||
  408. DOORS OF DURIN _||__||_ ,'----. _||__||_
  409. (o.____.o)____ `---' ____(o.____.o)
  410. | | /,--.) (,--.\ | |
  411. | |(( -`___ ___` ))| |
  412. | | \\,'', `. .' .``.// | |
  413. | | // (___,'. .'.___) \\ | |
  414. /| | ;;)) ____) . . (____ ((\\ | |\
  415. \|.__ | ||/ .'.--.\/ `/,--.`. \;: | __,|;
  416. |`-,`;.| :/ /,' `)-' `-(' `.\ \: |.;',-'|
  417. | `.. ' / \__.' `.__/ \ ` ,.' |
  418. | |,\ /, ,\ /,| |
  419. | ||: : ) . ( : :|| |
  420. /| |:; |/ . ./|\, , \| :;| |\
  421. \|.__ |/ : ,/- <--:--> ,\. ; \| __,|;
  422. |`-.``: `'/-. '\|/` ,-\`; ;'',-'|
  423. | `.. ,' `' ' ` `. ,.' |
  424. | || : : || |
  425. | || | | || |
  426. | || | | || |
  427. | |' | _ | `| |
  428. | | | '|)) | | |
  429. ;____: `._ `' _,' ;____:
  430. {______} \___________________/ {______}
  431. SSt |______|_______________________________|______|
  432. ```
  433. Have you seen The Lord of the Rings? Do you remember the Door of Durin? Where Gandalf couldn't remember how to enter and the fellowship almost got eaten?
  434. The experience through this book will feel like that. Sometimes you will be stuck, and I mean really really stuck, and at some point, as if the cosmos itself colludes, something will click, and you will level up. Sadly I can not know when this will happen to **you**, as every person is different.
  435. ## [DAY-0] How to Google
  436. Anything you don't know how to do, you should use google to search for answers. However it is not easy to know what is good link to read and what is not, try to read from verified sources, like wikipedia, python.org, stackoverflow, mozilla and university websites, ask your parent to help.
  437. There is a lot of scams on the internet, you will open websites that claim you have viruses on your computer and you need to pay 20$ to clean it, or that you need to install this amazing program that will speed up your internet. Sometimes on very trusted websites you will see ads that are pure scams, for example ads that looks like Download buttons to get the program you wanted, but it will just download a virus.
  438. Its getting increasingly difficult to distinguish between good and bad information as well, some websites are just poorly written articles, so they can make people clicking on them in order to get money from ads. With time, and with the help of your parent you will learn how to recognize the good articles.
  439. The rules about how to use the internet are:
  440. * The internet is sus!
  441. * Never put your real name or phone number or address anywhere
  442. * Never download anything unless your parent approves
  443. * Never run anything you downloaded (sometimes downloads just start automatically)
  444. * Don't trust messages like 'click here to get free iPhone' or 'clean your computer for free'
  445. * Always ask your parent for help if you are not sure.
  446. There is noting free on the internet. Even this book, even though I am writing it for free, and you can get it for free, but I am hosting it on GitHub (and I don't pay for that), and GitHub, and therefore Microsoft, knows you are reading it, and later they will use that information to show you better ads, or maybe they will use it for some other purpose, like to train a machine to create artificial text, but one thing you must remember is that there is nothing free on the internet.
  447. ## [DAY-1] Touch Typing
  448. Touch typing is just typing without looking, if you are super slow while typing you will get frustrated too soon.
  449. Use https://www.keybr.com/ or ask someone to recommend you something. After using the touch typing app for few days, write your own.
  450. ## [DAY-2] Install python
  451. In general the first thing you should do when you don't know how to do something is to google it.
  452. So google 'how to install python', you will see lots of results, some of them will tell you how to install the old version of python, and some will be for the too old or too new version of windows. This makes things a bit more difficult.
  453. Try to download from https://www.python.org/downloads/ and do it yourself, ask your parent for help if you are stuck.
  454. ## [DAY-2] Make a useful program
  455. After you have installed python3 run IDLE (ask your parent for help) and go to File -> New File and type:
  456. ```
  457. import random
  458. letters = 'fjfjfjfjfjfjjfghghghgaa;a;a;abcdefghijklmnopqrstuvwxyz'
  459. difficulty = 2
  460. while True:
  461. q = ''
  462. for i in range(difficulty):
  463. q = q + random.choice(letters)
  464. a = input(q + ': ')
  465. if a == q:
  466. difficulty += 1
  467. else:
  468. if difficulty > 2:
  469. difficulty -= 1
  470. ```
  471. Then hit F5 (this will ask you to save the file as well) to run the program. If it is too easy, try adjusting the difficulty or the letters.
  472. The program will ask you to type some letters, after you are done, hit enter, and it will ask you for more or less letters. It will keep doing that forever. It kind of looks like this:
  473. ```
  474. aj: aj
  475. akg: akg
  476. jjgh: jjgh
  477. ```
  478. If you type it correctly, it will ask for a bigger sequence of characters, and if you make mistake it will ask for smaller.
  479. Don't rush it.
  480. Place your fingers properly on the keyboard, open https://images.google.com and search for 'touch typing' you will see many images of how to place your fingers.
  481. ## [DAY-3] Touch Typing using your program
  482. Open IDLE again, go to File -> Open File, and find where you saved your program, then double click to open it. After opened hit F5 and it will start again.
  483. Spend the rest of the time for the day touch typing. Don't rush it. Place your fingers properly on the keyboard and slowly type the letters.
  484. > Spend the whole day touch typing and making and opening new files in IDLE and notepad; I cant stress enough how important it is for the kid to be independent to be able on its own to make or open a file.
  485. ## [DAY-4] HTML - Basics
  486. We will start with HTML.
  487. Making a page can be a bit overwhelming, so just start small. for example:
  488. Open notepad and make a file on your desktop named "first.html", then write in it:
  489. ```
  490. <html>
  491. <body>
  492. <h1>welcome!</h1>
  493. <p>this is my page</p>
  494. </body>
  495. </html>
  496. ```
  497. Open Windows Explorer and find the file on your desktop and double click on it.
  498. Congrats! You have made your first web page!
  499. Now try this:
  500. ```
  501. <html>
  502. <body>
  503. <marquee>
  504. <h1>check this out!</h1>
  505. </marquee>
  506. <mark>Why would somebody use this?</mark>
  507. </body>
  508. </html>
  509. ```
  510. The rest of the day you will just try some other examples:
  511. List:
  512. ```
  513. <html>
  514. <body>
  515. <ul>
  516. <li>first <b>item</b></li>
  517. <li>second <i>item</i></li>
  518. <li>third</li>
  519. </ul>
  520. </body>
  521. </html>
  522. ```
  523. Horizontal Line:
  524. ```
  525. <html>
  526. <body>
  527. first
  528. line<br>
  529. second line<br>
  530. <hr>
  531. third line<br>
  532. </body>
  533. </html>
  534. ```
  535. 'br' means line break, when the browser sees it know it has to show whatever comes next on another line, 'hr' means horizontal rule,just like when you take your ruler and draw a line from left to right in the text book. You see, even though you write things in separate lines (like the word first and line are clearly on separate lines), the browser will not know what to do until you tell it to 'br'. Maybe in school you had a project you have to use PowerPoint to make a presentation? With the special words ul, li, br, hr, h2 and b you can make your own presentation in HTML!
  536. ## [DAY-5] HTML - Basics
  537. The app you are using right now to see this website is called a web browser, I don't know if kids still call it like that, but adults do.
  538. First the browser app downloads the web page, which is just a normal text file (it is what you see when you click on View Source), then it has to process it, in the same way you read pigpen code or ascii code, you look symbol by symbol and try to make sense out of it by making it into letters you understand.
  539. It looks for word between '<' and then '>', when it sees '<' it knows what ever is between '<' and '>' is important word. Then it has kind of a table so it know what to do with different words, when it sees 'b' it knows that whatever is inside is gonna get **bold**. There are many words like that you should try for yourself 'b' 'i' 'u' 'h1', and many more.
  540. For example, try this on your page: `<b>this is bold</b>`
  541. ## [DAY-6] Touch Typing
  542. Spend half the time using your program and half the time on keybr.com.
  543. ## [DAY-7] New Touch Typing Program
  544. Make new file on your desktop, touchtyping.html and type in it:
  545. ```
  546. <center>
  547. <pre style="font-size: 30px; letter-spacing: 4px;" id="question"></pre>
  548. </center>
  549. <script>
  550. var makeNewQuestion = function() {
  551. var letters = 'fjfjfjfjfjfjjfghghghgaa;a;a;abcdefghijklmnopqrstuvwxyz'
  552. var difficulty = 10
  553. var q = []
  554. for (var i = 0; i < difficulty; i++) {
  555. q.push(letters.charAt(Math.floor(Math.random() * letters.length)));
  556. }
  557. return q
  558. }
  559. var currentQuestion = makeNewQuestion()
  560. var questionElement = document.getElementById("question")
  561. questionElement.innerHTML = currentQuestion.join("")
  562. var position = 0
  563. document.body.addEventListener('keydown', (e) => {
  564. if (e.key == currentQuestion[position]) {
  565. position++
  566. if (position == currentQuestion.length) {
  567. currentQuestion = makeNewQuestion()
  568. position = 0
  569. } else {
  570. currentQuestion[position-1] = '<b>' + currentQuestion[position-1] + '</b>'
  571. }
  572. questionElement.innerHTML = currentQuestion.join("")
  573. }
  574. })
  575. </script>
  576. ```
  577. Don't worry about what it all means. Just type it character by character. Now double click on the file and try out your program, just start typing as the web page is open, and characters will become bold as you type them.
  578. ## [DAY-8] Touch Typing
  579. Today just spend the day chilling on keybr.com
  580. > We spend considerable amount of time on touchtyping and learning english, not all the time spent is reflected in the book, but at least 2 times per week, either on our own practice programs or keybr.com, by day 190 my daughter is at around 50 words per minute and blind typing. The amount spend typing builds really good relationship with the computer, as it has extremely smooth learning curve, and sense of progression. In contrast with programming which is a learning staircase, with walls you have to break through, and sometimes you have to spend months on the same level until the puzzle pieces click together. Some days when she is frustrated or tired I just ask her to type for 20-30 minutes while listening to music, which turns into a bit of meditating experience.
  581. ## [DAY-9] Touch Typing using your program
  582. Open touchtyping.html and spend the day using your awesome program. Once you open it, right click and then click on `View Source` to remember that you actually wrote this! Good job!
  583. ## [DAY-10] HTML - Basics
  584. From now on the HTML examples will be more code and less text, so you just have to go through them with your parent.
  585. ```
  586. <html>
  587. <body>
  588. <h2>welcome!</h2>
  589. <p>
  590. this is my <b>first web page</b> it has also <i>weird twist</i>!
  591. </p>
  592. <hr>
  593. <p>
  594. and a line
  595. </p>
  596. </body>
  597. </html>
  598. ```
  599. Try to touch type as you are writing this, no need to hurry.
  600. ```
  601. <html>
  602. <body>
  603. <h2>welcome!</h2>
  604. <p>
  605. this is my <b>first web page</b>!
  606. </p>
  607. and it has a bug!<br>
  608. <button onclick="document.body.appendChild(this.cloneNode(true))">🐛</button>
  609. </body>
  610. </html>
  611. ```
  612. This is a funny one, you might not know how to write 🐛, but just google 'bug emoji' and copy it from there. After you open the web page, click on the bug to see what happens.
  613. You see we add this `onclick=...` which is code that is going to run every time you click on the bug, and what this code does it copies the button and adds it to the page, including the `onclick=..` stuff, so the other button you can press and it will copy itself again!
  614. Try to add more buttons by yourself with other emojis, 🏍️, 🏂, 🐓 or 🐧 for example.
  615. ## [DAY-11] HTML - Basics
  616. Making a presentation with HTML
  617. ```
  618. <html>
  619. <body style="font-size: 24px;">
  620. <h1>Presentation For School</h1>
  621. <small>by: John, from class 4</small>
  622. <br>
  623. <br>
  624. <br>
  625. <br>
  626. <br>
  627. <hr>
  628. <h1>First Slide</h1>
  629. <ul>
  630. <li>Something</li>
  631. <li>very <b>important</b></li>
  632. <li>and very <i>strange</i></li>
  633. </ul>
  634. <br>
  635. <br>
  636. <br>
  637. <hr>
  638. <h1>Second Slide</h1>
  639. <ul>
  640. <li>Something Else</li>
  641. <li>very <u>underline</u></li>
  642. <li>and very <del>weird</del></li>
  643. </ul>
  644. <br>
  645. <br>
  646. <br>
  647. <hr>
  648. <h1>Third Slide</h1>
  649. <ul>
  650. <li>... surely we can come up with a line</li>
  651. <li>... and another line</li>
  652. </ul>
  653. <br>
  654. <br>
  655. <br>
  656. <hr>
  657. </body>
  658. </html>
  659. ```
  660. ## [DAY-12] Touch Typing
  661. Use your program to touch type or go to keybr.com.
  662. Don't rush.
  663. ## [DAY-13] HTML
  664. This day is completely free style, try to put all kinds of HTML words inside each other, for example:
  665. ```
  666. <html>
  667. <body>
  668. <marquee>
  669. <ul>
  670. <li>
  671. <h1>
  672. <i>
  673. hello
  674. </i>
  675. </h1>
  676. </li>
  677. </ul>
  678. </marquee>
  679. </body>
  680. </html>
  681. ```
  682. Try to add the self cloning 🐛 button to that page.
  683. ## [DAY-14] HTML - Tables
  684. Tables are amazing, in fact, tables are one of the things that makes the modern world work. In your school for example, there is a table with the name of each student and their score. Or in your TV there is a table with each program number and the program there (e.g. 24 is 24 Kitchen). On your iPhone there are many programs that use many tables internally to make decisions. There is of course the ASCII table, which can tell you how to get from a character to its raw representation and the other way around. The periodic table is also a famous example. The table on the bus stop tells you which bus will come at what time.
  685. We use tables everywhere.
  686. Here are few examples:
  687. | power | pokemons |
  688. |-|-|
  689. | electiricy | Pikachu |
  690. | fire | Charmander |
  691. | grass | Bulbasaur |
  692. | poison | Bulbasaur |
  693. Or something you have probably seen, a multiplication table:
  694. | a | x | b | = |
  695. |---|---|---|----|
  696. | 5 | * | 5 | 25 |
  697. | 5 | * | 6 | 30 |
  698. | 5 | * | 7 | 37 |
  699. Make new file (or open the some old html page) and type this:
  700. ```
  701. <html>
  702. <body>
  703. <table border="10">
  704. <tr><th>Name</th><th>Year</th></tr>
  705. <tr>
  706. <td>
  707. Donald Duck
  708. </td>
  709. <td>
  710. 1937
  711. </td>
  712. </tr>
  713. <tr>
  714. <td>
  715. Daisy Duck
  716. </td>
  717. <td>
  718. 1940
  719. </td>
  720. </tr>
  721. <tr>
  722. <td>
  723. Scrooge McDuck
  724. </td>
  725. <td>
  726. 1947
  727. </td>
  728. </tr>
  729. <tr>
  730. <td>
  731. Ludwig Von Drake
  732. </td>
  733. <td>
  734. 1961
  735. </td>
  736. </tr>
  737. </table>
  738. </body>
  739. </html>
  740. ```
  741. Only 3 new tags we have to learn `table, tr, td, th` are the main things we will work with, `tr` means table row and `td` is table data cell, or a column, `th` is table header. All the html key words you have learned so far are called `tags` or `elements`.
  742. Make `<table border="100">` and see what happens.
  743. ## [DAY-15] HTML - More tables
  744. ```
  745. <html>
  746. <body>
  747. <table border="10">
  748. <tr><th>Name</th><th>Year</th></tr>
  749. <tr>
  750. <td>
  751. <marquee>
  752. hello world
  753. </marquee>
  754. </td>
  755. <td>
  756. <marquee>
  757. hello universe
  758. </marquee>
  759. </td>
  760. </tr>
  761. <tr>
  762. <td>
  763. <b>this does not move</b>
  764. </td>
  765. <td>
  766. <marquee>
  767. <i>this is italic</i>
  768. </marquee>
  769. </td>
  770. </tr>
  771. </table>
  772. </body>
  773. </html>
  774. ```
  775. Now make list in a table
  776. ```
  777. <table border=100>
  778. <tr>
  779. <td>
  780. <ul>
  781. <li>a</li>
  782. <li>b</li>
  783. <li>c</li>
  784. </ul>
  785. </td>
  786. <td>
  787. <ol>
  788. <li>a</li>
  789. <li>b</li>
  790. <li>c</li>
  791. </ol>
  792. </td>
  793. </tr>
  794. </table>
  795. ```
  796. Super small difference between `ul` and `ol`, one means 'unordered list' and the other one 'ordered list', so if you use `ol` every `li` will have its own number
  797. ## [DAY-16] HTML - Multiplication table
  798. Start writing the whole multiplication table
  799. (will take more than 1 day)
  800. ## [DAY-17] HTML - Multiplication table
  801. Finish writing the whole multiplication table.
  802. ## [DAY-18] Touch Typing
  803. Spend the day touch typing.
  804. ## [DAY-19] HTML - Links
  805. The most powerful feature of HTML is to be able to link to another place in the internet, try this:
  806. ```
  807. <html>
  808. <body>
  809. hi, <a href="https://wikipedia.com">click here</a> to go to wikipedia
  810. </body>
  811. </html>
  812. ```
  813. The `a` tag with its `href` attribute is one of the most important things of the modern internet, it means I can have a web page, and I can link to someone else's web page, and they can link to someone else and so on..
  814. Whatever is in the `href` attribute this is where the browser will go after you click on whatever is inside the `<a></a>`, in our case `click here`. So after you click on `click here` your browser will go to wikipedia.com, and from there when you click somewhere it will go to wherever that `a`'s `href` points to.
  815. ## [DAY-20] HTML - Tree
  816. Rainbow:
  817. ```
  818. <html>
  819. <body>
  820. <h1>🌈</h1>
  821. <h1 style="color: red;">red</h1>
  822. <h1 style="color: orange">orange</h1>
  823. <h1 style="color: yellow">yellow</h1>
  824. <h1 style="color: green">green</h1>
  825. <h1 style="color: blue">blue</h1>
  826. <h1 style="color: indigo">indigo</h1>
  827. <h1 style="color: violet">violet</h1>
  828. </body>
  829. </html>
  830. ```
  831. You dont always need `html` and `body`, the most browsers will show a page anyway, but it is good practice to do it proper and use `html` and `body` tags. Anyway, the next example is not "up to code".
  832. IT will make a sheep that follows your mouse, its pretty cool.
  833. ```
  834. <div id='sheep' style='position:absolute'>🐑</div>
  835. <script>
  836. var sheep = document.getElementById('sheep')
  837. document.body.onmousemove = (e) => {
  838. sheep.style.left = (e.clientX - 5 + 'px');
  839. sheep.style.top = (e.clientY - 5 + 'px');
  840. }
  841. </script>
  842. ```
  843. And a ghost button! it will remove itself when you press it.
  844. ```
  845. <button onclick="this.parentNode.removeChild(this)">👻</button>
  846. ```
  847. The way it works is `onclick=...` will call the code when you click on the button, in this case it says, "whoever *my* parent is, tell it to remove myself form its children list".
  848. You see, HTML is like a tree, let me show you.
  849. lets say our page is:
  850. ```
  851. <html>
  852. <body>
  853. <table border="10">
  854. <tr><th>Name</th><th>Year</th></tr>
  855. <tr>
  856. <td>
  857. <mark>
  858. hello
  859. </mark>
  860. </td>
  861. <td>
  862. <h1>
  863. world
  864. </h1>
  865. </td>
  866. </tr>
  867. <tr>
  868. <td>
  869. <b>move</b>
  870. </td>
  871. <td>
  872. <marquee>
  873. <i>italic</i>
  874. </marquee>
  875. </td>
  876. </tr>
  877. </table>
  878. </body>
  879. </html>
  880. ```
  881. It actually is a tree, every tag has children, and siblings
  882. ```
  883. <html>
  884. |
  885. <body>
  886. |
  887. <table>
  888. / | \
  889. / | \
  890. / | \
  891. / | \
  892. / | \
  893. / | \
  894. <tr> <tr> <tr> <--- siblings, same parent
  895. /\ / \ / \
  896. / \ / \ / \
  897. <th> <th> <td> <td> <td> <td> <--- the two td with same parent
  898. | | | | | | are siblings
  899. Name Year <mark> <h1> <b> <marquee>
  900. | | | |
  901. hello world move <i>
  902. |
  903. italic
  904. ```
  905. Well trees in the world are actually the other way around haha. Leave it to programmers to not know how to make a tree :)
  906. ```
  907. italic
  908. |
  909. hello world move <i>
  910. | | | |
  911. Name Year <mark> <h1> <b> <marquee>
  912. | | | | | |
  913. <th> <th> <td> <td> <td> <td>
  914. \ / \ / \ /
  915. \/ \ / \ /
  916. <tr> <tr> <tr>
  917. \ | /
  918. \ | /
  919. \ | /
  920. \ | /
  921. \ | /
  922. \ | /
  923. <table>
  924. |
  925. <body>
  926. |
  927. <html>
  928. ```
  929. But you can see how all things that have the same parent are related, like brothers and sisters.
  930. This is very important, we will spend the next week thinking about it as well.
  931. ## [DAY-21] HTML - View Source
  932. Browsers on laptops or pcs will allow you to rightclick on any page and then click on `View page source`, this will show you the HTML of the page your are looking at.
  933. Open https://archive.org then right click on the pager and then click on `View page source`.
  934. We will spend the rest of the day looking at some page sources
  935. * https://archive.org
  936. * https://www.spacejam.com
  937. * https://www.asciiart.eu/
  938. * https://www.wikipedia.org
  939. * https://www.gutenberg.org/
  940. * https://digitalcomicmuseum.com/
  941. * https://www.terrypratchettbooks.com/
  942. * https://www.goodreads.com/
  943. ## [DAY-22] HTML - Inspect
  944. Make new html file and write the following example:
  945. ```
  946. Right click on this page, click Inspect and then go to Console.
  947. <script>
  948. console.log('🐺🐺🐺🐺 You can see that in the console. 🐺🐺🐺🐺')
  949. console.log('🐺🐺🐺🐺 type 12312*18237978123 in the console and see what happens. 🐺🐺🐺🐺')
  950. </script>
  951. ```
  952. Open the file and then click F12, or right click on the page and click Inspect. You will see the logs.
  953. This will open the developer tools of your browser, you will be able to see the console, where you can run small programs or see the errors and the logs of the current page. Try writing `12312*18237978123` in the console and see the result.
  954. In the inspector you can also modify the HTML that you see. This wont modify the actual page on the server you are downloading from, but you can try things to see how they would look. There are actually many scammers that use this method to lie to people as if they are giving them money, or they say 'I will teach you how to add 10000 robux to your account if you pay me 5$' and they just show you how to inspect and edit the html you see. This does not actually give you robux of course, it just modifies your local version of the html to show different value and after you reload the page you will see the old value.
  955. Lets try it. Make a new file with this content:
  956. ```
  957. <html>
  958. <body>
  959. Your Robux Balance is: <b>0$</b>
  960. </body>
  961. </html>
  962. ```
  963. Open the file and then right click on `0$` and click inspect. Then you will see `<b>0$</b>` if you double click on it, you will be able to change it, and you will see the new version. Now reload the page, and you will see the old value is back.
  964. ## [DAY-23] HTML - Images
  965. To show an image you need the `img` tag, and give it `src` attribute with the address of the image, for example if I want to display https://picsum.photos/id/237/200/300 I have to do type it like this:
  966. ```
  967. <html>
  968. <body>
  969. <img src="https://picsum.photos/id/237/200/300">
  970. <img src="https://picsum.photos/id/40/200/300">
  971. </body>
  972. </html>
  973. ```
  974. Lets put the images in a table:
  975. ```
  976. <html>
  977. <body>
  978. <table>
  979. <tr>
  980. <td>
  981. <img src="https://picsum.photos/id/237/200/300">
  982. </td>
  983. <td>
  984. <img src="https://picsum.photos/id/40/200/300">
  985. </td>
  986. </tr>
  987. </table>
  988. </body>
  989. </html>
  990. ```
  991. Now of course we can have `img` in `a`, try this:
  992. ```
  993. <html>
  994. <body>
  995. <table>
  996. <tr>
  997. <td>
  998. <a href="https://wikipedia.com">
  999. <img src="https://picsum.photos/id/237/200/300">
  1000. </a>
  1001. </td>
  1002. <td>
  1003. <a href="https://gutenberg.org">
  1004. <img src="https://picsum.photos/id/40/200/300">
  1005. </a>
  1006. </td>
  1007. </tr>
  1008. </table>
  1009. </body>
  1010. </html>
  1011. ```
  1012. Now you can click on the dog or the nose and it will lead you to the pages you link to.
  1013. Is it possible to have `img` and text in `a`? Well I am glad you asked!
  1014. ```
  1015. <html>
  1016. <body>
  1017. <table>
  1018. <tr>
  1019. <td>
  1020. <a href="https://wikipedia.com">
  1021. <img src="https://picsum.photos/id/237/200/300">
  1022. <br>
  1023. This dog leads to wikipedia
  1024. </a>
  1025. </td>
  1026. <td>
  1027. <a href="https://gutenberg.org">
  1028. <img src="https://picsum.photos/id/40/200/300">
  1029. <br>
  1030. This cat (I think) leads to guttenberg.org
  1031. </a>
  1032. </td>
  1033. </tr>
  1034. </table>
  1035. </body>
  1036. </html>
  1037. ```
  1038. I even have `<br>` in the `a`, now you can click either on the image or on the text.
  1039. There is one more very important attribute of the `img` tag, and this is the `alt` attribute, it is used by people who are blind or visually impaired to know what kind of picture is on the page. In our example we can put `alt="puppy"` on the puppy picture.
  1040. ```
  1041. <p>
  1042. Hello, and welcome to my page.
  1043. I hope you will like this image.
  1044. </p>
  1045. <img src="https://picsum.photos/id/237/200/300" alt="puppy">
  1046. ```
  1047. If a blind person visits this page, they use a screen reader that reads most of the text on the page, and if we have `alt` attribute on images it will say `Image ...` and whatever the value of `alt` is, in our case "puppy". So the reader will say:
  1048. ```
  1049. Hello, and welcome to my page. I hope you will like this image.
  1050. Image puppy.
  1051. ```
  1052. If you have an image that has no information, like it is just there to make the site pretty, use `alt=""` then the screen reader will skip it.
  1053. ## [DAY-24] Licenses
  1054. If you take a picture of something you are the owner of that picture, and you can put it on your website and say you have the rights of that picture. It is up to you to decide if people should link to it by deciding what under license you will publish the image. There are many licenses you can choose from, there are some that say 'this picture is free for anyone to do whatever they want' or 'you can republish the picture but you cant make money selling it' or 'you can publish it but not print it in books' etc etc.
  1055. Complicated stuff this licensing, but the thing you have to remember, it is up to the creator to decide under what license their work can be distributed.
  1056. Some licenses you can check out with your parents:
  1057. * Creative Commons Licenses CC-BY https://creativecommons.org/licenses/
  1058. * GPL https://www.gnu.org/licenses/gpl-3.0.en.html
  1059. * MIT License https://opensource.org/licenses/MIT
  1060. * Apache License https://www.apache.org/licenses/LICENSE-2.0
  1061. * Public Domain https://en.wikipedia.org/wiki/Public-domain-equivalent_license
  1062. * Copyright https://en.wikipedia.org/wiki/Copyright
  1063. When you want to use someone else's work and it is not clear what license it uses, it is best to ask them. At least that is what I do. People are usually nice and they give me permission to use their work.
  1064. It is somewhat controversial what is the right way forward, which license to use and what is the best for you and for the world. Ask to your parent about what happens when you take a picture of a painting of a picture of a video and then you edit the video to include the picture you took in it..
  1065. Check out https://tldrlegal.com/ for super short description of licenses
  1066. ## [DAY-25] Touch Typing
  1067. relax and spend the day touch typing
  1068. ## [DAY-26] HTML - Title
  1069. ```
  1070. <html>
  1071. <head>
  1072. <title>THIS IS SPARTA</title>
  1073. </head>
  1074. <body>
  1075. <marquee>
  1076. <ul>
  1077. <li>
  1078. <a href="https://wikipedia.com">click me</a>
  1079. </li>
  1080. <li>
  1081. <mark>hello world</mark>
  1082. </li>
  1083. </ul>
  1084. </marquee>
  1085. </body>
  1086. </html>
  1087. ```
  1088. Usually bodies have a `<head>` hehe.
  1089. In html in the `head` tag you can put things that will help the browser. For example, what is the `title` of this page? or what language is this page? Who is the author of this page? etc..
  1090. You can also put there some style, changing the body's background color, or the color of the text in the `h1` or `p`:
  1091. ```
  1092. <html>
  1093. <head>
  1094. <style>
  1095. body {
  1096. background: blue;
  1097. }
  1098. p {
  1099. color: pink;
  1100. }
  1101. h1 {
  1102. color: cyan;
  1103. }
  1104. </style>
  1105. <title>some title</title>
  1106. </head>
  1107. <body>
  1108. <center>
  1109. <p>
  1110. Hello Universe
  1111. </p>
  1112. <h1>hello world</h1>
  1113. </center>
  1114. </body>
  1115. </html>
  1116. ```
  1117. The _language_ we use inside the `style` tag is called `CSS`, and it is quite simple (on its surface). We wont get deep into it for a while, but if you are interested check out at https://developer.mozilla.org/en-US/docs/Web/CSS
  1118. You see how in certain tags we can use different language, not html, like in `<style>` we use CSS, in `<script>` we use JavaScript, we are going to do more work with it soon, but you can check out at https://developer.mozilla.org/en-US/docs/Web/JavaScript
  1119. ## [DAY-27] HTML - Fun (JS)
  1120. Many buttons
  1121. ```
  1122. <button onclick="makeManyButtons()">🤖</button>
  1123. <script>
  1124. function makeManyButtons() {
  1125. // try to make million buttons!
  1126. for(var i = 0; i < 100; i++) {
  1127. var button = document.createElement('button')
  1128. button.innerText = '🐹'
  1129. document.body.appendChild(button)
  1130. }
  1131. }
  1132. </script>
  1133. ```
  1134. Replicator
  1135. ```
  1136. <button onclick="replicate(10,'🦊')">🤖</button>
  1137. <script>
  1138. function replicate(n,buttonText) {
  1139. // try to make million buttons!
  1140. for(var i = 0; i < n; i++) {
  1141. var button = document.createElement('button')
  1142. button.onclick = function () {
  1143. replicate(20,'🦓')
  1144. };
  1145. button.innerText = buttonText
  1146. document.body.appendChild(button)
  1147. }
  1148. }
  1149. </script>
  1150. ```
  1151. Canvas
  1152. ```
  1153. <html>
  1154. <body style="padding: 0; margin: 0">
  1155. <canvas id="squares"></canvas>
  1156. <script>
  1157. var canvas=document.getElementById('squares');
  1158. var ctx=canvas.getContext("2d");
  1159. canvas.width=window.innerWidth;
  1160. canvas.height=window.innerHeight;
  1161. function draw() {
  1162. ctx.fillStyle= '#' + Math.floor(Math.random()*16777215).toString(16);
  1163. ctx.globalAlpha=0.5;
  1164. var size=Math.floor((Math.random()) * 60) + 1;
  1165. var x = Math.floor(Math.random()*canvas.width)
  1166. var y = Math.floor(Math.random()*canvas.height)
  1167. ctx.fillRect(x, y, size, size);
  1168. };
  1169. setInterval(draw,10);
  1170. // why dont you try to make them rectangles instead of squares?
  1171. // or maybe even circles? google for 'canvas fillRect' and 'canvas arc'
  1172. </script>
  1173. </body>
  1174. </html>
  1175. ```
  1176. The last one is quite crazy! But I am sure you will like the result when done.
  1177. ## [DAY-28] Print; Functions; While; Variables; Conditions
  1178. Make a new file form IDLE, and write in it:
  1179. ```
  1180. print("Hi!")
  1181. ```
  1182. Hit F5 and enjoy!
  1183. Your first(or second) python program.. Quite useless, but nevertheless. A program is a program!
  1184. `print()` is called a function, functions are kind of mini useful programs, this one will print whatever you tell it. In this case `print("Hi!")` will output `Hi!`. Pretty amazing, I hope one day to explain to you what goes into showing a character on your screen. Remind me to show you Ben Eater's 6502 videos when you grow up.
  1185. `"Hi!"` is a string, strings are just series of characters, you can make them in python with `"something"` or `'something'`, either single quotes or double quotes.
  1186. ```
  1187. while True:
  1188. print("Hi!")
  1189. ```
  1190. `while True` that means forever. so you will see:
  1191. ```
  1192. Hi!
  1193. Hi!
  1194. Hi!
  1195. Hi!
  1196. Hi!
  1197. Hi!
  1198. Hi!
  1199. Hi!
  1200. ...
  1201. ```
  1202. Hi forever.
  1203. ```
  1204. while 1 == 1:
  1205. print("Hi!)
  1206. ```
  1207. `1 == 1` is also True, so this is the same as `while True`
  1208. So `while <condition>` will keep running the code **inside** it, while the condition holds true, which in the case of `1 == 1` will always be the case.
  1209. ```
  1210. while True:
  1211. zzz = input("what is your name: ")
  1212. print(zzz)
  1213. ```
  1214. `input` asks you to type something, and it returns whatever you typed.
  1215. `zzz = input(....)` takes whatever input returns, and puts it into memory that we can use later. `zzz` is just a name I picked so I can refer to this value later in the program, in this case on the next line when I do `print(zzz)`
  1216. `print(name)` prints whatever is in the memory pointed by `zzz`.
  1217. `zzz` is called a `variable`, you can choose the names of your variables, and `zzz` is surely a poor name, because if I use it 100 lines later in the code, I will forget what kind of information it stores, so usually we give names of the variables that make sense, for example:
  1218. ```
  1219. while True:
  1220. name = input("what is your name: ")
  1221. print(name)
  1222. ```
  1223. A group of statements with common parent, is called **code block**, in python we use spaces to say what belongs where, so the closest `while,for,if,elif,else` going up is the parent.
  1224. ```
  1225. while True:
  1226. name = input("what is your name: ")
  1227. print(name)
  1228. ```
  1229. Will throw an error: `IndentationError: unexpected indent` because it makes no sense, there is no valid parent to `print`, This is quite unique in python, most other languages make code blocks with `{}`, but python makes it prettier and easier to read by using indentation (the spaces/tabs). `print(name)` has 4 spaces, while `name = input..` has 2 spaces, so python expect everything in the `while:` to have 2 spaces unless a new block starts.
  1230. ```
  1231. while True:
  1232. name = input("what is your name: ")
  1233. if name == "pikachu":
  1234. print(name)
  1235. ```
  1236. This works fine, `print(name)` now has valid parent that also has a parent.
  1237. ```
  1238. while True:
  1239. | \
  1240. | \
  1241. | \
  1242. | \
  1243. if: name = input
  1244. |
  1245. print(name)
  1246. ```
  1247. `while True` has two children, `name = input ..` and `if name == ..` so they must have same indentation, then `if ..:` also expects a code block, so the children of `if name == ..` need to have one more indentation to whatever indentation the `if` had.
  1248. Anyway..
  1249. Don't worry too much about it, just don't panic when you see `IndentationError`, and I can promise you, you will see a lot of those. Look at where you got the spaces wrong, and if the block has correct parent.
  1250. You have seen by now in JavaScript we use `{}` to group statements into blocks.
  1251. ```
  1252. if (name == "pikachu") {
  1253. console.log("pikaaaachuuuuu")
  1254. console.log("evolutiooonn!")
  1255. }
  1256. ```
  1257. Now lets break out of the loop!
  1258. ```
  1259. while True:
  1260. name = input("what is your name: ")
  1261. if name == "pikachu":
  1262. break
  1263. ```
  1264. `if name == "pikachu":` will run the code inside `if` if whatever is in the `name` variable is equal to the string "pikachu". In this case its only 1 instruction inside it, the `break` instruction.
  1265. `break` breaks out of the closest `while` loop, so basically this program will ask what is your name until you type pikachu. It is a bit boring because we never actually print what you typed.
  1266. ```
  1267. while True:
  1268. name = input("what is your name: ")
  1269. print(name)
  1270. if name == "pikachu":
  1271. break
  1272. print("DONE")
  1273. ```
  1274. There we go, now it will ask you to type a name, it will print whatever name you typed, and then it will check if the name is equal to "pikachu" it will break the while loop and stop asking. We can actually write this program in a different way. After you break out of the loop, it just continues to execute the program below, in this case will print DONE.
  1275. ```
  1276. name = ''
  1277. while name != "pikachu":
  1278. name = input("what is your name: ")
  1279. print(name)
  1280. print("DONE")
  1281. ```
  1282. MAGIC!
  1283. we start by making name equal to empty string, a string with no characters, and then we check is the statement `name != "pikachu"` True? If this is True we will execute the code **inside** the while loop, after the last instruction in the loop, the program jumps back to `while name != "pikachu"` and checks again is name still not equal to "pikachu"? if the statement is False it will not run the code **inside** but will continue, in the above example it will print DONE, because this is the first thing **after** the while loop.
  1284. Lets make a more complicated one, this one will ask you what is your name, and if you answer pikachu will print pikaaaaaaachuuuuu and stop, any other answer it will print "Hello, " + answer, so if you type "Jane" it will show "Hello, Jane" and it will ask again.
  1285. ```
  1286. while True:
  1287. name = input("what is your name: ")
  1288. if name == "pikachu":
  1289. print("pikaaaaaaachuuuuu")
  1290. break
  1291. else:
  1292. print("Hello, " + name)
  1293. ```
  1294. In python you can add two strings, if you type "charmander" for name, `x = "Hello, " + name` will make x to be equal to "Hello, charmander". You can't do `"hello" - name`, but you can do `"hello" * 5` and get "hellohellohellohellohello".
  1295. `while,if,else,break` are keywords, kind of like `<html>` and `<body>`, `<h1>` etc, those are coming from python itself. There are not many python keywords, for reference, this is the **complete** list:
  1296. ```
  1297. False
  1298. True
  1299. None
  1300. and -> name == "pikachu" and age == "33"
  1301. or -> name == "pikachu" or name == "charmander"
  1302. not -> not name == "pikachu" is the same as name != "pikachu"
  1303. for -> used if you know how many times you want to do something
  1304. while -> do something until condition is True
  1305. break -> break out of the for or while loop
  1306. continue -> go to the start of the while/for loop and continue from there
  1307. if -> if something is true
  1308. elif -> else if something else is true
  1309. else -> else do this
  1310. in -> checks if something is in somethhing else, e.g. "pika" in name
  1311. def -> make a function
  1312. as
  1313. assert
  1314. async
  1315. await
  1316. class
  1317. del
  1318. except
  1319. finally
  1320. from
  1321. global
  1322. import
  1323. is
  1324. lambda
  1325. nonlocal
  1326. pass
  1327. raise
  1328. return
  1329. try
  1330. with
  1331. yield
  1332. ```
  1333. THATS THE WHOLE LANGUAGE, there are no more keywords.
  1334. ## [DAY-29] Print; If
  1335. ```
  1336. print("Welcome to the forest!")
  1337. print("This is a world of magic and wonders. You are on a cross road, you can go north east south or west.")
  1338. print("South leads to the swamps, where the aligators live")
  1339. print("West leads to the mountains, where the yeti lives")
  1340. print("North leads to the jungle, where the tigres live")
  1341. print("East leads to the desert, where the meerkats live")
  1342. print("")
  1343. what = input("what would you do next: ")
  1344. if what == "east":
  1345. print("Welcome to the desert")
  1346. print("It is very hot, and you need remember to put sun screen.")
  1347. print("Oh, you remember to put your hat as well.")
  1348. print("In the distance you see a meerkat approaching.")
  1349. print("What would you do? Run or Fight the meerkat?")
  1350. print("")
  1351. what = input("what would you do next: ")
  1352. if what == "run":
  1353. print("You start running, and the meerkat is super fast, it catches you in no time.")
  1354. elif what == "fight":
  1355. print("You try to fight it, but turns out it was friendly and wants to become your friend.")
  1356. print("What would you do?")
  1357. print("")
  1358. what = input("Do you want to be its friend: ")
  1359. if what == "yes":
  1360. print("Great! Now the meerkat wants to introduce you to his family.")
  1361. elif what == "no":
  1362. print("The meerkat starts crying!")
  1363. else:
  1364. print("I dont understand: " + what)
  1365. ```
  1366. That is a lot of typing.
  1367. In python there are few very important things. First even though it doesn't look like it, it is actually a tree, like HTML tree. The parent of `print("The meerkat starts crying!")` is `elif what == "no":`
  1368. ```
  1369. |
  1370. |
  1371. if what == "east"
  1372. |
  1373. / | \
  1374. / | \
  1375. / | \
  1376. / | \
  1377. / | \
  1378. if else elif
  1379. what == "run" | what == "fight
  1380. | | |
  1381. print print / \
  1382. / \
  1383. / \
  1384. / \
  1385. if elif
  1386. what == "yes" what == "no"
  1387. | |
  1388. [ ... ] [ ... ]
  1389. ```
  1390. Lets discuss another example:
  1391. ```
  1392. a = "he"
  1393. b = "ll"
  1394. c = "o"
  1395. if a == "he":
  1396. if b == "ll":
  1397. if c == "o":
  1398. print("hello")
  1399. ```
  1400. Can you tell who is the parent of who?
  1401. BTW, you can also use `and`, `or` and `not` when you want to see if something is `True`
  1402. ```
  1403. a = "he"
  1404. b = "ll"
  1405. c = "o"
  1406. if a == "he" and b == "ll" and c == "o":
  1407. print("hello")
  1408. ```
  1409. ## [DAY-30] Functions; Lists
  1410. Our game is quite limited, and a quick step to improve it is to make you ask where you want to go until you pick one of the options.
  1411. ```
  1412. def ask(possible_answers):
  1413. answer = ''
  1414. print("---") # print empty line
  1415. while True:
  1416. answer = input("> What would you do next: ")
  1417. if answer not in possible_answers:
  1418. print("> try again, it must be one of:", possible_answers)
  1419. else:
  1420. return answer
  1421. print("Welcome to the forest!")
  1422. #...
  1423. what = ask(["east","west","north","south"])
  1424. if what == "east":
  1425. print("Welcome to the desert")
  1426. #...
  1427. what = ask(["run","fight"])
  1428. if what == "run":
  1429. print("You start running, and the meerkat is super fast, it catches you in no time.")
  1430. elif what == "fight":
  1431. print("You try to fight it, but turns out it was friendly and wants to become your friend.")
  1432. # ...
  1433. what = ask(["yes","no"])
  1434. if what == "yes":
  1435. print("Great! Now the meerkat wants to introduce you to his family.")
  1436. elif what == "no":
  1437. print("The meerkat starts crying!")
  1438. elif what == "north":
  1439. print("Welcome to the north pole, it is super cold here.")
  1440. ```
  1441. `ask` is a function, just like `print` or `input`, it will keep asking you `> What would you do next: ` until the answer you type is in the possible_answers list, and if it is it will return it to wherever it is called from. So when we have `zzz = ask(["yes","no"]` the value of `zzz` will be whatever is returned from `ask`. Same as `name = input("what is your name)` will put in `name` whatever is returned from `input` which is whatever you typed on your keyboard.
  1442. To make a function in python you need to use the `def` keyword.
  1443. ```
  1444. def sum(a,b):
  1445. return a + b
  1446. r = sum(1737,1231231)
  1447. print(r)
  1448. ```
  1449. Whatever is between `def` and `(` is the name of the function, in the above example its `sum`. Between `()` you put in the name of the variables you expect to use when someone calls your function. I want to sum two numbers, I dont know what the numbers are, so I just make two variables `a, b` and expect whoever calls my function to give me the numbers, like `r = sum(1737,1231231)`
  1450. ## [DAY-31] Functions; If; Random; Lists
  1451. FIGHT TO THE DEATH!
  1452. ```
  1453. import random
  1454. import time
  1455. def fight(playerHP, enemyHP, enemy_name):
  1456. # fight to the death!
  1457. while playerHP >= 0 and enemyHP >= 0:
  1458. punch = random.randint(0, 20)
  1459. if random.choice(["player","enemy"]) == "player":
  1460. playerHP = playerHP - punch
  1461. print("<"+enemy_name+"> hits you for " + str(punch) + ", " + str(playerHP) + " left")
  1462. else:
  1463. enemyHP = enemyHP - punch
  1464. print("you hit <"+enemy_name+"> for " + str(punch) + ", " + str(enemyHP) + " left")
  1465. time.sleep(1)
  1466. return playerHP
  1467. fight(100, 50, "meerkat")
  1468. ```
  1469. `import` imports a module.
  1470. `random` and `time` those are the `modules` you import, modules are just a group of functions that you can use, for example `time.sleep(1)` makes python sleep for 1 second, it calls the function `sleep()` in the `time` module. `random.choice()` you can give a list of things to choose from, and it will randomly select one of the list. `random.randint(0,20)` means give me a random number between 0 and 20.
  1471. `str` is needed to convert integer to string, because 1 is not the same as "1", "1" is actually the ASCII value of the character 1, so somehow we have to convert the raw number 1 to ASCII code 61, and `str()` does that.
  1472. lets use it now in our dungeon game
  1473. ```
  1474. import random
  1475. import time
  1476. def ask(possible_answers):
  1477. ...
  1478. def fight(playerHP, enemyHP, enemy_name):
  1479. ...
  1480. ...
  1481. health = 100
  1482. what = ask(["east","west","north","south"])
  1483. if what == "east":
  1484. ...
  1485. what = ask(["run","fight"])
  1486. if what == "run":
  1487. ...
  1488. elif what == "fight":
  1489. meerkatHP = 50
  1490. health = fight(health, meerkatHP, "meerkat")
  1491. if health <= 0:
  1492. print("GAME OVER! THE MEERKAT BEAT YOU")
  1493. else:
  1494. print("You won against the meerkat, you have " + str(health) + " HP left))
  1495. ```
  1496. ## [DAY-32] Lists; While
  1497. Today you have to make only two programs:
  1498. ```
  1499. bad = ["broccoli","chocolate","pineapple"]
  1500. while True:
  1501. food = input("what is your favorite food: ")
  1502. if food in bad:
  1503. print("ewwwww I hate " + food)
  1504. else:
  1505. print("yumm, I love " + food)
  1506. ```
  1507. And the second one:
  1508. ```
  1509. bad = ["broccoli","chocolate","pineapple"]
  1510. good = ["pizza","popcorn"]
  1511. while True:
  1512. food = input("what is your favorite food: ")
  1513. if food in bad:
  1514. print("ewwwww I hate " + food)
  1515. elif food in good:
  1516. print("yumm, I love " + food)
  1517. else:
  1518. print("I have never tried " + food)
  1519. ```
  1520. Great job!
  1521. Spend the rest of the day touch typing.
  1522. ## [DAY-33] For
  1523. `for` does something number of times, if I want to print the numbers from 0 to 99, I could do:
  1524. ```
  1525. for i range(100):
  1526. print(i)
  1527. ```
  1528. or
  1529. ```
  1530. for i in range(10, 20):
  1531. print(i)
  1532. ```
  1533. will print the numbers from 10 to 19
  1534. ```
  1535. colors = ["red","green","blue"]
  1536. for color in colors:
  1537. print(color)
  1538. ```
  1539. will print each of the elements in the list. If you want to print each character of a string in a similar way you can do:
  1540. ```
  1541. name = "jack"
  1542. for c in name:
  1543. print(c)
  1544. ```
  1545. prints:
  1546. ```
  1547. j
  1548. a
  1549. c
  1550. k
  1551. ```
  1552. ## [DAY-34] Love Tester
  1553. ```
  1554. def love_test(a,b):
  1555. sum = 0
  1556. for c in a+b:
  1557. print(c + ': ' + str(ord(c)))
  1558. sum += ord(c)
  1559. print('sum is:' + str(sum))
  1560. return sum % 100
  1561. while True:
  1562. nameA = input("first name: ")
  1563. nameB = input("second name: ")
  1564. print("love test: " + str(love_test(nameA,nameB)))
  1565. ```
  1566. `ord` takes the ascii code of a character.
  1567. `%` is the remainder, so `109 % 100` is 9, basically what is left after you can cleanly divide two numbers, `812 % 100` is 12, you can fit 100 in 819 exactly 8 times, and then there is 12 left, this 12 is the remainder.
  1568. So in this program we take two names into the variables `nameA` and `nameB` and then we give them to the love_test function, which sums the ascii code of `nameA+nameB`, and then returns the remainder of 100.
  1569. ```
  1570. first name: jack
  1571. second name: jane
  1572. j: 106
  1573. a: 97
  1574. c: 99
  1575. k: 107
  1576. j: 106
  1577. a: 97
  1578. n: 110
  1579. e: 101
  1580. sum is:823
  1581. love test: 23
  1582. ```
  1583. BTW, now you know how those "professional" love testers are made, so if you use https://www.lovetester.nl/ or something similar.. don't read too much into the result. You can easily tweak it to do whatever you want.
  1584. ## [DAY-34] Touch Typing
  1585. Whoaa it has been a difficult week.
  1586. Relax with some touch typing.
  1587. ## [DAY-35] Lists; While; Continue
  1588. This week there will be less talking and more programming.
  1589. Make a program to help you to decide what to do:
  1590. ```
  1591. import random
  1592. possible = ["nothing"]
  1593. while True:
  1594. x = input("What would you like to do: ")
  1595. if x == "done":
  1596. break
  1597. else:
  1598. possible.append(x)
  1599. what = random.choice(possible)
  1600. print("possible choices: ")
  1601. print(possible)
  1602. print("the magic 8 ball decided: " + what)
  1603. ```
  1604. Make a program to help you multiply two numbers:
  1605. ```
  1606. while True:
  1607. a = int(input("first number: "))
  1608. b = int(input("second number: "))
  1609. print(a, "*", b, "=", a*b)
  1610. ```
  1611. Here I do a little trick, and make print print numbers instead of making them into string by passing it as separate parameters to the print function. otherwise I have to do:
  1612. ```
  1613. while True:
  1614. a = int(input("first number: "))
  1615. b = int(input("second number: "))
  1616. print(str(a) + " *" + str(b) + "=" + str(a*b))
  1617. ```
  1618. What is your spy name?
  1619. ```
  1620. name = input("what is your name: ")
  1621. print("Your spy name is: " + name[0] + name[1])
  1622. ```
  1623. You can get individual characters from string by picking them up with `[]` so if name is 'jane' then `name[0]` is 'j'
  1624. Make a calculator
  1625. ```
  1626. while True:
  1627. a = int(input("first number: "))
  1628. b = int(input("second number: "))
  1629. op = input("operation * / + :")
  1630. result = 0
  1631. if op == "*":
  1632. result = a * b
  1633. elif op == "/":
  1634. result = a/b
  1635. elif op == "+":
  1636. result = a+b
  1637. else:
  1638. print("I dont understand " + op)
  1639. continue
  1640. print(a,op,b,'=',result)
  1641. ```
  1642. See how we use `continue` to not print a result if we don't understand the operation. `continue` jumps to the beginning of the loop.
  1643. ## [DAY-36] While; Range; Functions
  1644. Print the numbers from 0 to 9 FOREVER
  1645. ```
  1646. while True:
  1647. for i in range(10):
  1648. print(i)
  1649. ```
  1650. Print each character of a string:
  1651. ```
  1652. name = input("what is your name: ")
  1653. for c in name:
  1654. print(c)
  1655. ```
  1656. Sum the numbers from 0 to 99
  1657. ```
  1658. sum = 0
  1659. for i in range(100):
  1660. sum = sum + i
  1661. print(sum)
  1662. ```
  1663. Print all the prime numbers from 0 to 100:
  1664. ```
  1665. def is_prime(n):
  1666. if n == 1 or n == 0:
  1667. return False
  1668. for i in range(2, n):
  1669. if n % i == 0:
  1670. return False
  1671. return True
  1672. for i in range(100):
  1673. print(i, is_prime(i))
  1674. ```
  1675. multiply two numbers:
  1676. ```
  1677. a = int(input("number 1: "))
  1678. b = int(input("number 2: "))
  1679. c = a * b
  1680. print(c)
  1681. ```
  1682. Timer:
  1683. ```
  1684. import time
  1685. s = int(input("how many seconds: "))
  1686. for i in range(s):
  1687. print(i)
  1688. time.sleep(1)
  1689. print(s, "SECONDS ARE OVER")
  1690. ```
  1691. ## [DAY-37] While; Functions
  1692. Clock
  1693. ```
  1694. import datetime
  1695. import time
  1696. import os
  1697. while True:
  1698. os.system('clear')
  1699. now = datetime.datetime.now()
  1700. print(now)
  1701. time.sleep(1)
  1702. ```
  1703. Calendar
  1704. ```
  1705. def show(calendar):
  1706. for row in calendar:
  1707. for day in row:
  1708. print(day,end=' ')
  1709. print('')
  1710. june = [
  1711. ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
  1712. [' ', ' ', ' 1', ' 2', ' 3', ' 4', ' 5'],
  1713. [' 6', ' 7', ' 8', ' 9', '10', '11', '12'],
  1714. ['13', '14', '15', '16', '17', '18', '19'],
  1715. ['20', '21', '22', '23', '24', '25', '26'],
  1716. ['27', '28', '29', '30', ' ', ' ', ' '],
  1717. ]
  1718. show(june)
  1719. ```
  1720. Growing list of food.
  1721. ```
  1722. food = []
  1723. while True:
  1724. what = input("what is your favorite food: ")
  1725. food.append(what)
  1726. print(what)
  1727. ```
  1728. Guessing game
  1729. ```
  1730. colors = ["red","green","blue"]
  1731. score = 0
  1732. while True:
  1733. guess = input("guess a color: ")
  1734. if guess in colors:
  1735. print("good guess! I like " + guess)
  1736. else:
  1737. print("nop, I dont like " + guess)
  1738. ```
  1739. Guess again
  1740. ```
  1741. def is_in_list(list,what):
  1742. for element in list:
  1743. if element == what:
  1744. return True
  1745. return False
  1746. colors = ["red","green","blue"]
  1747. score = 0
  1748. while True:
  1749. guess = input("guess a color: ")
  1750. if is_in_list(colors, guess):
  1751. print("good guess! I like " + guess)
  1752. else:
  1753. print("nop, I dont like " + guess)
  1754. ```
  1755. ## [DAY-38] Strings
  1756. What was your name again?
  1757. ```
  1758. for i in range(10):
  1759. name = input("what is your name: ")
  1760. print(i)
  1761. print(name)
  1762. ```
  1763. First and last letter:
  1764. ```
  1765. name = input("what is your name: ")
  1766. print("first letter: " + name[0])
  1767. print("last letter: " + name[len(name)-1])
  1768. ```
  1769. to get the last letter we have to count however letters are in the whole name, so `len(name)` will return 4 for 'jane' and it counts from 1
  1770. ```
  1771. len("jane"):
  1772. j a n e
  1773. 1 2 3 4
  1774. len("ja")
  1775. j a
  1776. 1 2
  1777. ```
  1778. but when we are using `[0]` to get to specific character from a string or element from a list, it counts from 0, so
  1779. ```
  1780. j a n e
  1781. 0 1 2 3
  1782. name = "jane"
  1783. name[0] is j
  1784. name[1] is a
  1785. name[2] is n
  1786. name[3] is e
  1787. len(name) is 4 (because len counts from 1)
  1788. so name[len(name) - 1], is name[4 - 1] or name[3] which is the last letter
  1789. ```
  1790. Make a Line
  1791. ```
  1792. def line(width, symbol):
  1793. for x in range(width):
  1794. print(symbol,end='')
  1795. line(20, '#')
  1796. line(30, '*')
  1797. line(40, '_')
  1798. ```
  1799. Make a triangle
  1800. ```
  1801. def line(width, symbol):
  1802. for x in range(width):
  1803. print(symbol,end='')
  1804. for i in range(100):
  1805. line(i,'*')
  1806. print('')
  1807. ```
  1808. Make a beam
  1809. ```
  1810. def line(width, symbol):
  1811. for x in range(width):
  1812. print(symbol,end='')
  1813. for i in range(50):
  1814. line(i, ' ')
  1815. line(i, '*')
  1816. print('')
  1817. ```
  1818. Make a box
  1819. ```
  1820. def line(width, symbol):
  1821. for x in range(width):
  1822. print(symbol,end='')
  1823. def box(width,height,symbol):
  1824. for y in range(height):
  1825. line(width,symbol)
  1826. print('')
  1827. box(16,20)
  1828. box(10,20,'#')
  1829. box(15,13,'*')
  1830. ```
  1831. ## [DAY-39] Touch Typing
  1832. Do some touch typing.
  1833. ## [DAY-40] Functions; Strings; Range
  1834. Make inverse beam
  1835. ```
  1836. def line(width, symbol):
  1837. for x in range(width):
  1838. print(symbol,end='')
  1839. count = 50
  1840. for i in range(count):
  1841. line(count - i, ' ')
  1842. line(i, '*')
  1843. print('')
  1844. ```
  1845. Make a tree
  1846. ```
  1847. def line(width, symbol):
  1848. for x in range(width):
  1849. print(symbol,end='')
  1850. count = 50
  1851. for i in range(count):
  1852. half = int((count-i)/2)
  1853. line(half , ' ')
  1854. line(i, '*')
  1855. print('')
  1856. ```
  1857. Inverse
  1858. ```
  1859. def line(width, symbol):
  1860. for x in range(width):
  1861. print(symbol,end='')
  1862. count = 50
  1863. for i in range(count):
  1864. line(count-i, '*')
  1865. print('')
  1866. ```
  1867. Inverse tree
  1868. ```
  1869. def line(width, symbol):
  1870. for x in range(width):
  1871. print(symbol,end='')
  1872. count = 50
  1873. for i in range(count):
  1874. half = int(i/2)
  1875. line(half , ' ')
  1876. line(count-i, '*')
  1877. print('')
  1878. ```
  1879. Art
  1880. ```
  1881. def line(width, symbol):
  1882. for x in range(width):
  1883. print(symbol,end='')
  1884. while True:
  1885. count = 10
  1886. for i in range(count):
  1887. line(count-i, '*')
  1888. print('')
  1889. for i in range(count):
  1890. line(i, '#')
  1891. print('')
  1892. ```
  1893. Looks so pretty!
  1894. ```
  1895. #
  1896. ##
  1897. ###
  1898. ####
  1899. #####
  1900. ######
  1901. #######
  1902. ########
  1903. #########
  1904. **********
  1905. *********
  1906. ********
  1907. *******
  1908. ******
  1909. *****
  1910. ****
  1911. ***
  1912. **
  1913. *
  1914. #
  1915. ##
  1916. ###
  1917. ####
  1918. #####
  1919. ######
  1920. #######
  1921. ########
  1922. #########
  1923. **********
  1924. *********
  1925. ********
  1926. *******
  1927. ******
  1928. *****
  1929. ****
  1930. ***
  1931. **
  1932. *
  1933. ```
  1934. ## [DAY-41] Basics of Basics
  1935. More Art
  1936. ```
  1937. import random
  1938. def line(width, symbol):
  1939. for x in range(width):
  1940. print(symbol,end='')
  1941. symbols = ['*','#','%','^','&']
  1942. while True:
  1943. count = random.randint(5,80)
  1944. symbol = random.choice(symbols)
  1945. for i in range(count):
  1946. line(count-i, symbol)
  1947. print('')
  1948. symbol = random.choice(symbols)
  1949. for i in range(count):
  1950. line(i, symbol)
  1951. print('')
  1952. ```
  1953. Staircase
  1954. ```
  1955. def line(width, symbol):
  1956. for x in range(width):
  1957. print(symbol,end='')
  1958. count = 100
  1959. for i in range(0, count, 5):
  1960. line(i, '*')
  1961. print('')
  1962. ```
  1963. Range is so cool, and you didnt even notice!
  1964. Try this:
  1965. ```
  1966. for i in range(0, 100, 10):
  1967. print(i)
  1968. ```
  1969. it will print
  1970. ```
  1971. 0
  1972. 10
  1973. 20
  1974. 30
  1975. 40
  1976. 50
  1977. 60
  1978. 70
  1979. 80
  1980. 90
  1981. ```
  1982. so every 10th number, now try:
  1983. ```
  1984. for i in range(0, 100, 5):
  1985. print(i)
  1986. ```
  1987. and
  1988. ```
  1989. for i in range(0, 100, 2):
  1990. print(i)
  1991. ```
  1992. Of course you dont have to start counting from 0:
  1993. ```
  1994. for i in range(50, 100, 2):
  1995. print(i)
  1996. ```
  1997. Do some touch typing if there is time left.
  1998. ## [DAY-41] Lists; If; While
  1999. ```
  2000. import random
  2001. words = ["pizza","pikachu","ball","pokemon"]
  2002. while True:
  2003. word = random.choice(words)
  2004. guessed = []
  2005. life = 10
  2006. while True:
  2007. print('*' * 10, ' HANGMAN ', '*' * 10)
  2008. matching = 0
  2009. for c in word:
  2010. if c in guessed:
  2011. print(c,end='')
  2012. matching = matching + 1
  2013. else:
  2014. print('-',end='')
  2015. print('')
  2016. print('*' * 31)
  2017. if matching == len(word):
  2018. print('congratz you won!')
  2019. break
  2020. character = input("guess a character: ")
  2021. if character in word:
  2022. guessed.append(character)
  2023. else:
  2024. print(character + " is not in the word, " + str(life) + ' lives left')
  2025. life = life - 1
  2026. if life == 0:
  2027. print('you lost!')
  2028. break
  2029. ```
  2030. ## [DAY-42] Lists; Functions; Grid; While
  2031. World without a player
  2032. ```
  2033. def render(world):
  2034. for row in world:
  2035. for col in row:
  2036. print(col,end=' ')
  2037. print('')
  2038. def empty():
  2039. return [
  2040. ['-','-','-','-'],
  2041. ['-','-','-','-'],
  2042. ['-','-','-','-'],
  2043. ['-','-','-','-'],
  2044. ['-','-','-','-'],
  2045. ['-','-','-','-'],
  2046. ['-','-','-','-'],
  2047. ]
  2048. world = empty()
  2049. render(world)
  2050. while True:
  2051. row = int(input("which row (count from 0): "))
  2052. col = int(input("which column (count from 0): "))
  2053. world[row][col] = 'x'
  2054. render(world)
  2055. ```
  2056. World with a player
  2057. ```
  2058. def render(world):
  2059. for row in world:
  2060. for col in row:
  2061. print(col,end=' ')
  2062. print('')
  2063. def empty():
  2064. return [
  2065. ['-','-','-','-'],
  2066. ['-','-','-','-'],
  2067. ['-','-','-','-'],
  2068. ['-','-','-','-'],
  2069. ['-','-','-','-'],
  2070. ['-','-','-','-'],
  2071. ['-','-','-','-'],
  2072. ]
  2073. world = empty()
  2074. player_row = 0
  2075. player_col = 0
  2076. world[player_row][player_col] = 'x'
  2077. render(world)
  2078. while True:
  2079. direction = input("which direction: ")
  2080. world[player_row][player_col] = '*'
  2081. if direction == "up":
  2082. player_row = player_row - 1
  2083. elif direction == "down":
  2084. player_row = player_row + 1
  2085. elif direction == "left":
  2086. player_col = player_col - 1
  2087. elif direction == "right":
  2088. player_col = player_col + 1
  2089. world[player_row][player_col] = 'x'
  2090. render(world)
  2091. ```
  2092. ## [DAY-43] If; Range
  2093. Even and Odd
  2094. ```
  2095. number = int(input("give me a number: "))
  2096. if number % 2 == 0:
  2097. print("this number is even")
  2098. else:
  2099. print("this number is odd")
  2100. ```
  2101. Fizz Buzz
  2102. Print integers 1 to N, but print "fizz" if an integer is divisible by 3, "buzz" if an integer is divisible by 5, and "fizzbuzz" if an integer is divisible by both 3 and 5.
  2103. ```
  2104. n = 100
  2105. for i in range(1,n+1):
  2106. if i % 5 == 0 and i % 3 == 0:
  2107. print("fizz buzz")
  2108. elif i % 3 == 0:
  2109. print("fizz")
  2110. elif i % 5 == 0:
  2111. print("buzz")
  2112. else:
  2113. print(i)
  2114. ```
  2115. or different version
  2116. ```
  2117. n = 100
  2118. for i in range(1,n+1):
  2119. fizzbuzzing = False
  2120. if i % 3 == 0:
  2121. fizzbuzzing = True
  2122. print("fizz", end = '')
  2123. if i % 5 == 0:
  2124. fizzbuzzing = True
  2125. print("buzz", end = '')
  2126. if not fizzbuzzing:
  2127. print(i, end = '')
  2128. print('')
  2129. ```
  2130. There are many ways to write this, lets just have fun.
  2131. ```
  2132. n = 100
  2133. numbers = []
  2134. # first make empty list with 100 elements
  2135. for i in range(1, n+1):
  2136. numbers.append('')
  2137. # then fill in the fizzes
  2138. for i in range(1, n+1):
  2139. if i % 3 == 0:
  2140. numbers[i-1] += 'fizz'
  2141. # then fill in the buzzess
  2142. for i in range(1, n+1):
  2143. if i % 5 == 0:
  2144. numbers[i-1] += 'buzz'
  2145. # then fill in the numbers
  2146. for i in range(1, n+1):
  2147. if numbers[i-1] == '':
  2148. numbers[i-1] = i
  2149. # then we print it
  2150. for x in numbers:
  2151. print(x)
  2152. ```
  2153. Haha this is a funny way to make fizzbuzz. See first it puts fizz if you can divide it by 3, and then buzz if you can divide it by 5, but if there was already fizz there it will just add if with `+=`, so it automatically works to put fizzbuzz for 15.
  2154. ## [DAY-44] Lists
  2155. Reviews
  2156. ```
  2157. reviews =[5,3,2,4,1,2,3,4,2,1,5,5,3,2]
  2158. sum = 0
  2159. for r in reviews:
  2160. sum += r
  2161. rating = sum / len(reviews)
  2162. print(str(rating) + "⭐ out ot 5")
  2163. ```
  2164. Icecream Maker
  2165. ```
  2166. import random
  2167. flavors = ['vanilla','chocolate','blue','banana','bluberry']
  2168. flavorA = random.choice(flavors)
  2169. flavorB = random.choice(flavors)
  2170. print(flavorA + " + " + flavorB)
  2171. ```
  2172. Spend the rest of the day touch typing.
  2173. ## [DAY-45] Lists; Functions
  2174. Different touch typing
  2175. ```
  2176. import random
  2177. vowels = ['a', 'e', 'i', 'o', 'u', 'y']
  2178. consonants = ['b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','z']
  2179. def make_word(n_chars):
  2180. word = ''
  2181. for i in range(n_chars):
  2182. if random.randint(1,100) < 40:
  2183. word += random.choice(vowels)
  2184. else:
  2185. word += random.choice(consonants)
  2186. return word
  2187. def make_sentence(n_words):
  2188. sentence = ''
  2189. for i in range(n_words):
  2190. sentence += make_word(random.randint(3,6))
  2191. sentence += ' '
  2192. # this will remove the last element from the sentence string
  2193. # so we dont have empty space in the end
  2194. return sentence[:-1]
  2195. while True:
  2196. sentence = make_sentence(random.randint(10,20))
  2197. print(sentence)
  2198. guess = input('write the sentence: ')
  2199. if guess != sentence:
  2200. print("SORRY")
  2201. else:
  2202. print("GOOD JOB")
  2203. ```
  2204. spend the rest of the day trying it out
  2205. ## [DAY-46] Basic Turtle
  2206. Some turtle!
  2207. ```
  2208. import turtle
  2209. turtle.circle(30)
  2210. ```
  2211. Many circles
  2212. ```
  2213. import turtle
  2214. for i in range(30):
  2215. turtle.circle(i)
  2216. ```
  2217. Bigger circles
  2218. ```
  2219. import turtle
  2220. turtle.color("blue")
  2221. for i in range(30):
  2222. turtle.circle(50 + i)
  2223. ```
  2224. Smile
  2225. ```
  2226. import turtle
  2227. turtle.color("blue")
  2228. turtle.circle(100)
  2229. turtle.penup()
  2230. turtle.goto(60,120)
  2231. turtle.pendown()
  2232. turtle.circle(20)
  2233. turtle.penup()
  2234. turtle.goto(20,120)
  2235. turtle.pendown()
  2236. turtle.circle(20)
  2237. turtle.penup()
  2238. turtle.goto(-30,20)
  2239. turtle.pendown()
  2240. turtle.right(45)
  2241. turtle.circle(20, 120)
  2242. ```
  2243. ## [DAY-47] Range; While
  2244. Try to make a program that prints a symbol N times, where N is coming from the user input.
  2245. Try by yourself.
  2246. ## [DAY-48] Strings; Functions
  2247. How big can a string be?
  2248. Your computer has limited amount of memory, usually 8 gigabytes, that is a lot of memory. 8 * 1024 megabytes * 1024 kilobytes * 1024 bytes, so 8589934592 bytes. What if we make python create a string with more characters than memory?
  2249. NB: before you try that, save all your files because you might have to restart your computer, depending on the operation system version.
  2250. ```
  2251. try_me = 'x' * (8 * 1024 * 1024 * 1024)
  2252. print(len(try_me))
  2253. ```
  2254. If you can not press any buttons after that, or the mouse is not working, you will have to hold the power button for 10 seconds to turn your computer off and then turn it back on.
  2255. lets try another thing
  2256. ```
  2257. def forever(n):
  2258. print(n)
  2259. forever(n+1)
  2260. forever(1)
  2261. ```
  2262. this will throw a weird error
  2263. ```
  2264. RecursionError: maximum recursion depth exceeded while pickling an object
  2265. ```
  2266. Don't be afraid of it, every time you call a function, a little bit of memory has to be used, and this memory is released when the function returns, now imagine a function that calls itself, so you get this:
  2267. ```
  2268. forever(1)
  2269. forever(1+1)
  2270. forever(1+1+1)
  2271. forever(....)
  2272. ```
  2273. So the memory for those function is never released, and this error just says, you cant go and call so many functions that never return. But you will see on your system you can have around 10000 functions that are waiting for their child to return.
  2274. Play with it a bit.
  2275. ```
  2276. def one(n):
  2277. print("one", n)
  2278. two(n+1)
  2279. def two(n):
  2280. print("two", n)
  2281. one(n+1)
  2282. one(1)
  2283. ```
  2284. ## [DAY-49] List; Dictionaries
  2285. ```
  2286. import random
  2287. game = [
  2288. ['What is the capital of France?','Paris','London','Paris','Berlin','Tokyo'],
  2289. ['What is the capital of Japan?','Tokyo','London','Paris','Berlin','Tokyo'],
  2290. ["What is Jane's favorite food?",'Popcorn','Pizza','Popcorn','Cucumber','Sushi']
  2291. ]
  2292. while True:
  2293. quiz = random.choice(game)
  2294. print(quiz[0])
  2295. for index, possible in enumerate(quiz):
  2296. if index >= 2:
  2297. print(possible)
  2298. answer = input('What is your answer: ')
  2299. if answer == quiz[1]:
  2300. print("✨✨✨ CORRECT ✨✨✨")
  2301. else:
  2302. print("INCORRECT")
  2303. ```
  2304. see `enumerate` is quite handy, you get the index of something and its value while you are doing the `for`
  2305. ```
  2306. x = ['a','b','c','d']
  2307. for index ,element in enumerate(x):
  2308. print(index)
  2309. print(' ' + element)
  2310. ```
  2311. make it easier to read:
  2312. ```
  2313. import random
  2314. QUESTION_IDX = 0
  2315. ANSWER_IDX = 1
  2316. game = [
  2317. ['What is the capital of France?','Paris','London','Paris','Berlin','Tokyo'],
  2318. ['What is the capital of Japan?','Tokyo','London','Paris','Berlin','Tokyo'],
  2319. ["What is Jane's favorite food?",'Popcorn','Pizza','Popcorn','Cucumber','Sushi']
  2320. ]
  2321. while True:
  2322. quiz = random.choice(game)
  2323. print(quiz[QUESTION_IDX])
  2324. for index, possible in enumerate(quiz):
  2325. if index >= ANSWER_IDX+1:
  2326. print(possible)
  2327. answer = input('What is your answer: ')
  2328. if answer == quiz[ANSWER_IDX]:
  2329. print("✨✨✨ CORRECT ✨✨✨")
  2330. else:
  2331. print("INCORRECT")
  2332. ```
  2333. See how just using QUESTION_IDX and ANSWER_IDX instead of 0 and 1 it is easier to read. Now lets try a completely different way:
  2334. ```
  2335. import random
  2336. game = [
  2337. {
  2338. "question": "What is the capital of France?",
  2339. "answer": "Paris",
  2340. "possible": ['London','Paris','Berlin','Tokyo'],
  2341. },
  2342. {
  2343. "question": "What is the capital of Japan?",
  2344. "answer": "Tokyo",
  2345. "possible": ['London','Paris','Berlin','Tokyo'],
  2346. },
  2347. ]
  2348. while True:
  2349. quiz = random.choice(game)
  2350. print(quiz["question"])
  2351. for p in quiz["possible"]:
  2352. print(' --> ' + p)
  2353. answer = input('What is your answer: ')
  2354. if answer == quiz["answer"]:
  2355. print("✨✨✨ CORRECT ✨✨✨")
  2356. else:
  2357. print("INCORRECT")
  2358. ```
  2359. This is just another way to do it, see in the list we can store those strange things. We will talk about them in a couple of weeks, I just wanted to show you how clean it is when
  2360. ## [DAY-50] Lists; If
  2361. Print the odd numbers from 0 to 999
  2362. ```
  2363. for i in range(1000):
  2364. if i % 2 != 0:
  2365. print(i)
  2366. ```
  2367. rock paper scissors
  2368. ```
  2369. import random
  2370. game = ["rock","paper","scissors"]
  2371. rounds = 3
  2372. nameA = input("name player A: ")
  2373. nameB = input("name player B: ")
  2374. winsA = 0
  2375. winsB = 0
  2376. for i in range(rounds):
  2377. playerA = random.choice(game)
  2378. playerB = random.choice(game)
  2379. print("ROUND: " + str(i + 1))
  2380. print("playerA : " + playerA)
  2381. print("playerB : " + playerB)
  2382. if playerA == playerB:
  2383. print(" > DRAW")
  2384. elif playerA == "rock" and playerB == "paper":
  2385. print(" > " + nameB + " WINS")
  2386. winsB += 1
  2387. elif playerA == "rock" and playerB == "scissors":
  2388. print(" > " + nameA + " WINS")
  2389. winsA += 1
  2390. elif playerA == "paper" and playerB == "rock":
  2391. print(" > " + nameA + " WINS")
  2392. winsA += 1
  2393. elif playerA == "paper" and playerB == "scissors":
  2394. print(" > " + nameB + " WINS")
  2395. winsB += 1
  2396. elif playerA == "scissors" and playerB == "rock":
  2397. print(" > " + nameB + " WINS")
  2398. winsB += 1
  2399. elif playerA == "scissors" and playerB == "paper":
  2400. print(" > " + nameA + " WINS")
  2401. winsA += 1
  2402. else:
  2403. print("WTF " + playerA + " " + playerB)
  2404. print("---")
  2405. print(nameA + " has " + str(winsA) + " points")
  2406. print(nameB + " has " + str(winsB) + " points")
  2407. if winsA > winsB:
  2408. print(nameA + " IS THE WINNER")
  2409. elif winsA < winsB:
  2410. print(nameB + " IS THE WINNER")
  2411. else:
  2412. # this will show only if we have even number of rounds
  2413. print("THERE IS NO WINNER")
  2414. ```
  2415. ## [DAY-51] Internet Awareness - Scams/Viruses
  2416. Today is an important day, its Internet awareness day.
  2417. Make the most expensive drone on amazon.com cost 0$, or even -5$. As we did in the first week, open inspect click on the mouse selector (or press Control+Shift+C) and click on the price you want to change, then double click on the HTML and change it to whatever you want.
  2418. After you are done reload the page to see it is not actually changed.
  2419. Now do that on roblox, make it look like you have 999999 robux.
  2420. Go to google and search for `Speed up your internet connection`, go over the websites one by one with your parent, and observe, look at many many scams, some are very easy to fall into, some are obvious.
  2421. Open youtube.com, search for 'free energy hack' watch some of the videos, then search for 'electroboom free energy' and watch Mehdi explain why it is a scam. Search for 'be carefull what you order from facebook ads' Pleasant Green and watch how he explains a scam with ads to buy a cool looking helmet.
  2422. See the internet is a place, where you can find great things, like electroboom and pleasant green or veritasium or vsauce, but also where there are horrible things, like people selling garbage for 30$. Or people claiming
  2423. Now with your parent, search on youtube for 'how to hack in roblox' and look at the scame, how people want to install something so they can steal your password.
  2424. ## [DAY-52] Internet Awareness - How Login Works
  2425. Ok now for something more serious!
  2426. Just a quick intro into cookies, when you login to a website, it stores a piece of information on your computer called a cookie, and with every request you make to the website after it sends this cookie, the website can also tell you to replace the cookie. This is how websites know you are logged in, after they check your user and password they send you a cookie with a secret value, that you use for every request, they store that value usually in a database (kind of like huge huge excel sheet, that you can quickly search in), and look it up to see if it is valid.
  2427. So imagine websites have a table like so:
  2428. |username|password|
  2429. |-|-|
  2430. |jane|123456|
  2431. |john|blabla|
  2432. It is a bit more complicated than that, because they don't store the password but "encrypted" version of the password, so instead of 123456 (which is a horrible password btw), they store the result of a cryptographic hash function, hash(salt + '___' + password), and salt is used so that the attacker has to get both the usernames, the encrypted passwords and the code that joins them in order to extract a password using some bruteforce methods.
  2433. A cryptographic hash function is like a machine where you put in a lego castle in, and it will spit out exactly 8 pieces (ot 32 or whatever the function is), and there is no easy way for you to guess what kind of castle you put in it, but you know that *always* the same castle will spit out the same 8 pieces.
  2434. So in reality the excel sheet looks a bit like this:
  2435. |username|encrypted password|salt|
  2436. |-|-|-|
  2437. |jane|4c87d9b2ecfbd99c483aedfae8045fe578912e63|someRandom123|
  2438. |john|065ce4538c7c51687270972babdeaa986f3ce1bd|someRandom435|
  2439. But that is not important, we will use the simple example for our case. When you click 'login' it will send the username and password over the internet, and their server will look in the table for this user and will check if the password matches. If it matches it will insert a row another excel sheet that looks like this:
  2440. |username|token|
  2441. |-|-|
  2442. |jane|bbd0bff806a177f082f3ba2cff33030d335c296e|
  2443. then tell your browser, hey set this cookies:
  2444. ```
  2445. the username for amazon.com is 'jane'
  2446. the token is bbd0bff806a177f082f3ba2cff33030d335c296e
  2447. ```
  2448. So next time when you make a request to amazon your browser will send both the user name and the token, amazon will check in the token table if this token is valid (they have expiration date as well, kind of like a real token), and then it will know you actually logged in, without your password being stored on your browser.
  2449. Now lets see how someone can login as you without knowing your password.
  2450. Login to amazon. Open chrome in private mode. Open amazon there as well, and see that on one browser you are logged in, on the private mode you are not. Now open the console(press F12) on the logged in browser and type this:
  2451. ```
  2452. var cookies = []
  2453. for (cookie of document.cookie.split(";")) {
  2454. cookies.push(cookie.replace(" ", ""))
  2455. }
  2456. console.log(JSON.stringify(cookies))
  2457. ```
  2458. This will print all the cookies amazon has set on your browser in a list.
  2459. Copy the whole list of cookies, now on the private mode browser's console(press F12 to open the console) type:
  2460. ```
  2461. var newCookies = ["session-id....." .. .. ] // just paste the whole string from the other browser
  2462. for (cookie of newCookies) {
  2463. document.cookie = cookie;
  2464. }
  2465. ```
  2466. Paste the whole list there, and refresh the page.
  2467. And voila! You are logged in now without typing a password.
  2468. So if you give access to somebody to your computer, they can trivially copy your cookies and send them somewhere, and then they can login as you without even knowing your password. In fact this is a very common way to steal someone's account on social media. Ask them to paste a strange code in the console, which is usually `base64 encoded` that looks like this:
  2469. ```
  2470. d = atob('dmFyIGNvb2tpZXMgPSBbXQpmb3IgKGNvb2tpZSBvZiBkb2N1bWVudC5jb29raWUuc3BsaXQoIjsiKSkgewogICAgY29va2llcy5wdXNoKGNvb2tpZS5yZXBsYWNlKCIgIiwgIiIpKQp9CmNvbnNvbGUubG9nKGNvb2tpZXMpCg==')
  2471. console.log(d)
  2472. eval(d)
  2473. ```
  2474. You see how it printed your cookies? The thing that runs the code is `eval` it is kind of like double clicking on a program, but it will run the code that is inside the string you give it. If you want to see what the code does just run `console.log(atob('....'))` this will just decode the base64 encoding into a string you can read. `atob` decodes base64 string into the real string, it is kind of like in python `ord('a')` gives you 97 and `chr(97)` gives you 'a'.
  2475. Of course the code that the scammers give you is more sophisticated, it sends the cookies to their database(think excel sheet) via the internet, including all local storage and local session data, and they can just use it after that.
  2476. That is why if you open facebook.com and press F12 you will see giant message:
  2477. ```
  2478. STOP STOP STOP
  2479. This is a browser feature intended for developers. If someone has told you to copy and paste something here to enable a Facebook feature or "hack" someone else's account, it is a scam and they are trying to access your Facebook account.
  2480. ```
  2481. When you Logout from somewhere, they delete the token on their side, so the next time a request is made, they know you are not logged in anymore. That is why its important to logout if you use someone else's computer to login.
  2482. ## [DAY-53] Basics of the Internet - IP/DNS
  2483. The internet is a mess, a mess of things that talk to each other. Each of the things has their own IP address (ip stands for internet protocol), for example open https://1.1.1.1 you see this is a simple ip address of a popular DNS server (dns is a system we use to resolve names into ip addresses, e.g. facebook.com is 31.13.64.35). You can check the ip address by searching 'whats my ip' on google, and because your browser has to connect to google's server and they connect through their IP addresses, so google knows your IP. Of course it is a bit more complicated than that, but for now this will do.
  2484. The other most important thing is domain names, like facebook.com and yahoo.com or amazon.de. We need names otherwise everyone will have to remember 31.13.64.35 to open facebook.. which is not easy. To find out the ip of facebook.com you need to ask a .com server about which server is responsible for facebook.com, and then ask this server about what is the ip address of www.facebook.com. The whole system is like a tree.
  2485. ```
  2486. ROOT
  2487. "."
  2488. / | \
  2489. / | \
  2490. .de .com .io
  2491. / |
  2492. amazon /|\
  2493. / | \
  2494. / | \
  2495. / | \
  2496. / | \
  2497. amazon netflix yahoo
  2498. ```
  2499. your internet provider gives you your ip address and also a convenient name server to use, you can also use other name servers like 1.1.1.1 or 8.8.8.8, keep in mind, whoever nameserver you use, knows which websites you visit, because you have to ask them about the ip address of each website you visit.
  2500. A lot of scammers also ask you to change your dns server, they lie about getting faster internet and etc, but you see, if you ask a scammer's dns server 'what is the ip address of facebook.com', and they say 'well its 12.12.12.12' or whatever their server's address is, they can show you a webpage that looks like facebook, but its theirs, and when you login they can get your password. Remember when you login your browser sends the password to the other server that has to check it, so they can steal it that way.
  2501. To prevent this kind of attacks modern browsers use something called HTTPS, or secure http, you see a small closed lock on the address bar, and when you click it it will say 'Connection is secure', that means that it verified that the website you opened is actually the website you think it is. There are ways to attack this as well, but it is not trivial, and someone has to have physical access to your computer to install a new Trusted Certificate Authority (which we will explain way later).
  2502. But one more reason to be sus of people using your computer. Not only they can steal your cookies, but they can also install a new Trusted CA, change the DNS and then intercept all your requests.
  2503. ## [DAY-54] Touch Typing
  2504. Touch typing day is finally here! Enjoy keybr.com!
  2505. ## [DAY-55] Lists; Functions
  2506. Tic Tac Toe
  2507. ```
  2508. def empty_game():
  2509. game = [
  2510. [' ','a','b','c','d'],
  2511. ['1','-','-','-','-'],
  2512. ['2','-','-','-','-'],
  2513. ['3','-','-','-','-'],
  2514. ['4','-','-','-','-']
  2515. ]
  2516. return game
  2517. def show_game(game):
  2518. for row in game:
  2519. #[' ','a','b','c','d']
  2520. #...
  2521. for col in row:
  2522. #' '
  2523. #'a'
  2524. #'b'
  2525. print (col, end=' ')
  2526. print('')
  2527. g = empty_game()
  2528. x_or_zero='x'
  2529. while True:
  2530. show_game(g)
  2531. p = input('place ' + x_or_zero + ': ')
  2532. if p == 'a1':
  2533. g[1][1]=x_or_zero
  2534. if p == 'a2':
  2535. g[2][1]=x_or_zero
  2536. if p == 'a3':
  2537. g[3][1]=x_or_zero
  2538. if p == 'a4':
  2539. g[4][1]=x_or_zero
  2540. if p == 'b1':
  2541. g[1][2]=x_or_zero
  2542. if p == 'b2':
  2543. g[2][2]=x_or_zero
  2544. if p == 'b3':
  2545. g[3][2]=x_or_zero
  2546. if p == 'b4':
  2547. g[4][2]=x_or_zero
  2548. if p == 'c1':
  2549. g[1][3]=x_or_zero
  2550. if p == 'c2':
  2551. g[2][3]=x_or_zero
  2552. if p == 'c3':
  2553. g[3][3]=x_or_zero
  2554. if p == 'c4':
  2555. g[4][3]=x_or_zero
  2556. if p == 'd1':
  2557. g[1][4]=x_or_zero
  2558. if p == 'd2':
  2559. g[2][4]=x_or_zero
  2560. if p == 'd3':
  2561. g[3][4]=x_or_zero
  2562. if p == 'd4':
  2563. g[4][4]=x_or_zero
  2564. if p == 'clear':
  2565. g = empty_game()
  2566. if x_or_zero =='x':
  2567. x_or_zero = '0'
  2568. else:
  2569. x_or_zero='x'
  2570. ```
  2571. Spend the rest of the day playing.
  2572. ## [DAY-56] Functions; If; Random
  2573. Trivia game
  2574. ```
  2575. def check(question, answer):
  2576. x = input(question + ": ")
  2577. if x == answer:
  2578. return True
  2579. else:
  2580. return False
  2581. score = 0
  2582. if check("which animal lives on the north pole?", "polar bear"):
  2583. score += 1
  2584. if check("which animal lives in the jungle?", "tiger"):
  2585. score += 1
  2586. print("your score is: " + str(score))
  2587. ```
  2588. Math test:
  2589. ```
  2590. import random
  2591. while True:
  2592. a = random.randint(1,10)
  2593. b = random.randint(1,10)
  2594. r = int(input("what is " + str(a) + " * " + str(b) + "? " ))
  2595. if r == a * b:
  2596. print("Correct!")
  2597. else:
  2598. print("Incorrect, the answer was: " + str(a * b))
  2599. ```
  2600. Random characters
  2601. ```
  2602. import random
  2603. while True:
  2604. x = random.randint(ord('a'), ord('z'))
  2605. print(chr(x))
  2606. ```
  2607. ## [DAY-57] Lists; Functions; Grid
  2608. Snake
  2609. ```
  2610. import random
  2611. APPLE_SYMBOL = '@'
  2612. def render(world):
  2613. for row in world:
  2614. for col in row:
  2615. print(col,end=' ')
  2616. print('')
  2617. def empty():
  2618. return [
  2619. ['-','-','-','-'],
  2620. ['-','-','-','-'],
  2621. ['-','-','-','-'],
  2622. ['-','-','-','-'],
  2623. ['-','-','-','-'],
  2624. ['-','-','-','-'],
  2625. ['-','-','-','-'],
  2626. ]
  2627. def snake_eats_itself(positions, current_col, current_row):
  2628. for (col,row) in positions:
  2629. if col == current_col and row == current_row:
  2630. return True
  2631. def place_apple(world):
  2632. # just place it on a random square from all possible squares
  2633. possible = []
  2634. for index_row in range(len(world)):
  2635. for index_col in range(len(world[index_row])):
  2636. if world[index_row][index_col] == '-':
  2637. possible.append((index_col,index_row))
  2638. if len(possible) == 0:
  2639. # we cant place an apple
  2640. return False
  2641. else:
  2642. (col,row) = random.choice(possible)
  2643. world[row][col] = APPLE_SYMBOL
  2644. return True
  2645. world = empty()
  2646. player_row = 0
  2647. player_col = 0
  2648. player_history = []
  2649. world[player_row][player_col] = '%'
  2650. player_history.append((player_col,player_row))
  2651. place_apple(world)
  2652. render(world)
  2653. while True:
  2654. direction = input("which direction: ")
  2655. world[player_row][player_col] = '='
  2656. if direction == "u":
  2657. player_row = player_row - 1
  2658. elif direction == "d":
  2659. player_row = player_row + 1
  2660. elif direction == "l":
  2661. player_col = player_col - 1
  2662. elif direction == "r":
  2663. player_col = player_col + 1
  2664. else:
  2665. print("try again, u for up/d for down/l for left/r for right")
  2666. continue
  2667. if snake_eats_itself(player_history, player_col, player_row):
  2668. print("GAME OVER")
  2669. break
  2670. if world[player_row][player_col] == APPLE_SYMBOL:
  2671. world[player_row][player_col] = '$'
  2672. if not place_apple(world):
  2673. print("YOU WON!")
  2674. break
  2675. else:
  2676. world[player_row][player_col] = '%'
  2677. player_history.append((player_col,player_row))
  2678. render(world)
  2679. ```
  2680. ## [DAY-58] Continue Previous Day
  2681. Keep working on the snake game if you are not done. if you are do touch typing
  2682. ## [DAY-59] Tuples; Lists
  2683. Tuples are kind of like lists that you cant grow or shrink, but also you usually assign meaning to each of the positions, for example
  2684. ```
  2685. position = (1,2)
  2686. (x,y) = position
  2687. print(x)
  2688. print(y)
  2689. ```
  2690. it can have more elements
  2691. ```
  2692. posittion = (1,2,3)
  2693. (width,depth,height) = position
  2694. print(width)
  2695. print(depth)
  2696. print(height)
  2697. ```
  2698. You see how we used it in the snake game, to make a list of tuples, where we had the player history.
  2699. ```
  2700. positions = [(1,2),(3,4),(5,6)]
  2701. print(positions)
  2702. for p in positions:
  2703. print(p)
  2704. (x,y) = p
  2705. print(x)
  2706. print(y)
  2707. ```
  2708. It is quite handy when you know you have pairs of data, like X and Y position or Season number and Episode number.
  2709. ```
  2710. favorite_miraculous = [(3,1),(3,2),(2,1)]
  2711. for m in favorite_miraculous:
  2712. (season,episode) = m
  2713. print(str(season) + " season episode: " + str(episode))
  2714. ```
  2715. Or more than 2 pieces, you can hold however many you want, but it usually is you that assign meaning to each position, like in the above case, the first element we decide is season, and the second one we decide is episode
  2716. ## [DAY-60] Go Back In Time
  2717. Back to the beginning.
  2718. * Write a program to make a spy name
  2719. * Write a program to ask for favorite food
  2720. * Write a program to ask what is your name forever
  2721. ## [DAY-61] PyGame; PyGameZero; Coordinates
  2722. open `cmd` and run:
  2723. ```
  2724. pip install pygame
  2725. pip install pgzero
  2726. ```
  2727. then make a circle
  2728. ```
  2729. import pgzrun
  2730. WIDTH = 400
  2731. HEIGHT = 400
  2732. def draw():
  2733. screen.clear()
  2734. x = WIDTH/2
  2735. y = WIDTH/2
  2736. pos = (x,y)
  2737. radius = 30
  2738. screen.draw.circle(pos, radius, 'white')
  2739. pgzrun.go()
  2740. ```
  2741. Now lets move it:
  2742. ```
  2743. import pgzrun
  2744. import random
  2745. WIDTH = 400
  2746. HEIGHT = 400
  2747. x = WIDTH/2
  2748. y = WIDTH/2
  2749. def on_mouse_down(pos):
  2750. global x,y
  2751. (mouse_x, mouse_y) = pos
  2752. x = mouse_x
  2753. y = mouse_y
  2754. def draw():
  2755. screen.clear()
  2756. pos = (x,y)
  2757. radius = 30
  2758. screen.draw.circle(pos, radius, 'white')
  2759. pgzrun.go()
  2760. ```
  2761. Move it with keyboard
  2762. ```
  2763. import pgzrun
  2764. import random
  2765. WIDTH = 400
  2766. HEIGHT = 400
  2767. STEP = 10
  2768. x = WIDTH/2
  2769. y = WIDTH/2
  2770. def on_key_down(key):
  2771. global x,y
  2772. if key == keys.LEFT:
  2773. x -= STEP
  2774. elif key == keys.RIGHT:
  2775. x += STEP
  2776. elif key == keys.UP:
  2777. # coordinates start 0,0 on the upper left corner
  2778. y -= STEP
  2779. elif key == keys.DOWN:
  2780. y += STEP
  2781. def draw():
  2782. screen.clear()
  2783. pos = (x,y)
  2784. radius = 30
  2785. screen.draw.circle(pos, radius, 'white')
  2786. pgzrun.go()
  2787. ```
  2788. Lets say we have 400 width and 300 height window
  2789. ```
  2790. (0,0)
  2791. +---------------------------+
  2792. | |
  2793. | |
  2794. | |
  2795. | |
  2796. | |
  2797. | |
  2798. +---------------------------+
  2799. (400, 300)
  2800. ```
  2801. top left corner is y = 0 and x = 0, bottom right is `x = 400` and `y = 300`. So when we move 'UP' with the keyboard we actually have to decrease `y` instead of increasing it like in `turtle`, where 0,0 is in the center of the screen, so top left is `(-half_x, -half_y)` and bottom right is `(half_x, half_y)`
  2802. ## [DAY-62] Collisions; Callbacks
  2803. Smooth movement.
  2804. ```
  2805. import pgzrun
  2806. import random
  2807. WIDTH = 400
  2808. HEIGHT = 400
  2809. STEP = 10
  2810. x = WIDTH/2
  2811. y = WIDTH/2
  2812. def update():
  2813. global x,y
  2814. if keyboard.LEFT:
  2815. x -= STEP
  2816. elif keyboard.RIGHT:
  2817. x += STEP
  2818. elif keyboard.UP:
  2819. y -= STEP
  2820. elif keyboard.DOWN:
  2821. y += STEP
  2822. def draw():
  2823. screen.clear()
  2824. pos = (x,y)
  2825. radius = 30
  2826. screen.draw.circle(pos, radius, 'white')
  2827. pgzrun.go()
  2828. ```
  2829. `pgzero` will call your `update` function 60 times per second, and now it will just check at the time of the call, is `keyboard.UP`, and if it is it will just move. Which is completely different, where each time you press the `up` key the `on_key_down` function is called. So previously you had ot press the key every time to move, now you can just hold it.
  2830. Where do those `keyboard` and `screen` magic variables come from? In python there is such thing as `__builtin__` which literally adds new keywords, kind of like `input` or `print`, when you `import pgzrun` it will import also those builtins. `Actor`, `Rect`, `keyboard` etc.. you can check them at https://pygame-zero.readthedocs.io/en/stable/builtins.html
  2831. COLLIDE!
  2832. ![game-62.png](./screenshots/game-62.png "game 62 screenshot")
  2833. ```
  2834. import pgzrun
  2835. import random
  2836. WIDTH = 400
  2837. HEIGHT = 400
  2838. STEP = 10
  2839. x = WIDTH/2
  2840. y = WIDTH/2
  2841. box = Rect((20,20),(100,100))
  2842. game_over = False
  2843. def update():
  2844. global x, y, game_over
  2845. if keyboard.LEFT:
  2846. x -= STEP
  2847. elif keyboard.RIGHT:
  2848. x += STEP
  2849. elif keyboard.UP:
  2850. y -= STEP
  2851. elif keyboard.DOWN:
  2852. y += STEP
  2853. if box.collidepoint((x,y)):
  2854. game_over = True
  2855. def draw():
  2856. screen.clear()
  2857. pos = (x,y)
  2858. radius = 30
  2859. screen.draw.rect(box, color="red")
  2860. screen.draw.circle(pos, radius, 'white')
  2861. if game_over:
  2862. screen.draw.text("GAME OVER", (50, 30), color="blue")
  2863. pgzrun.go()
  2864. ```
  2865. ## [DAY-63] Functions
  2866. Catch the snake
  2867. ![game-63.png](./screenshots/game-63.png "game 63 screenshot")
  2868. Make images/ folder and download the images from https://github.com/jackdoe/programming-for-kids. When you say `Actor("c1")` it will look for `c1.png` in images/ folder in the current directory.
  2869. ```
  2870. import pgzrun
  2871. import random
  2872. HEIGHT = 200
  2873. WIDTH = 200
  2874. score = 0
  2875. speed = 1
  2876. elf = Actor("c1")
  2877. snake = Actor("snake")
  2878. elf.x = WIDTH/2
  2879. elf.y = HEIGHT/2
  2880. def place_snake():
  2881. snake.x = random.randint(10,WIDTH-10)
  2882. snake.y = random.randint(10,HEIGHT-10)
  2883. place_snake()
  2884. def update():
  2885. global game_over, speed, score
  2886. if keyboard.left:
  2887. elf.x = elf.x-speed
  2888. if keyboard.right:
  2889. elf.x = elf.x+speed
  2890. if keyboard.up:
  2891. elf.y = elf.y-speed
  2892. if keyboard.down:
  2893. elf.y= elf.y+speed
  2894. if keyboard.R:
  2895. speed = 1
  2896. score = 0
  2897. if elf.colliderect(snake):
  2898. score += 1
  2899. speed += 1
  2900. place_snake()
  2901. def draw():
  2902. screen.fill('black')
  2903. elf.draw()
  2904. snake.draw()
  2905. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  2906. pgzrun.go()
  2907. ```
  2908. ## [DAY-64] Lists; Functions
  2909. Many Snakes
  2910. ![game-64.png](./screenshots/game-64.png "game 64 screenshot")
  2911. ```
  2912. import pgzrun
  2913. import random
  2914. HEIGHT = 200
  2915. WIDTH = 200
  2916. score = 1
  2917. speed = 1
  2918. elf = Actor("c1")
  2919. snakes = []
  2920. elf.x = WIDTH/2
  2921. elf.y = HEIGHT/2
  2922. def place_snakes():
  2923. global snakes
  2924. snakes = []
  2925. for i in range(score):
  2926. snake = Actor("snake")
  2927. snake.x = random.randint(10,WIDTH-10)
  2928. snake.y = random.randint(10,HEIGHT-10)
  2929. snakes.append(snake)
  2930. place_snakes()
  2931. def update():
  2932. global game_over, speed, score, snakes
  2933. if keyboard.left:
  2934. elf.x = elf.x-speed
  2935. if keyboard.right:
  2936. elf.x = elf.x+speed
  2937. if keyboard.up:
  2938. elf.y = elf.y-speed
  2939. if keyboard.down:
  2940. elf.y= elf.y+speed
  2941. if keyboard.R:
  2942. speed = 1
  2943. score = 0
  2944. snakes = []
  2945. place_snakes()
  2946. for s in snakes:
  2947. if elf.colliderect(s):
  2948. score += 1
  2949. speed += 1
  2950. place_snakes()
  2951. def draw():
  2952. screen.fill('black')
  2953. elf.draw()
  2954. for s in snakes:
  2955. s.draw()
  2956. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  2957. pgzrun.go()
  2958. ```
  2959. ## [DAY-65] Functions; Collisions
  2960. ```
  2961. import pgzrun
  2962. import random
  2963. HEIGHT = 200
  2964. WIDTH = 200
  2965. score = 0
  2966. speed = 1
  2967. game_over = False
  2968. elf = Actor("c1")
  2969. snake = Actor("snake")
  2970. elf.x = WIDTH/2
  2971. elf.y = HEIGHT/2
  2972. def place_snake():
  2973. snake.x = random.randint(10,WIDTH-10)
  2974. snake.y = random.randint(10,HEIGHT-10)
  2975. place_snake()
  2976. def update():
  2977. global game_over, speed, score
  2978. if keyboard.left:
  2979. elf.x = elf.x-speed
  2980. if keyboard.right:
  2981. elf.x = elf.x+speed
  2982. if keyboard.up:
  2983. elf.y = elf.y-speed
  2984. if keyboard.down:
  2985. elf.y= elf.y+speed
  2986. if keyboard.R:
  2987. speed = 1
  2988. score = 0
  2989. if elf.colliderect(snake):
  2990. score += 1
  2991. speed += 1
  2992. place_snake()
  2993. def draw():
  2994. screen.fill('black')
  2995. elf.draw()
  2996. snake.draw()
  2997. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  2998. pgzrun.go()
  2999. ```
  3000. ## [DAY-66] Schedule; Callbacks; Functions
  3001. Catch as many snakes as you can in 5 seconds.
  3002. ```
  3003. import pgzrun
  3004. import random
  3005. HEIGHT = 200
  3006. WIDTH = 200
  3007. game_over = False
  3008. score = 0
  3009. speed = 1
  3010. elf = Actor("c1")
  3011. snake = Actor("snake")
  3012. elf.x = WIDTH/2
  3013. elf.y = HEIGHT/2
  3014. def place_snake():
  3015. snake.x = random.randint(10,WIDTH-10)
  3016. snake.y = random.randint(10,HEIGHT-10)
  3017. place_snake()
  3018. def time_is_up():
  3019. global game_over
  3020. game_over = True
  3021. def update():
  3022. global game_over, speed, score
  3023. if keyboard.left:
  3024. elf.x = elf.x-speed
  3025. if keyboard.right:
  3026. elf.x = elf.x+speed
  3027. if keyboard.up:
  3028. elf.y = elf.y-speed
  3029. if keyboard.down:
  3030. elf.y= elf.y+speed
  3031. if keyboard.R:
  3032. speed = 1
  3033. score = 0
  3034. if elf.colliderect(snake):
  3035. score += 1
  3036. speed += 1
  3037. place_snake()
  3038. def draw():
  3039. screen.fill('black')
  3040. elf.draw()
  3041. snake.draw()
  3042. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3043. if game_over:
  3044. screen.fill('blue')
  3045. screen.draw.text("GAME OVER, Score: "+ str(score), color="white", topleft=(10,10))
  3046. clock.schedule(time_is_up, 5)
  3047. pgzrun.go()
  3048. ```
  3049. You see we just overwrite the screen with 'blue' and write another text, but you can still move in the back and the score will update if you catch a sneak.
  3050. If you want to stop the hero to move outside of the window, simply restrict elf.x and elf.y to be smaller than 0 or bigger than WIDTH and HEIGHT
  3051. Example:
  3052. ```
  3053. def update():
  3054. ...
  3055. if keyboard.left:
  3056. elf.x = elf.x-speed
  3057. if elf.x > WIDTH:
  3058. elf.x = WIDTH
  3059. ```
  3060. ## [DAY-67] Lists; Functions
  3061. Cross the road. Work with your parent to find images for the game, you need few cars, fox and a door. If not just use the existing assets from your images/ folder
  3062. ```
  3063. import pgzrun
  3064. import random
  3065. HEIGHT = 1000
  3066. WIDTH = 1200
  3067. score = 0
  3068. step = 5
  3069. coin_speed = 1
  3070. fox = Actor("fox")
  3071. gate = Actor("door")
  3072. gate.y = HEIGHT - 50
  3073. gate.x = WIDTH/2 - 20
  3074. cars=[
  3075. [Actor("car-2"),Actor("car-5"),Actor("car-3")],
  3076. [Actor("car-1"),Actor("car-5")],
  3077. [Actor("car-3"),Actor("car-4"),Actor("car-2")],
  3078. ]
  3079. for a in cars:
  3080. for (coin_index,f) in enumerate(a):
  3081. f.x += coin_index * int(WIDTH/len(a)) + 30
  3082. def move_coins():
  3083. for (index,a) in enumerate(cars):
  3084. for (coin_index, f) in enumerate(a):
  3085. f.y = (index * int(HEIGHT/len(cars))) + int(HEIGHT/len(cars))/2
  3086. f.x += coin_speed
  3087. if f.x > WIDTH:
  3088. f.x = 0
  3089. game_over = False
  3090. move_coins()
  3091. def update():
  3092. global score
  3093. global step
  3094. global game_over
  3095. global coin_speed
  3096. if keyboard.left:
  3097. fox.x = fox.x-step
  3098. if fox.x <0:
  3099. fox.x=0
  3100. if keyboard.right:
  3101. fox.x = fox.x+step
  3102. if fox.x >WIDTH:
  3103. fox.x=WIDTH
  3104. if keyboard.up:
  3105. fox.y =fox.y-step
  3106. if fox.y <0:
  3107. fox.y=0
  3108. if keyboard.down:
  3109. fox.y= fox.y+step
  3110. if fox.y >HEIGHT:
  3111. fox.y=HEIGHT
  3112. if keyboard.R:
  3113. game_over = False
  3114. score = 0
  3115. fox.x = 0
  3116. fox.y = 0
  3117. coin_speed = 1
  3118. for i in cars:
  3119. for s in i:
  3120. if fox.colliderect(s):
  3121. game_over = 1 == 1
  3122. if fox.colliderect(gate):
  3123. fox.x = 0
  3124. fox.y = 0
  3125. score += 1
  3126. coin_speed += 2
  3127. move_coins()
  3128. def draw():
  3129. screen.fill('black')
  3130. fox.draw()
  3131. gate.draw()
  3132. for i in cars:
  3133. for k in i:
  3134. k.draw()
  3135. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3136. if game_over:
  3137. screen.fill("blue")
  3138. screen.draw.text("Final Score: "+ str(score), color="white", topleft=(10,10),fontsize=60)
  3139. pgzrun.go()
  3140. ```
  3141. ## [DAY-68] Lists; Functions
  3142. Shoot bullets and remove them from the list, play sound, and also level up after killing 3 snakes!
  3143. ![game-68.png](./screenshots/game-68.png "game 68 screenshot")
  3144. ```
  3145. import pgzrun
  3146. import random
  3147. HEIGHT = 200
  3148. WIDTH = 200
  3149. score = 0
  3150. speed = 1
  3151. elf = Actor("c1")
  3152. snake = Actor("snake")
  3153. beep = tone.create('A3', 0.5)
  3154. elf.x = WIDTH/2
  3155. elf.y = HEIGHT/2
  3156. bullets = []
  3157. def place_snake():
  3158. snake.x = random.randint(10,WIDTH-10)
  3159. snake.y = random.randint(10,HEIGHT-10)
  3160. place_snake()
  3161. def bullet_out_of_screen():
  3162. # just delete the first bullet
  3163. bullets.pop(0)
  3164. def on_key_down(key):
  3165. if key == keys.SPACE:
  3166. b = Actor("bullet2")
  3167. b.x = elf.x + 5
  3168. b.y = elf.y
  3169. animate(b, pos=(WIDTH + 100, elf.y), tween='accelerate', on_finished=bullet_out_of_screen)
  3170. bullets.append(b)
  3171. def update():
  3172. global game_over, speed, score, bullets
  3173. if keyboard.left:
  3174. elf.x = elf.x-speed
  3175. if keyboard.right:
  3176. elf.x = elf.x+speed
  3177. if keyboard.up:
  3178. elf.y = elf.y-speed
  3179. if keyboard.down:
  3180. elf.y= elf.y+speed
  3181. if keyboard.R:
  3182. speed = 1
  3183. score = 0
  3184. elf.image = "c1"
  3185. bullets = []
  3186. for b in bullets:
  3187. if b.colliderect(snake):
  3188. score += 1
  3189. speed += 1
  3190. if score == 3:
  3191. elf.image = "c2"
  3192. beep.play()
  3193. place_snake()
  3194. def draw():
  3195. screen.fill('black')
  3196. elf.draw()
  3197. snake.draw()
  3198. for b in bullets:
  3199. b.draw()
  3200. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3201. pgzrun.go()
  3202. ```
  3203. You see how we are adding, bullets to a list every time you press 'space'. Now the problem is we need to clean up that list at some point, otherwise it will grow a lot, and every time we do `for b in bullets` it will bet slower and slower. Computers can only do so many things per second.
  3204. So when the animation finishes, it will call `bullets_out_of_screen`, and from there we just say `bullets.pop(0)` which will remove the first element in the list of bullets, which is the oldest bullet. So if you press space 5 times, the list will have 5 items, and each of them will finish and will remove the first element.
  3205. Lets say you pressed space 3 times, and shot 3 bullets, so the list, and how the bullets are traveling kindof looks like this:
  3206. ```
  3207. 0 -> bbbbbbbbbbbbbb
  3208. 1 -> bbbbbbb
  3209. 2 -> bbbb
  3210. ```
  3211. So you see when 0 finishes because it is the oldest, when it does bullets.pop(0), it will actually delete itself.
  3212. pretty cool!
  3213. ## [DAY-69] Sockets; Functions; Callbacks
  3214. ![game-69.png](./screenshots/game-69.png "game 69 screenshot")
  3215. Multiplayer!
  3216. ```
  3217. import pgzrun
  3218. import socket
  3219. import threading
  3220. import sys
  3221. HEIGHT = 200
  3222. WIDTH = 200
  3223. MULTIPLAYER_PORT = 5025
  3224. OTHER_COMPUTER_IP = "192.168.0.10"
  3225. speed = 4
  3226. me = Actor("c1")
  3227. other = Actor("c2")
  3228. me.x = WIDTH/2
  3229. me.y = HEIGHT/2
  3230. socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  3231. socket.bind(("0.0.0.0", MULTIPLAYER_PORT))
  3232. data = None
  3233. def multiplayer():
  3234. global data
  3235. while True:
  3236. data, addr = socket.recvfrom(1024)
  3237. def update():
  3238. if data != None:
  3239. message = data.decode("utf8")
  3240. (x,y) = message.split(":")
  3241. other.x = float(x)
  3242. other.y = float(y)
  3243. def on_key_down(key):
  3244. if key == keys.LEFT:
  3245. me.x = me.x-speed
  3246. if key == keys.RIGHT:
  3247. me.x = me.x+speed
  3248. if key == keys.UP:
  3249. me.y = me.y-speed
  3250. if key == keys.DOWN:
  3251. me.y= me.y+speed
  3252. if key == keys.Q:
  3253. sys.exit(0)
  3254. message = bytearray(str(me.x) + ':' + str(me.y),"utf8")
  3255. socket.sendto(message, (OTHER_COMPUTER_IP, MULTIPLAYER_PORT))
  3256. def draw():
  3257. screen.fill('black')
  3258. me.draw()
  3259. other.draw()
  3260. threading.Thread(target=multiplayer).start()
  3261. pgzrun.go()
  3262. ```
  3263. There are two important parts here, first is the `socket` and then the `Thread`. For now we will leave them a mystery. But basically every time you press the UP/DOWN/LEFT/RIGHT key your computer sends a message "currentX:currentY" to the other computer, and when the other computer receives it, it stores it in the global `data` variable, then in the `update` function it splits the message by `:` and extract the `x` and `y` and sets it to the `other` actor.
  3264. The `multiplayer()` function runs in a separate thread, or you can think of a separate process, so we are doing two things in the same time, the game loop (which is one `while True`) and the multiplayer loop which is also `while True`.
  3265. ## [DAY-70] Lists; Functions
  3266. print numbers in a list
  3267. ```
  3268. data = [1,2,3,4,5]
  3269. for item in data:
  3270. print(e)
  3271. ```
  3272. ```
  3273. list_of_lists = [[1,2,3,4,5], [1,2,3], [4,5,6]]
  3274. for l in list_of_lists:
  3275. for item in l:
  3276. print(item)
  3277. ```
  3278. ```
  3279. list_of_list_of_lists = [[[1,2,3,4,5], [1,2,3], [4,5,6]], [[1,2,3,4,5], [1,2,3], [4,5,6]]]
  3280. for list_of_lists in list_of_list_of_lists:
  3281. for l in list_of_lists:
  3282. for item in l:
  3283. print(item)
  3284. ```
  3285. ```
  3286. list_of_list_of_list_of_lists = [
  3287. [
  3288. [
  3289. [1,2,3,4,5],
  3290. [1,2,3],
  3291. [4,5,6]
  3292. ],
  3293. [
  3294. [1,2,3,4,5],
  3295. [1,2,3],
  3296. [4,5,6]
  3297. ]
  3298. ],
  3299. [
  3300. [
  3301. [1,2,3,4,5],
  3302. [1,2,3],
  3303. [4,5,6]
  3304. ],
  3305. [
  3306. [1,2,3,4,5],
  3307. [1,2,3],
  3308. [4,5,6]
  3309. ]
  3310. ],
  3311. ]
  3312. for list_of_list_of_lists in list_of_list_of_list_of_lists:
  3313. for list_of_lists in list_of_list_of_lists:
  3314. for l in list_of_lists:
  3315. for item in l:
  3316. print(item)
  3317. ```
  3318. ```
  3319. def sum(x):
  3320. r = 0
  3321. for item in x:
  3322. r += item
  3323. return r
  3324. data = [1,2,3,4,5]
  3325. print(sum(data))
  3326. ```
  3327. ```
  3328. def sum(x):
  3329. r = 0
  3330. for l in x:
  3331. for item in l:
  3332. r += item
  3333. return r
  3334. data = [[1,2,3,4,5], [1,2,3,4,5]]
  3335. print(sum(data))
  3336. ```
  3337. ## [DAY-71] Strings; Integers; While; Functions
  3338. make a calculator
  3339. ```
  3340. while True:
  3341. n1 = int(input("number 1: "))
  3342. n2 = int(input("number 2: "))
  3343. op = input("operation +/-* : ")
  3344. r = 0
  3345. if op == "quit":
  3346. break
  3347. elif op == "+":
  3348. r = n1 + n2
  3349. elif op == "-":
  3350. r = n1 - n2
  3351. elif op == "*":
  3352. r = n1 * n2
  3353. else:
  3354. print("i dont know " + op)
  3355. continue
  3356. print(n1, op, n2, '=',r)
  3357. ```
  3358. sum numbers from input
  3359. ```
  3360. def sum(x):
  3361. r = 0
  3362. for item in x:
  3363. r += item
  3364. return r
  3365. x = []
  3366. while True:
  3367. k = input("enter number: ")
  3368. x.append(int(k))
  3369. print(x)
  3370. print(sum(x))
  3371. ```
  3372. ## [DAY-72] Reading Code
  3373. Reading code is even more important than writing it, and it is more difficult than reading a book, because the story does not develop top to bottom. You have to see the important pieces, and how they are linked together. Where are things assigned and changed and how are those pieces related. For example in the touch typing program, you have a couple of functions, you can study them on their own, and know what they do, and then see how they are used and make sense of the whole program, without even running it.
  3374. We will go over a couple of programs we wrote before, the rock paper scissors game, the bullet shooting game, and one of the touch typing programs.
  3375. ![day-72-0.jpg](./reading/day-72-0.jpg "day 72 example 0")
  3376. ![day-72-1.jpg](./reading/day-72-1.jpg "day 72 example 1")
  3377. ![day-72-2.jpg](./reading/day-72-2.jpg "day 72 example 2")
  3378. Those are just examples, you have to print the programs and go over them with your parent.
  3379. ## [DAY-73] Reading Code
  3380. More reading today, those are a couple of examples from the earlier days, the love tester, the fight function from the text game, the hangman game and first touch typing program.
  3381. ![day-73-0.jpg](./reading/day-73-0.jpg "day 73 example 0")
  3382. ![day-73-1.jpg](./reading/day-73-1.jpg "day 73 example 1")
  3383. ![day-73-2.jpg](./reading/day-73-2.jpg "day 73 example 2")
  3384. ![day-73-3.jpg](./reading/day-73-3-0.jpg "day 73 example 3")
  3385. Again you can use something else as well, those are just the ones I picked. Be messy with the pencil, connect things together!
  3386. ## [DAY-74] Strings; While; Lists
  3387. Today its up to you what to write, my kid came up with those programs:
  3388. 1. Ask forever what your favorite sport is, if yours is not here use https://emojipedia.org/ to find good emojis.
  3389. ```
  3390. while True:
  3391. k = input('what is your favorite sport: ')
  3392. if k == 'soccer':
  3393. print('⚽')
  3394. elif k == 'hockey':
  3395. print('🏑')
  3396. elif k == 'tennis':
  3397. print('🎾')
  3398. elif k == 'volleyball':
  3399. print('🏐')
  3400. elif k == 'table tennis':
  3401. print('🏓')
  3402. elif k == 'baseball':
  3403. print('⚾')
  3404. elif k == 'basketball':
  3405. print('🏀')
  3406. elif k == 'golf':
  3407. print('🏌️‍♂️')
  3408. else:
  3409. print('i dont now ' +k)
  3410. ```
  3411. 2. and one simple, append and pop from a list.
  3412. ```
  3413. k = []
  3414. while True:
  3415. s = input('What are you thinking of: ')
  3416. if s == 'pop':
  3417. k.pop(0)
  3418. else:
  3419. k.append(s)
  3420. print(k)
  3421. ```
  3422. ## [DAY-75] Functions; Callbacks; Lists; Encoding
  3423. ![game-75.png](./screenshots/game-75.png "game 75 screenshot")
  3424. Enemies come to get you, and you shoot half moons at them. pretty cool.
  3425. ```
  3426. import pgzrun
  3427. import random
  3428. HEIGHT = 200
  3429. WIDTH = 200
  3430. score = 0
  3431. speed = 1
  3432. elf = Actor("c1")
  3433. beep = tone.create('A3', 0.5)
  3434. elf.x = 10
  3435. elf.y = HEIGHT/2
  3436. game_over = False
  3437. bullets = []
  3438. enemies = []
  3439. def make_enemies():
  3440. level = int(score / 5) + 1
  3441. duration = (5 - level)
  3442. if duration < 1:
  3443. duration = 1
  3444. for i in range(level):
  3445. snake = Actor("snake")
  3446. snake.x = WIDTH-20
  3447. snake.y = random.randint(10,HEIGHT-10)
  3448. animate(snake, pos=(-100, snake.y), tween='accelerate', duration=duration)
  3449. enemies.append(snake)
  3450. def bullet_out_of_screen():
  3451. bullets.pop(0)
  3452. def on_key_down(key):
  3453. if key == keys.SPACE:
  3454. b = Actor("bullet2")
  3455. b.x = elf.x + 5
  3456. b.y = elf.y
  3457. animate(b, pos=(WIDTH + 100, elf.y), tween='accelerate', on_finished=bullet_out_of_screen)
  3458. bullets.append(b)
  3459. def update():
  3460. global game_over, speed, score, bullets, enemies
  3461. if keyboard.left:
  3462. elf.x = elf.x-speed
  3463. if keyboard.right:
  3464. elf.x = elf.x+speed
  3465. if keyboard.up:
  3466. elf.y = elf.y-speed
  3467. if keyboard.down:
  3468. elf.y= elf.y+speed
  3469. if keyboard.R:
  3470. speed = 1
  3471. score = 0
  3472. bullets = []
  3473. enemies = []
  3474. game_over = False
  3475. hit = []
  3476. for b in bullets:
  3477. for e in enemies:
  3478. if b.colliderect(e):
  3479. hit.append(e)
  3480. if len(hit) > 0:
  3481. score += len(hit)
  3482. if speed < 4:
  3483. speed += 1
  3484. beep.play()
  3485. for e in hit:
  3486. enemies.remove(e)
  3487. for e in enemies:
  3488. if e.colliderect(elf):
  3489. game_over = True
  3490. def draw():
  3491. if game_over:
  3492. screen.fill('black')
  3493. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3494. else:
  3495. screen.fill('black')
  3496. elf.draw()
  3497. for b in bullets:
  3498. b.draw()
  3499. for e in enemies:
  3500. e.draw()
  3501. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3502. make_enemies()
  3503. clock.schedule_interval(make_enemies, 2)
  3504. pgzrun.go()
  3505. ```
  3506. ![day-75-1.jpg](./reading/day-75-1.jpg "day 75 example 1")
  3507. tic tac toe but with one character variable names
  3508. ```
  3509. x = [
  3510. # 0 1 2 3
  3511. ['〰️','🅰️','🅱️','🅾️'], # 0
  3512. ['🥇','〰️','〰️','〰️'], # 1
  3513. ['🥈','〰️','〰️','〰️'], # 2
  3514. ['🥉','〰️','〰️','〰️'], # 3
  3515. ]
  3516. k = '🛹'
  3517. while True:
  3518. for i in x:
  3519. for s in i:
  3520. print(s,end=' ')
  3521. print('')
  3522. l = input(k + ": ")
  3523. if l == 'a1':
  3524. x[1][1]=k
  3525. elif l == 'a2':
  3526. x[2][1]=k
  3527. elif l == 'a3':
  3528. x[3][1]=k
  3529. elif l == 'b1':
  3530. x[1][2]=k
  3531. elif l == 'b2':
  3532. x[2][2]=k
  3533. elif l == 'b3':
  3534. x[3][2]=k
  3535. elif l == 'o1':
  3536. x[1][3]=k
  3537. elif l == 'o2':
  3538. x[2][3]=k
  3539. elif l == 'o3':
  3540. x[3][3]=k
  3541. else:
  3542. continue
  3543. if k == '🛹':
  3544. k = '⚽'
  3545. else:
  3546. k = '🛹'
  3547. ```
  3548. 30 and back
  3549. ```
  3550. for i in range(1,31):
  3551. print(i)
  3552. for i in range(1,31):
  3553. print(30 - i)
  3554. ```
  3555. football mania
  3556. ```
  3557. d = 30
  3558. while True:
  3559. for i in range(1,d):
  3560. print('⚽' * i)
  3561. for i in range(1,d):
  3562. h = (d - i)
  3563. print('⚽' * h)
  3564. ```
  3565. ## [DAY-76] Functions; Callbacks; Lists
  3566. ![game-76.png](./screenshots/game-76.png "game 76 screenshot")
  3567. A game of tag! The elf is robin hood, running away from the king. The elf plays with WASD and the king plays with up/down/left/right.
  3568. ```
  3569. import pgzrun
  3570. import random
  3571. HEIGHT = 200
  3572. WIDTH = 200
  3573. speedA = 3
  3574. speedB = 3
  3575. playerA = Actor("c1")
  3576. playerB = Actor("c2")
  3577. playerA.x = 10
  3578. playerA.y = HEIGHT - 40
  3579. playerB.x = 10
  3580. playerB.y = 40
  3581. game_over = False
  3582. def random_speed():
  3583. global speedA, speedB
  3584. speedA = random.randint(1,5)
  3585. speedB = random.randint(1,5)
  3586. def on_key_down(key):
  3587. global game_over
  3588. # player A
  3589. if key == keys.A:
  3590. playerA.x -= speedA
  3591. if key == keys.D:
  3592. playerA.x += speedA
  3593. if key == keys.W:
  3594. playerA.y -= speedA
  3595. if key == keys.S:
  3596. playerA.y += speedA
  3597. # player B
  3598. if key == keys.LEFT:
  3599. playerB.x -= speedB
  3600. if key == keys.RIGHT:
  3601. playerB.x += speedB
  3602. if key == keys.UP:
  3603. playerB.y -= speedB
  3604. if key == keys.DOWN:
  3605. playerB.y += speedB
  3606. def update():
  3607. global game_over
  3608. if playerA.colliderect(playerB):
  3609. game_over = True
  3610. def draw():
  3611. if game_over:
  3612. screen.fill('black')
  3613. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3614. else:
  3615. screen.fill('black')
  3616. screen.draw.text("RUN! elf: " + str(speedA) + " king: " + str(speedB) , color="white", topleft=(10,10))
  3617. playerA.draw()
  3618. playerB.draw()
  3619. clock.schedule_interval(random_speed, 2)
  3620. pgzrun.go()
  3621. ```
  3622. Basic math quiz
  3623. ```
  3624. import random
  3625. while True:
  3626. k = random.randint(1,13)
  3627. s = random.randint(1,13)
  3628. r = k * s
  3629. g = int(input('How much is '+str(k) +'*' +str(s) + ': '))
  3630. if g == r:
  3631. print('Wow nice job its CORRECT')
  3632. else:
  3633. print('wrong the answer was: ' + str(r))
  3634. ```
  3635. 7 days average
  3636. ```
  3637. x = [1231,5123,6737,6725,6261,2664,62561]
  3638. n = len(x)
  3639. print(x)
  3640. print(n)
  3641. sum = 0
  3642. for i in x:
  3643. sum += i
  3644. print('sum: ' + str(sum))
  3645. print('average: ' + str(sum/n))
  3646. ```
  3647. ## [DAY-77] Lists; Encode/Decode
  3648. morse code translator
  3649. ```
  3650. alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','.',',']
  3651. morse = ['.-','-...','-.-.','-..','.','..-.','--.','....','..','.---','-.-','.-..','--','-.','---','.--.','--.-','.-.','...','-','..-','...-','.--','-..-','-.--','--..','/','.-.-.-','--..--']
  3652. print(len(morse))
  3653. print(len(alphabet))
  3654. for i in range(len(alphabet)):
  3655. print(alphabet[i] + " -> " + morse[i])
  3656. text = '.... . .-.. .-.. --- / .-- --- .-. .-.. -.. .-.-.- / - .... .. ... / .. ... / -- --- .-. ... . / -.-. --- -.. . .-.-.- / - .... . .-. . / .- .-. . / -- .- -. -.-- / -.-. --- -.. . ... --..-- / -... ..- - / - .... .. ... / --- -. . / .. ... / .--. .-. . - - -.-- / -.-. --- --- .-.. --..-- / --. --- --- -.. / .--- --- -... / - .-. .- -. ... .-.. .- - .. -. --. / .. - .-.-.-'.split(' ')
  3657. for word in text:
  3658. found = False
  3659. for i in range(len(morse)):
  3660. x = morse[i]
  3661. if x == word:
  3662. print(alphabet[i], end = '')
  3663. found = True
  3664. if not found:
  3665. print(word , end='')
  3666. ```
  3667. ## [DAY-78] Coordinates; Functions; Callbacks
  3668. ![game-78.png](./screenshots/game-78.png "game 78 screenshot")
  3669. Small modifications to the previous game, gold in the middle moves the king away, randomize the elf position every 2 seconds
  3670. ```
  3671. import pgzrun
  3672. import random
  3673. HEIGHT = 200
  3674. WIDTH = 200
  3675. speedE = 3
  3676. speedK = 3
  3677. elf = Actor("c1")
  3678. king = Actor("c2")
  3679. gold = Actor("c3")
  3680. gold.x = WIDTH/2
  3681. gold.y = HEIGHT/2
  3682. elf.x = 10
  3683. elf.y = HEIGHT - 40
  3684. king.x = 10
  3685. king.y = 40
  3686. game_over = False
  3687. def random_speed():
  3688. global speedE, speedK
  3689. speedE = random.randint(3,5)
  3690. speedK = random.randint(2,5)
  3691. def random_place():
  3692. elf.x = random.randint(0,WIDTH)
  3693. elf.y = random.randint(0,HEIGHT)
  3694. def update():
  3695. global game_over
  3696. # elf
  3697. if keyboard.A:
  3698. elf.x -= speedE
  3699. if keyboard.D:
  3700. elf.x += speedE
  3701. if keyboard.W:
  3702. elf.y -= speedE
  3703. if keyboard.S:
  3704. elf.y += speedE
  3705. # king
  3706. if keyboard.left:
  3707. king.x -= speedK
  3708. if keyboard.right:
  3709. king.x += speedK
  3710. if keyboard.up:
  3711. king.y -= speedK
  3712. if keyboard.down:
  3713. king.y += speedK
  3714. if keyboard.SPACE:
  3715. elf.image = 'snake'
  3716. random_speed()
  3717. if keyboard.R:
  3718. game_over = 1==2
  3719. elf.x = 10
  3720. elf.y = HEIGHT - 40
  3721. king.x = 10
  3722. king.y = 40
  3723. if elf.x < 0:
  3724. elf.x = 0
  3725. if elf.x > WIDTH:
  3726. elf.x = WIDTH
  3727. if elf.y < 0:
  3728. elf.y = 0
  3729. if elf.y > HEIGHT:
  3730. elf.y = HEIGHT
  3731. if king.x < 0:
  3732. king.x = 0
  3733. if king.x > WIDTH:
  3734. king.x = WIDTH
  3735. if king.y < 0:
  3736. king.y = 0
  3737. if king.y > HEIGHT:
  3738. king.y = HEIGHT
  3739. if elf.colliderect(gold):
  3740. king.x = WIDTH
  3741. king.y = HEIGHT
  3742. if king.colliderect(gold):
  3743. game_over = True
  3744. if elf.colliderect(king):
  3745. game_over = True
  3746. def draw():
  3747. if game_over:
  3748. screen.fill('black')
  3749. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3750. else:
  3751. screen.fill('black')
  3752. screen.draw.text("RUN! elf: " + str(speedE) + " king: " + str(speedK) , color="white", topleft=(10,10))
  3753. elf.draw()
  3754. king.draw()
  3755. gold.draw()
  3756. clock.schedule_interval(random_speed, 2)
  3757. clock.schedule_interval(random_place, 5)
  3758. pgzrun.go()
  3759. ```
  3760. Explanation about setting x and y to be random:
  3761. ![day-78-explain.png](./reading/day-78-explain.png "day 78 explain coordinates")
  3762. Write a program to compute the average of a list of numbers:
  3763. ![day-78-a.jpg](./reading/day-78-a.jpg "day 78 average of list of numbers")
  3764. Decode morse code:
  3765. ![day-78-c.jpg](./reading/day-78-c.jpg "day 78 decode morse code")
  3766. ## [DAY-79] Lists; Encoding
  3767. morse code agian
  3768. ```
  3769. alphabet = ['a','b','c','d','e']
  3770. morse = ['.-','-...','-.-.','...','.']
  3771. for i in range(len(alphabet)):
  3772. print(alphabet[i])
  3773. print(morse[i])
  3774. text = ['.-..','.','.-..','.-']
  3775. for word in text:
  3776. for c in range(len(morse)):
  3777. if word == morse[c]:
  3778. print(alphabet[c])
  3779. ```
  3780. ## [DAY-80] Lists; Functions
  3781. ![game-80.png](./screenshots/game-80.png "game 80 screenshot")
  3782. PONG (almost)
  3783. ```
  3784. import pgzrun
  3785. import random
  3786. HEIGHT = 200
  3787. WIDTH = 200
  3788. left = Actor("c1")
  3789. left.x = 10
  3790. left.y = HEIGHT/2
  3791. right = Actor("c2")
  3792. right.x = WIDTH - 10
  3793. right.y = HEIGHT/2
  3794. ball = Actor("bullet")
  3795. ball.x = WIDTH/2
  3796. ball.y = HEIGHT/2
  3797. game_area = Rect((0, 0), (WIDTH, HEIGHT))
  3798. game_over = False
  3799. def send_ball_to(direction):
  3800. duration = 3
  3801. if direction == 'left':
  3802. animate(ball, pos=(-100, random.randint(0,HEIGHT)), tween='linear', duration=duration)
  3803. else:
  3804. animate(ball, pos=(WIDTH + 100, random.randint(0,HEIGHT)), tween='linear', duration=duration)
  3805. def update():
  3806. global game_over
  3807. speed = 3
  3808. if keyboard.R:
  3809. ball.x = WIDTH/2
  3810. ball.y = HEIGHT/2
  3811. send_ball_to('left')
  3812. game_over = False
  3813. if keyboard.W:
  3814. left.y -= speed
  3815. if keyboard.S:
  3816. left.y += speed
  3817. if keyboard.up:
  3818. right.y -= speed
  3819. if keyboard.down:
  3820. right.y += speed
  3821. if left.colliderect(ball):
  3822. send_ball_to('right')
  3823. if right.colliderect(ball):
  3824. send_ball_to('left')
  3825. if not ball.colliderect(game_area):
  3826. game_over = True
  3827. def draw():
  3828. if game_over:
  3829. screen.fill('black')
  3830. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3831. else:
  3832. screen.fill('black')
  3833. left.draw()
  3834. right.draw()
  3835. ball.draw()
  3836. screen.draw.rect(game_area, (200, 0, 0))
  3837. send_ball_to('left')
  3838. pgzrun.go()
  3839. ```
  3840. ![day-80-a.jpg](./reading/day-80-a.jpg "day 80 reading pong")
  3841. average of two lists
  3842. ![day-80-b.jpg](./reading/day-80-b.jpg "day 80 reading average of two lists")
  3843. ## [DAY-81] Lists; Encoding
  3844. First image
  3845. ```
  3846. +-----+
  3847. | * * |
  3848. | * |
  3849. | * * |
  3850. +-----+
  3851. ```
  3852. list of lists with pixels
  3853. ```
  3854. image = [
  3855. [1,3,3,3,3,3,1],
  3856. [2,4,5,4,5,4,2],
  3857. [2,4,4,5,4,4,2],
  3858. [2,4,5,4,5,4,2],
  3859. [1,3,3,3,3,3,1],
  3860. ]
  3861. for row in image:
  3862. for pixel in row:
  3863. if pixel == 1:
  3864. print('+', end='')
  3865. elif pixel == 2:
  3866. print('|', end='')
  3867. elif pixel == 3:
  3868. print('-', end='')
  3869. elif pixel == 4:
  3870. print(' ', end='')
  3871. elif pixel == 5:
  3872. print('*', end='')
  3873. else:
  3874. print("dont know what to do with: " + str(pixel))
  3875. print('')
  3876. ```
  3877. just a list of pixels
  3878. ```
  3879. image = [
  3880. 1,3,3,3,3,3,1,
  3881. 2,4,5,4,5,4,2,
  3882. 2,4,4,5,4,4,2,
  3883. 2,4,5,4,5,4,2,
  3884. 1,3,3,3,3,3,1,
  3885. ]
  3886. width = 7
  3887. for (index, pixel) in enumerate(image):
  3888. if index > 0 and index % width == 0:
  3889. print('')
  3890. if pixel == 1:
  3891. print('+', end='')
  3892. elif pixel == 2:
  3893. print('|', end='')
  3894. elif pixel == 3:
  3895. print('-', end='')
  3896. elif pixel == 4:
  3897. print(' ', end='')
  3898. elif pixel == 5:
  3899. print('*', end='')
  3900. else:
  3901. print("dont know what to do with: " + str(pixel))
  3902. ```
  3903. some fun with lists
  3904. ```
  3905. x = ['a','b','c','d']
  3906. m = ['w','x','y','z']
  3907. d = ['g','h','j','k']
  3908. # a -> 0
  3909. # b -> 1
  3910. # c -> 2
  3911. for i in range(len(x)):
  3912. print(i,end=' ')
  3913. print(x[i],end=' ')
  3914. print(m[i],end=' ')
  3915. print(d[i])
  3916. ```
  3917. how similar are lists and strings
  3918. ```
  3919. x = 'hello'
  3920. for i in range(len(x)):
  3921. print(i,end=' ')
  3922. print(x[i])
  3923. ```
  3924. similar, but not quite, you cant change the inside of a string, but you can change the inside of a list.
  3925. ```
  3926. x = ['h','e','l','l','o']
  3927. y = 'hello'
  3928. x[2] = 'm'
  3929. y = 'hemlo'
  3930. for i in range(len(x)):
  3931. print(i,end=' ')
  3932. print(x[i], end=' ')
  3933. print(y[i])
  3934. ```
  3935. sum many lists
  3936. ```
  3937. a = [6,3,2]
  3938. b = [78,21,1]
  3939. c = [123,5,1]
  3940. sum = 0
  3941. for i in range(len(a)):
  3942. sum += a[i] + b[i] + c[i]
  3943. print(sum)
  3944. ```
  3945. another way to sum
  3946. ```
  3947. a = [6,3,2]
  3948. b = [78,21,1]
  3949. c = [123,5,1]
  3950. sum = 0
  3951. for x in a:
  3952. sum += x
  3953. for x in b:
  3954. sum += x
  3955. for x in c:
  3956. sum += x
  3957. print(sum)
  3958. ```
  3959. ## [DAY-82] Lists; Strings
  3960. ![game-82.png](./screenshots/game-82.png "game 82 screenshot")
  3961. simple game with history, press S to save your position to a list of positions, and then B to go back in time
  3962. ```
  3963. import pgzrun
  3964. import random
  3965. HEIGHT = 200
  3966. WIDTH = 200
  3967. player = Actor("c1")
  3968. player.x = WIDTH/2
  3969. player.y = HEIGHT/2
  3970. history = []
  3971. def on_key_down(key):
  3972. speed = 3
  3973. if key == keys.UP:
  3974. player.y -= speed
  3975. if key == keys.DOWN:
  3976. player.y += speed
  3977. if key == keys.LEFT:
  3978. player.x -= speed
  3979. if key == keys.RIGHT:
  3980. player.x += speed
  3981. if key == keys.S:
  3982. position = [player.x, player.y]
  3983. history.append(position)
  3984. print('append', history)
  3985. if key == keys.B and len(history) > 0:
  3986. last = history.pop()
  3987. player.x = last[0]
  3988. player.y = last[1]
  3989. print('pop', history)
  3990. def draw():
  3991. screen.fill('black')
  3992. player.draw()
  3993. pgzrun.go()
  3994. ```
  3995. Two players, and more positions
  3996. ```
  3997. import pgzrun
  3998. import random
  3999. HEIGHT = 200
  4000. WIDTH = 200
  4001. player1 = Actor("c1")
  4002. player2 = Actor('c2')
  4003. history = []
  4004. def on_key_down(key):
  4005. speed = 10
  4006. if key == keys.W:
  4007. player1.y-= speed
  4008. if key == keys.A:
  4009. player1.x-=speed
  4010. if key == keys.S:
  4011. player1.y += speed
  4012. if key == keys.D:
  4013. player1.x += speed
  4014. if key == keys.UP:
  4015. player2.y-= speed
  4016. if key == keys.LEFT:
  4017. player2.x-=speed
  4018. if key == keys.DOWN:
  4019. player2.y += speed
  4020. if key == keys.RIGHT:
  4021. player2.x += speed
  4022. if key == keys.F:
  4023. positions = [player1.x,player1.y,player2.x,player2.y]
  4024. history.append(positions)
  4025. print('push', history)
  4026. if key == keys.G:
  4027. if len(history) > 0:
  4028. positions = history.pop()
  4029. player1.x = positions[0]
  4030. player1.y = positions[1]
  4031. player2.x = positions[2]
  4032. player2.y = positions[3]
  4033. print('pop', history)
  4034. def draw():
  4035. screen.fill('black')
  4036. player1.draw()
  4037. player2.draw()
  4038. pgzrun.go()
  4039. ```
  4040. More lists
  4041. ```
  4042. a = ['h','w','e']
  4043. b = ['e','o','a']
  4044. c = ['l','r','r']
  4045. d = ['l','l','t']
  4046. e = ['o','d','h']
  4047. sum1 = ''
  4048. sum2 = ''
  4049. sum1 = a[0] + b[0] + c[0] + d[0] + e[0]
  4050. sum2 = a[1] + b[1] + c[1] + d[1] + e[1]
  4051. print(sum1)
  4052. print(sum2)
  4053. sum = []
  4054. for i in range(len(a)):
  4055. sum.append('')
  4056. sum[i] = a[i] + b[i] + c[i] + d[i] + e[i]
  4057. print(sum)
  4058. ```
  4059. sum from the input
  4060. ```
  4061. list = []
  4062. while True:
  4063. integer = int(input('enter a number: '))
  4064. list.append(integer)
  4065. sum = 0
  4066. for i in list:
  4067. sum += i
  4068. print(list, sum)
  4069. ```
  4070. ## [DAY-83] Lists; Functions
  4071. ![game-83.png](./screenshots/game-83.png "game 83 screenshot")
  4072. ```
  4073. import pgzrun
  4074. import random
  4075. HEIGHT = 200
  4076. WIDTH = 200
  4077. player = Actor("c1")
  4078. player.x = WIDTH/2
  4079. player.y = HEIGHT/2
  4080. things = []
  4081. def on_key_down(key):
  4082. speed = 10
  4083. if key == keys.UP:
  4084. player.y -= speed
  4085. if key == keys.DOWN:
  4086. player.y += speed
  4087. if key == keys.LEFT:
  4088. player.x -= speed
  4089. if key == keys.RIGHT:
  4090. player.x += speed
  4091. if key == keys.F:
  4092. thing = Actor("flower")
  4093. thing.x = player.x
  4094. thing.y = player.y
  4095. things.append(thing)
  4096. if key == keys.R:
  4097. thing = Actor("rock")
  4098. thing.x = player.x
  4099. thing.y = player.y
  4100. things.append(thing)
  4101. def draw():
  4102. screen.fill('black')
  4103. player.draw()
  4104. for t in things:
  4105. t.draw()
  4106. pgzrun.go()
  4107. ```
  4108. With a function, so we can add more keys faster and we dont duplicate that much code
  4109. ```
  4110. import pgzrun
  4111. import random
  4112. HEIGHT = 200
  4113. WIDTH = 200
  4114. player = Actor("c1")
  4115. player.x = WIDTH/2
  4116. player.y = HEIGHT/2
  4117. things = []
  4118. def place_thing(kind):
  4119. thing = Actor(kind)
  4120. thing.x = player.x
  4121. thing.y = player.y
  4122. things.append(thing)
  4123. def on_key_down(key):
  4124. speed = 15
  4125. if key == keys.UP:
  4126. player.y -= speed
  4127. if key == keys.DOWN:
  4128. player.y += speed
  4129. if key == keys.LEFT:
  4130. player.x -= speed
  4131. if key == keys.RIGHT:
  4132. player.x += speed
  4133. if key == keys.F:
  4134. place_thing("flower")
  4135. if key == keys.R:
  4136. place_thing("rock")
  4137. if key == keys.K:
  4138. place_thing("c2")
  4139. def draw():
  4140. screen.fill('black')
  4141. player.draw()
  4142. for t in things:
  4143. t.draw()
  4144. pgzrun.go()
  4145. ```
  4146. Now we can make a map, just add the kind of thing, its x and y position in a list and print it, after we are done building the map we can use it later
  4147. ```
  4148. ...
  4149. game_map = []
  4150. def place_thing(kind):
  4151. thing = Actor(kind)
  4152. thing.x = player.x
  4153. thing.y = player.y
  4154. things.append(thing)
  4155. game_map.append([kind, thing.x, thing.y])
  4156. print(game_map)
  4157. ...
  4158. ```
  4159. use the map:
  4160. ![game-83-a.png](./screenshots/game-83-a.png "game 83-a screenshot")
  4161. ```
  4162. import pgzrun
  4163. import random
  4164. HEIGHT = 200
  4165. WIDTH = 200
  4166. player = Actor("c1")
  4167. player.x = WIDTH/2
  4168. player.y = HEIGHT/2
  4169. things = []
  4170. def place_thing(kind,x,y):
  4171. thing = Actor(kind)
  4172. thing.x = x
  4173. thing.y = y
  4174. things.append(thing)
  4175. def on_key_down(key):
  4176. speed = 15
  4177. if key == keys.UP:
  4178. player.y -= speed
  4179. if key == keys.DOWN:
  4180. player.y += speed
  4181. if key == keys.LEFT:
  4182. player.x -= speed
  4183. if key == keys.RIGHT:
  4184. player.x += speed
  4185. def draw():
  4186. screen.fill('black')
  4187. player.draw()
  4188. for t in things:
  4189. t.draw()
  4190. game_map = [['rock', 100.0, 55.0], ['flower', 100.0, 85.0], ['c2', 100.0, 130.0], ['c2', 70.0, 130.0], ['c2', 55.0, 130.0], ['c2', 40.0, 130.0], ['c2', 25.0, 130.0], ['c2', 25.0, 100.0], ['c2', 25.0, 85.0], ['c2', 25.0, 70.0], ['c2', 25.0, 55.0], ['c2', 25.0, 40.0], ['c2', 25.0, 25.0], ['c2', 40.0, 25.0], ['c2', 55.0, 25.0], ['c2', 70.0, 25.0], ['c2', 85.0, 25.0], ['c2', 100.0, 25.0], ['c2', 115.0, 25.0], ['c2', 130.0, 25.0], ['c2', 145.0, 25.0], ['c2', 145.0, 40.0], ['c2', 145.0, 55.0], ['c2', 145.0, 70.0], ['c2', 145.0, 85.0], ['c2', 145.0, 100.0], ['c2', 145.0, 115.0], ['c2', 145.0, 130.0], ['c2', 130.0, 130.0], ['c2', 115.0, 130.0], ['c2', 100.0, 130.0], ['c2', 85.0, 130.0], ['c2', 25.0, 115.0]]
  4191. for g in game_map:
  4192. place_thing(g[0],g[1],g[2])
  4193. pgzrun.go()
  4194. ```
  4195. ![game-83-b.png](./screenshots/game-83-b.png "game 83-a screenshot")
  4196. ![game-83-c.png](./screenshots/game-83-c.png "game 83-c screenshot")
  4197. Another way to do it, press S to print the list of things, and then paste it in the game[] list to use it, D deletes things where you stand, and U removes the last thing
  4198. ```
  4199. import pgzrun
  4200. import random
  4201. HEIGHT = 200
  4202. WIDTH = 200
  4203. player = Actor("c1")
  4204. things = []
  4205. game = []
  4206. for g in game:
  4207. t = Actor(g[0])
  4208. t.x = g[1]
  4209. t.y = g[2]
  4210. things.append(t)
  4211. def on_key_down(key):
  4212. speed = 10
  4213. if key == keys.UP:
  4214. player.y -= speed
  4215. if key == keys.DOWN:
  4216. player.y += speed
  4217. if key == keys.LEFT:
  4218. player.x -= speed
  4219. if key == keys.RIGHT:
  4220. player.x += speed
  4221. if key == keys.F:
  4222. f = Actor("flower")
  4223. f.x = player.x
  4224. f.y = player.y
  4225. things.append(f)
  4226. if key == keys.R:
  4227. f = Actor("rock")
  4228. f.x = player.x
  4229. f.y = player.y
  4230. things.append(f)
  4231. if key == keys.U:
  4232. things.pop()
  4233. if key == keys.D:
  4234. collide = []
  4235. for t in things:
  4236. if player.colliderect(t):
  4237. collide.append(t)
  4238. for t in collide:
  4239. things.remove(t)
  4240. if key == keys.S:
  4241. positions = []
  4242. for t in things:
  4243. positions.append([t.image,t.x,t.y])
  4244. print(positions)
  4245. def draw():
  4246. screen.fill('black')
  4247. player.draw()
  4248. for t in things:
  4249. t.draw()
  4250. pgzrun.go()
  4251. ```
  4252. ## [DAY-84] Lists
  4253. ![game-84.png](./screenshots/game-84.png "game 84 screenshot")
  4254. Lets visualize the list, try to delete from the middle, and see how the indexes change.
  4255. ```
  4256. import pgzrun
  4257. import random
  4258. HEIGHT = 200
  4259. WIDTH = 200
  4260. player = Actor("c1")
  4261. things = []
  4262. def on_key_down(key):
  4263. speed = 10
  4264. if key == keys.UP:
  4265. player.y -= speed
  4266. if key == keys.DOWN:
  4267. player.y += speed
  4268. if key == keys.LEFT:
  4269. player.x -= speed
  4270. if key == keys.RIGHT:
  4271. player.x += speed
  4272. if key == keys.F:
  4273. f = Actor("flower")
  4274. f.x = player.x
  4275. f.y = player.y
  4276. things.append(f)
  4277. if key == keys.R:
  4278. f = Actor("rock")
  4279. f.x = player.x
  4280. f.y = player.y
  4281. things.append(f)
  4282. if key == keys.U:
  4283. things.pop()
  4284. if key == keys.D:
  4285. collide = []
  4286. for t in things:
  4287. if player.colliderect(t):
  4288. collide.append(t)
  4289. for t in collide:
  4290. things.remove(t)
  4291. def draw():
  4292. screen.fill('black')
  4293. player.draw()
  4294. for i in range(len(things)):
  4295. t = things[i]
  4296. t.draw()
  4297. screen.draw.text(str(i), color=(255,255,255), topleft=(t.x,t.y))
  4298. if i > 0:
  4299. p = things[i-1]
  4300. screen.draw.line((p.x,p.y), (t.x,t.y), (255,255,255))
  4301. pgzrun.go()
  4302. ```
  4303. spend more time thinking about connecting previous and current elements from a list, think about how to do it the other way around, from current element to next:
  4304. ```
  4305. # change this to go from t to the next element of things, instead from t to previous
  4306. for i in range(len(things)):
  4307. t = things[i]
  4308. ...
  4309. if i > 0:
  4310. p = things[i-1]
  4311. ...
  4312. ```
  4313. ## [DAY-85] List; Functions
  4314. This day is more about reading than writing, those are few different examples you can use
  4315. ![game-85.png](./screenshots/game-85.png "game 85 screenshot")
  4316. don't let the **zombie** flowers overrun you, smash them with rocks
  4317. ```
  4318. import pgzrun
  4319. import random
  4320. HEIGHT = 200
  4321. WIDTH = 200
  4322. game_over = False
  4323. elf = Actor("c1")
  4324. elf.x = WIDTH/2
  4325. elf.y = HEIGHT-20
  4326. flowers = []
  4327. rocks = []
  4328. game_area = Rect((0, 0), (WIDTH, HEIGHT-40))
  4329. def add_one_row():
  4330. lastY = 0
  4331. if len(flowers) > 0:
  4332. f = flowers[len(flowers)-1]
  4333. lastY = f.y
  4334. for i in range(20, WIDTH-10, 20):
  4335. f = Actor("flower")
  4336. f.x = i
  4337. f.y = lastY + 10
  4338. flowers.append(f)
  4339. def rock_out_of_screen():
  4340. if len(rocks) > 0:
  4341. rocks.pop(0)
  4342. def on_key_down(key):
  4343. speed = 10
  4344. if key == keys.LEFT:
  4345. elf.x -= speed
  4346. if key == keys.RIGHT:
  4347. elf.x += speed
  4348. if key == keys.SPACE:
  4349. rock = Actor("rock")
  4350. rock.x = elf.x
  4351. rock.y = elf.y - 20
  4352. animate(rock,pos=(rock.x, -100), on_finished=rock_out_of_screen)
  4353. rocks.append(rock)
  4354. def update():
  4355. global game_over
  4356. hit = []
  4357. for b in rocks:
  4358. for f in flowers:
  4359. if b.colliderect(f) and random.randint(0,10) > 7:
  4360. hit.append(f)
  4361. for h in hit:
  4362. flowers.remove(h)
  4363. for f in flowers:
  4364. if not f.colliderect(game_area):
  4365. game_over = True
  4366. def draw():
  4367. if game_over:
  4368. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  4369. else:
  4370. screen.fill('black')
  4371. elf.draw()
  4372. for f in flowers:
  4373. f.draw()
  4374. for r in rocks:
  4375. r.draw()
  4376. screen.draw.rect(game_area, (200, 0, 0))
  4377. add_one_row()
  4378. clock.schedule_interval(add_one_row, 5)
  4379. pgzrun.go()
  4380. ```
  4381. ![game-85-a.png](./screenshots/game-85-a.png "game 85-a screenshot")
  4382. ```
  4383. import turtle as t
  4384. size = 10
  4385. t.pensize(size)
  4386. t.left(45)
  4387. t.forward(90)
  4388. t.circle(45,extent=180)
  4389. t.right(90)
  4390. t.circle(45,extent=180)
  4391. t.forward(90)
  4392. t.penup()
  4393. t.goto(-35,-35)
  4394. t.pendown()
  4395. t.write('i love python')
  4396. t.penup()
  4397. ```
  4398. ![game-85-b.png](./screenshots/game-85-b.png "game 85-b screenshot")
  4399. ```
  4400. import turtle as t
  4401. import datetime
  4402. import time
  4403. def deg(h,m,s):
  4404. hDeg=(h*3600+m*60+s)/(3600*12)*360
  4405. mDeg=(m*60+s)/3600*360
  4406. sDeg=360/60*s
  4407. return (90+hDeg,90+mDeg,90+sDeg)
  4408. def show(h, size):
  4409. (hDeg,m,s) = deg(h,0,0)
  4410. t.penup()
  4411. t.goto(0, size)
  4412. t.pencolor('white')
  4413. t.setheading(hDeg)
  4414. t.forward(size)
  4415. t.write(str(h))
  4416. def klok(size, h, m, s):
  4417. t.reset()
  4418. (hDeg,mDeg,sDeg) = deg(h,m,s)
  4419. t.pendown()
  4420. t.pensize(7)
  4421. t.bgcolor('black')
  4422. t.pencolor('lime')
  4423. t.circle(size)
  4424. t.penup()
  4425. t.goto(0, size)
  4426. t.setheading(hDeg)
  4427. t.pendown()
  4428. t.pencolor('springgreen')
  4429. t.forward(size/3)
  4430. t.penup()
  4431. t.goto(0, size)
  4432. t.setheading(mDeg)
  4433. t.pendown()
  4434. t.pencolor('lawngreen')
  4435. t.forward(size/2)
  4436. t.penup()
  4437. t.pencolor('cyan')
  4438. t.goto(0, size)
  4439. t.setheading(sDeg)
  4440. t.pendown()
  4441. t.forward(size-25)
  4442. t.penup()
  4443. size = 150
  4444. while True:
  4445. now = datetime.datetime.now()
  4446. klok(size,now.hour, now.minute, now.second)
  4447. for h in range(1, 13):
  4448. show(h,size)
  4449. time.sleep(10)
  4450. ```
  4451. ![game-85-c.png](./screenshots/game-85-c.png "game 85-c screenshot")
  4452. Just one rock that hits the zombies above you
  4453. ```
  4454. import pgzrun
  4455. import random
  4456. HEIGHT = 200
  4457. WIDTH = 200
  4458. game_over = False
  4459. elf = Actor("c1")
  4460. elf.x = WIDTH/2
  4461. elf.y = HEIGHT-20
  4462. rock = Actor("rock")
  4463. rock.x = elf.x + 10
  4464. rock.y = elf.y - 20
  4465. flowers = []
  4466. def add_one_row():
  4467. lastY = 0
  4468. if len(flowers) > 0:
  4469. f = flowers[len(flowers)-1]
  4470. lastY = f.y
  4471. for i in range(20, WIDTH-10, 20):
  4472. f = Actor("flower")
  4473. f.x = i
  4474. f.y = lastY + 10
  4475. flowers.append(f)
  4476. def on_key_down(key):
  4477. speed = 10
  4478. if key == keys.LEFT:
  4479. elf.x -= speed
  4480. if key == keys.RIGHT:
  4481. elf.x += speed
  4482. if key == keys.UP:
  4483. elf.y -= speed
  4484. if key == keys.DOWN:
  4485. elf.y += speed
  4486. def update():
  4487. global game_over
  4488. hit = []
  4489. for f in flowers:
  4490. if rock.colliderect(f) and random.randint(0,10) > 7:
  4491. hit.append(f)
  4492. for h in hit:
  4493. flowers.remove(h)
  4494. rock.x -= 1
  4495. if rock.x < elf.x - 10:
  4496. rock.x = elf.x + 10
  4497. rock.y = elf.y - 20
  4498. def draw():
  4499. screen.fill('black')
  4500. elf.draw()
  4501. rock.draw()
  4502. for f in flowers:
  4503. f.draw()
  4504. add_one_row()
  4505. clock.schedule_interval(add_one_row, 5)
  4506. pgzrun.go()
  4507. ```
  4508. ![day-85.jpg](./reading/day-85.jpg "day 85 reading")
  4509. ## [DAY-86] Lists
  4510. ![game-86.png](./screenshots/game-86.png "game 86 screenshot")
  4511. SNAKE
  4512. ```
  4513. import pgzrun
  4514. import random
  4515. HEIGHT = 200
  4516. WIDTH = 200
  4517. snake = Actor("c1")
  4518. snake.x = WIDTH/2
  4519. snake.y = HEIGHT-20
  4520. apple = Actor("flower")
  4521. apple.x = WIDTH/2
  4522. apple.y = HEIGHT/2
  4523. snake_size = 20
  4524. snake_speed = 1
  4525. steps = []
  4526. direction = "up"
  4527. step_size = 1
  4528. game_over = False
  4529. game_area = Rect(0,0,WIDTH,HEIGHT)
  4530. def on_key_down(key):
  4531. global direction
  4532. if key == keys.LEFT:
  4533. direction = "left"
  4534. if key == keys.RIGHT:
  4535. direction = "right"
  4536. if key == keys.UP:
  4537. direction = "up"
  4538. if key == keys.DOWN:
  4539. direction = "down"
  4540. def update():
  4541. global snake_size, game_over, snake_speed, steps
  4542. s = Actor("snake")
  4543. s.x = snake.x
  4544. s.y = snake.y
  4545. steps.append(s)
  4546. if len(steps) > snake_size:
  4547. steps = steps[-snake_size:]
  4548. if direction == "left":
  4549. snake.x -= step_size
  4550. if direction == "right":
  4551. snake.x += step_size
  4552. if direction == "up":
  4553. snake.y -= step_size
  4554. if direction == "down":
  4555. snake.y += step_size
  4556. if snake.colliderect(apple):
  4557. apple.x = random.randint(0,WIDTH)
  4558. apple.y = random.randint(0,HEIGHT)
  4559. snake_size += step_size * 10
  4560. if not snake.colliderect(game_area):
  4561. game_over = True
  4562. def draw():
  4563. screen.fill('black')
  4564. if game_over:
  4565. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  4566. else:
  4567. screen.draw.rect(game_area, (255,0,0))
  4568. for s in steps:
  4569. s.draw()
  4570. snake.draw()
  4571. apple.draw()
  4572. pgzrun.go()
  4573. ```
  4574. There are few key moments to emphasize, but the most important one is `steps = steps[-snake_size:]`.
  4575. Try this in IDLE:
  4576. ```
  4577. x = [1,2,3,4]
  4578. print(x[-1])
  4579. ```
  4580. It will print '4', so in python you can get elements from the back of the list, just as easily as the front, try `x[-2]`, now try to get multiple elements from a list, `y = x[0:2]`, it will make new list `[1,2]`, it is a bit like this code:
  4581. ```
  4582. x = [1,2,3,4]
  4583. y = []
  4584. for i in range(0,2):
  4585. y.append(x[i])
  4586. ```
  4587. Now you can also ask python to give you the first 2 elements by saying `x[0:2]` or you can ask it for the elements *after* the second one by doing `x[2:len(x)]`, you can omit 0 and `len(x)` so it is a bit shorter, `x[:2]` and `x[2:]`. Sometimes you want the last 2 elements, to do that just say `x[-2:len(x)]` or `x[-2:]` and that's how we are getting the last `snake_size` elements of the `steps` list.
  4588. Again, `x[-2:len(x)]` just means from -2 elements from the end if the list, until the end of the list. It looks scary though.
  4589. Similar to this code:
  4590. ```
  4591. x = [1,2,3,4]
  4592. y = []
  4593. for i in range(len(x)-2,len(x)):
  4594. y.append(x[i])
  4595. ```
  4596. ## [DAY-87] Read/Write Files
  4597. Its File time!
  4598. First lets make a new file, called day-87.txt and we will open it in "w" mode, which means "write", so once we do `f.write` it will start from the beginning of the file, we can use "a" (for append) mode as well that would continue appending to the end of the file
  4599. ```
  4600. f = open("day-87.txt", "w")
  4601. while True:
  4602. a = input("what do you want to write: ")
  4603. if a == "quit":
  4604. break
  4605. f.write(a + "\n")
  4606. f.close()
  4607. ```
  4608. Now you can open day-87.txt with Notepad or some other text editor and see what you wrote.
  4609. It is important to remember this pattern
  4610. 1. Open
  4611. 2. Read or Write
  4612. 3. Read or Write
  4613. 4. Read or Write
  4614. 5. Read or Write
  4615. 6. ...
  4616. 7. Close
  4617. lets see how you read a file:
  4618. ```
  4619. f = open("day-87.txt", "r")
  4620. data = f.read()
  4621. print(data)
  4622. ```
  4623. Make a game that persists the player position.
  4624. ```
  4625. import pgzrun
  4626. import random
  4627. HEIGHT = 200
  4628. WIDTH = 200
  4629. elf = Actor("c1")
  4630. elf.x = WIDTH/2
  4631. elf.y = HEIGHT-20
  4632. try:
  4633. x = open("day-87-x.txt", "r")
  4634. elf.x = float(x.read())
  4635. x.close()
  4636. y = open("day-87-y.txt", "r")
  4637. elf.y = float(y.read())
  4638. y.close()
  4639. except IOError:
  4640. pass
  4641. def on_key_down(key):
  4642. speed = 10
  4643. if key == keys.LEFT:
  4644. elf.x -= speed
  4645. if key == keys.RIGHT:
  4646. elf.x += speed
  4647. if key == keys.UP:
  4648. elf.y -= speed
  4649. if key == keys.DOWN:
  4650. elf.y += speed
  4651. if key == keys.S:
  4652. x = open("day-87-x.txt", "w")
  4653. x.write(str(elf.x))
  4654. x.close()
  4655. y = open("day-87-y.txt", "w")
  4656. y.write(str(elf.y))
  4657. y.close()
  4658. def draw():
  4659. screen.fill('black')
  4660. elf.draw()
  4661. pgzrun.go()
  4662. ```
  4663. open `day-87-x.txt` and `day-87-y.txt` to see the positions of X and Y of the elf after you press `S`.
  4664. One other patter you will see is:
  4665. ```
  4666. try:
  4667. try to do something
  4668. except some error:
  4669. handle error
  4670. ```
  4671. There are many many things that could go wrong when you write to or read a file, for example when you read the file might not be created, or you might have no access to read it, or when you write the disk might be full, and there is no more space.
  4672. In our example we don't check if our write fails, so if your disk is full the game will crash, but in the beginning we do check for IOError in case the reading fails, and it will if the files are not created yet the very first time you start the game and there is no save yet.
  4673. ## [DAY-88] Flask
  4674. Reading exercise, a lot of unfamiliar code
  4675. ```
  4676. from flask import Flask, redirect, request,make_response
  4677. import random
  4678. app = Flask(__name__)
  4679. tokens = {}
  4680. @app.route('/')
  4681. def index():
  4682. token = request.cookies.get('token')
  4683. if token in tokens:
  4684. response = make_response("""
  4685. welcome to the secure section of the website,
  4686. <a href="/logout">click here to logout
  4687. """)
  4688. return response
  4689. response = make_response("""
  4690. <html>
  4691. <form action="/login" method="post">
  4692. user: <input name="user">
  4693. pass: <input type="password" name="pass">
  4694. <input type="submit">
  4695. </form>
  4696. </html>
  4697. """)
  4698. return response
  4699. @app.route('/logout')
  4700. def logout():
  4701. token = request.cookies.get('token')
  4702. try:
  4703. del tokens[token]
  4704. except KeyError:
  4705. pass
  4706. response = make_response(redirect('/'))
  4707. response.set_cookie('token', '')
  4708. return response
  4709. @app.route('/login', methods = ['POST'])
  4710. def login():
  4711. user = request.form['user']
  4712. password = request.form['pass']
  4713. if user == "admin" and password == "123":
  4714. token = str(random.randint(0,10000000))
  4715. tokens[token] = "admin"
  4716. response = make_response(redirect('/'))
  4717. response.set_cookie('token', token)
  4718. return response
  4719. else:
  4720. return "access denied"
  4721. if __name__ == "__main__":
  4722. app.run(host="127.0.0.1",port=8000,debug=True)
  4723. ```
  4724. start the script, see what it does, try to debug how `tokens` changes. Inspect your cookies, try to hack it, login from private mode and steal the cookie from the console.
  4725. ## [DAY-89] Files; Strings; Lists
  4726. super simple text editor
  4727. ![game-89.png](./screenshots/game-89.png "game 89 screenshot")
  4728. Reading exercise, make a text editor, save with `ctrl+s` and quit with `ctrl+q`
  4729. ```
  4730. import pgzrun
  4731. import random
  4732. HEIGHT = 480
  4733. WIDTH = 640
  4734. filename = "example.py"
  4735. lines = [[]]
  4736. cursor_row = 0
  4737. cursor_col = 0
  4738. try:
  4739. x = open(filename, "r")
  4740. for c in x.read():
  4741. if c== '\n' or c == '\r':
  4742. lines.append([])
  4743. cursor_row += 1
  4744. cursor_col = 0
  4745. else:
  4746. lines[cursor_row].append(c)
  4747. cursor_col += 1
  4748. x.close()
  4749. except IOError:
  4750. pass
  4751. def lines_to_string():
  4752. s = ''
  4753. for r in lines:
  4754. for c in r:
  4755. s += c
  4756. s += '\n'
  4757. return s
  4758. def on_key_down(key, mod, unicode):
  4759. global cursor_row, cursor_col
  4760. if key == keys.Q and mod == keymods.LCTRL:
  4761. exit()
  4762. if key == keys.S and mod == keymods.LCTRL:
  4763. x = open(filename, "w")
  4764. s = lines_to_string()
  4765. x.write(s)
  4766. x.close()
  4767. elif key == keys.LEFT:
  4768. if cursor_col > 0:
  4769. cursor_col -= 1
  4770. elif key == keys.RIGHT:
  4771. if cursor_col < len(lines[cursor_row]):
  4772. cursor_col += 1
  4773. elif key == keys.UP:
  4774. if cursor_row > 0:
  4775. cursor_row -= 1
  4776. if cursor_col > len(lines[cursor_row]):
  4777. cursor_col = len(lines[cursor_row])
  4778. elif key == keys.DOWN:
  4779. if cursor_row < len(lines) - 1:
  4780. cursor_row += 1
  4781. if cursor_col > len(lines[cursor_row]):
  4782. cursor_col = len(lines[cursor_row])
  4783. elif key == keys.BACKSPACE:
  4784. if cursor_col == 0:
  4785. if cursor_row >= 1:
  4786. row = lines.pop(cursor_row)
  4787. cursor_col = len(lines[cursor_row-1])
  4788. for c in row:
  4789. lines[cursor_row-1].append(c)
  4790. cursor_row -= 1
  4791. else:
  4792. row = lines[cursor_row]
  4793. if len(row) > 0:
  4794. cursor_col -= 1
  4795. row.pop(cursor_col)
  4796. elif key == keys.RETURN:
  4797. # get the rest of the lines
  4798. left = []
  4799. right = []
  4800. if cursor_col < len(lines[cursor_row]):
  4801. # split the line if we are pressing enter in the middle
  4802. row = lines[cursor_row]
  4803. left = row[:cursor_col]
  4804. right = row[cursor_col:]
  4805. if cursor_row < len(lines):
  4806. lines[cursor_row] = left
  4807. cursor_col = 0
  4808. cursor_row += 1
  4809. lines.insert(cursor_row, right)
  4810. elif len(unicode) > 0 and ord(unicode) >= 20 and ord(unicode) <= 125:
  4811. lines[cursor_row].insert(cursor_col, unicode)
  4812. cursor_col += 1
  4813. def draw():
  4814. screen.fill('black')
  4815. screen.draw.text(filename + ", " + str(cursor_row) + ":" + str(cursor_col), (0,0), fontsize=20,fontname="437-win", color="green")
  4816. x = 0
  4817. y = 30
  4818. stepX = 10
  4819. stepY = 22
  4820. for (index_row, row) in enumerate(lines):
  4821. for (index_col, c) in enumerate(row):
  4822. screen.draw.text(c, (x,y), fontsize=20,fontname="437-win")
  4823. x += stepX
  4824. y += stepY
  4825. x = 0
  4826. cursorX = cursor_col * stepX
  4827. cursorY = 30 + (cursor_row * stepY)
  4828. screen.draw.rect(Rect((cursorX,cursorY,stepX,stepY)), (255,0,0))
  4829. pgzrun.go()
  4830. ```
  4831. write some python, and then run it with `python3 example.py`
  4832. ## [DAY-90] Strings
  4833. ![game-90.png](./screenshots/game-90.png "game 90 screenshot")
  4834. Write a super simple text editor. Start by thinking about the problem. How can you display a character on the screen? How can you get the input from the user? How are you going to deal with new lines?
  4835. ```
  4836. import pgzrun
  4837. HEIGHT = 480
  4838. WIDTH = 640
  4839. text = ''
  4840. def on_key_down(key, mod, unicode):
  4841. global text
  4842. if key == keys.Q and mod == keymods.LCTRL:
  4843. exit()
  4844. elif key == keys.BACKSPACE:
  4845. if len(text) > 0:
  4846. text = text[:len(text)-1]
  4847. elif key == keys.RETURN:
  4848. text += '\n'
  4849. elif len(unicode) > 0 and ord(unicode) >= 20 and ord(unicode) <= 125:
  4850. text += unicode
  4851. def draw():
  4852. screen.fill('black')
  4853. x = 0
  4854. y = 0
  4855. stepX = 10
  4856. stepY = 22
  4857. for c in text:
  4858. if c == '\n':
  4859. y += stepY
  4860. x = 0
  4861. else:
  4862. screen.draw.text(c, (x,y), fontsize=20,fontname="437-win")
  4863. x += stepX
  4864. screen.draw.rect(Rect((x,y,stepX,stepY)), (255,0,0))
  4865. pgzrun.go()
  4866. ```
  4867. This is kind of what `screen.draw.text` does, you can of course just do `screen.draw.text(text, (0,0), fontsize=20,fontname="437-win")` and it will work fine, instead of displaying character by character and computing our own char spacing, but what is the fun in that? Also this way we are one step closer to be able to move the cursor left and right so we can edit in the middle of the text.
  4868. ## [DAY-91] Lists
  4869. list your favorite games, and rank them
  4870. ```
  4871. games = [
  4872. ["mario smash bros", 3],
  4873. ["mario party", 4],
  4874. ["super mario", 2]
  4875. ]
  4876. while True:
  4877. for game in games:
  4878. print(game[0])
  4879. what = input("which game are you interested in: ")
  4880. for game in games:
  4881. if what in game[0]:
  4882. print("i like " + game[0] + ", score: " + str(game[1]))
  4883. ```
  4884. print the lyrics of songs:
  4885. ```
  4886. songs = [
  4887. ["wellerman", """There once was a ship that put to sea
  4888. The name of the ship was the Billy of Tea
  4889. The winds blew up, her bow dipped down
  4890. Oh blow, my bully boys, blow (huh)
  4891. Soon may the Wellerman come
  4892. To bring us sugar and tea and rum
  4893. One day, when the tonguing is done
  4894. We'll take our leave and go"""],
  4895. ]
  4896. while True:
  4897. what = input("which song are you interested in: ")
  4898. for song in songs:
  4899. if what in song[0]:
  4900. print('-' * 40)
  4901. print(song[1])
  4902. print('-' * 40)
  4903. ```
  4904. ## [DAY-92] Command Line; Command Line Arguments; Files
  4905. Today is command line day.
  4906. > First quickly go back to the start and read about files and folders (directories).
  4907. The same way functions can get parameters, your program can get parameters as well, try this:
  4908. ```
  4909. import sys
  4910. print(sys.argv)
  4911. ```
  4912. save it as `a.py` and then run `python3 a.py hello those are paremeters` from the Terminal app, you will see `['a.py', 'hello', 'those', 'are', 'paremeters']`, sys.argv[0] is the name of the program, and then the parameters you gave it.
  4913. Now lets make few handy programs to help us with our command line:
  4914. ---
  4915. xcat.py
  4916. ```
  4917. import sys
  4918. x = open(sys.argv[1], "r")
  4919. data = x.read()
  4920. print(data)
  4921. ```
  4922. ---
  4923. xls.py
  4924. ```
  4925. import os
  4926. import sys
  4927. files = os.listdir(sys.argv[1])
  4928. files.sort()
  4929. for f in files:
  4930. if os.path.isdir(f):
  4931. print(f + "/")
  4932. else:
  4933. print(f)
  4934. ```
  4935. ---
  4936. xed.py
  4937. ```
  4938. import sys
  4939. import os
  4940. text = ''
  4941. filename = sys.argv[1]
  4942. try:
  4943. f = open(filename, "r")
  4944. text = f.read()
  4945. f.close()
  4946. except IOError:
  4947. pass
  4948. while True:
  4949. what = input("> ")
  4950. if what == '?':
  4951. print("""
  4952. * ? - help
  4953. * p - print
  4954. * s - save
  4955. * d [n] - delete last N lines
  4956. * a text - append text to the end
  4957. """)
  4958. elif what == 'q':
  4959. sys.exit(0)
  4960. elif what == 'p':
  4961. print(text, end = '')
  4962. elif what == 's':
  4963. f = open(filename, "w")
  4964. f.write(text)
  4965. f.close()
  4966. elif what[0] == 'a' and what[1] == ' ':
  4967. text += what[2:] + '\n'
  4968. elif what[0] == 'd':
  4969. lines = text.split('\n')
  4970. n = 1
  4971. if len(what) > 2:
  4972. n = int(what[2:])
  4973. for i in range(0, n):
  4974. lines.pop()
  4975. text = "\n".join(lines)
  4976. else:
  4977. print("* use ? for help")
  4978. ```
  4979. ---
  4980. OK now we have a text editor, a program to list files, and a program to print the file's content, now we can use our programs to write more programs :)
  4981. try this:
  4982. ```
  4983. $ python3 xed,py example.py
  4984. > a for i in range(100)
  4985. > a print(i)
  4986. > p
  4987. > s
  4988. $ python3 xls.py .
  4989. $ python3 xcat.py example.py
  4990. $ python3 example.py
  4991. ```
  4992. ## [DAY-93] PyDoc
  4993. Reading docs. type this in the terminal: `pydoc3 open` `pydoc3 input` `pydoc3 print` and `pydoc3 pgzero.actor`.
  4994. Lets take `open` as an example.
  4995. ```
  4996. Help on built-in function open in module io:
  4997. open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
  4998. Open file and return a stream. Raise OSError upon failure.
  4999. file is either a text or byte string giving the name (and the path
  5000. if the file isn't in the current working directory) of the file to
  5001. be opened or an integer file descriptor of the file to be
  5002. wrapped. (If a file descriptor is given, it is closed when the
  5003. returned I/O object is closed, unless closefd is set to False.)
  5004. mode is an optional string that specifies the mode in which the file
  5005. is opened. It defaults to 'r' which means open for reading in text
  5006. mode. Other common values are 'w' for writing (truncating the file if
  5007. it already exists), 'x' for creating and writing to a new file, and
  5008. 'a' for appending (which on some Unix systems, means that all writes
  5009. append to the end of the file regardless of the current seek position).
  5010. In text mode, if encoding is not specified the encoding used is platform
  5011. dependent: locale.getpreferredencoding(False) is called to get the
  5012. current locale encoding. (For reading and writing raw bytes use binary
  5013. mode and leave encoding unspecified.) The available modes are:
  5014. ========= ===============================================================
  5015. Character Meaning
  5016. --------- ---------------------------------------------------------------
  5017. 'r' open for reading (default)
  5018. 'w' open for writing, truncating the file first
  5019. 'x' create a new file and open it for writing
  5020. 'a' open for writing, appending to the end of the file if it exists
  5021. 'b' binary mode
  5022. 't' text mode (default)
  5023. '+' open a disk file for updating (reading and writing)
  5024. 'U' universal newline mode (deprecated)
  5025. ========= ===============================================================
  5026. The default mode is 'rt' (open for reading text). For binary random
  5027. access, the mode 'w+b' opens and truncates the file to 0 bytes, while
  5028. 'r+b' opens the file without truncation. The 'x' mode implies 'w' and
  5029. raises an `FileExistsError` if the file already exists.
  5030. Python distinguishes between files opened in binary and text modes,
  5031. even when the underlying operating system doesn't. Files opened in
  5032. binary mode (appending 'b' to the mode argument) return contents as
  5033. bytes objects without any decoding. In text mode (the default, or when
  5034. 't' is appended to the mode argument), the contents of the file are
  5035. returned as strings, the bytes having been first decoded using a
  5036. platform-dependent encoding or using the specified encoding if given.
  5037. 'U' mode is deprecated and will raise an exception in future versions
  5038. of Python. It has no effect in Python 3. Use newline to control
  5039. universal newlines mode.
  5040. buffering is an optional integer used to set the buffering policy.
  5041. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select
  5042. line buffering (only usable in text mode), and an integer > 1 to indicate
  5043. the size of a fixed-size chunk buffer. When no buffering argument is
  5044. given, the default buffering policy works as follows:
  5045. * Binary files are buffered in fixed-size chunks; the size of the buffer
  5046. is chosen using a heuristic trying to determine the underlying device's
  5047. "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`.
  5048. On many systems, the buffer will typically be 4096 or 8192 bytes long.
  5049. * "Interactive" text files (files for which isatty() returns True)
  5050. use line buffering. Other text files use the policy described above
  5051. for binary files.
  5052. encoding is the name of the encoding used to decode or encode the
  5053. file. This should only be used in text mode. The default encoding is
  5054. platform dependent, but any encoding supported by Python can be
  5055. passed. See the codecs module for the list of supported encodings.
  5056. errors is an optional string that specifies how encoding errors are to
  5057. be handled---this argument should not be used in binary mode. Pass
  5058. 'strict' to raise a ValueError exception if there is an encoding error
  5059. (the default of None has the same effect), or pass 'ignore' to ignore
  5060. errors. (Note that ignoring encoding errors can lead to data loss.)
  5061. See the documentation for codecs.register or run 'help(codecs.Codec)'
  5062. for a list of the permitted encoding error strings.
  5063. newline controls how universal newlines works (it only applies to text
  5064. mode). It can be None, '', '\n', '\r', and '\r\n'. It works as
  5065. follows:
  5066. * On input, if newline is None, universal newlines mode is
  5067. enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
  5068. these are translated into '\n' before being returned to the
  5069. caller. If it is '', universal newline mode is enabled, but line
  5070. endings are returned to the caller untranslated. If it has any of
  5071. the other legal values, input lines are only terminated by the given
  5072. string, and the line ending is returned to the caller untranslated.
  5073. * On output, if newline is None, any '\n' characters written are
  5074. translated to the system default line separator, os.linesep. If
  5075. newline is '' or '\n', no translation takes place. If newline is any
  5076. of the other legal values, any '\n' characters written are translated
  5077. to the given string.
  5078. If closefd is False, the underlying file descriptor will be kept open
  5079. when the file is closed. This does not work when a file name is given
  5080. and must be True in that case.
  5081. A custom opener can be used by passing a callable as *opener*. The
  5082. underlying file descriptor for the file object is then obtained by
  5083. calling *opener* with (*file*, *flags*). *opener* must return an open
  5084. file descriptor (passing os.open as *opener* results in functionality
  5085. similar to passing None).
  5086. open() returns a file object whose type depends on the mode, and
  5087. through which the standard file operations such as reading and writing
  5088. are performed. When open() is used to open a file in a text mode ('w',
  5089. 'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open
  5090. a file in a binary mode, the returned class varies: in read binary
  5091. mode, it returns a BufferedReader; in write binary and append binary
  5092. modes, it returns a BufferedWriter, and in read/write mode, it returns
  5093. a BufferedRandom.
  5094. It is also possible to use a string or bytearray as a file for both
  5095. reading and writing. For strings StringIO can be used like a file
  5096. opened in a text mode, and for bytes a BytesIO can be used like a file
  5097. opened in a binary mode.
  5098. ```
  5099. It's a lot! But I guarantee you its the best way to learn about something, the people who wrote the `open` function, wrote text to help anyone who is going to use it, describging what it does and how it behaves. It is always worth reading the docs of functions you are going to use. Sometimes they are not very good, but it is worth checking it out.
  5100. The other way find things is to google `python3 open` and you will usually see stackoverflow answers and maybe some examples, in many cases they will be incomplete or wrong, or pure scam 'pay 10$ to buy our video to learn how to use python3 open'
  5101. You can also do pydoc3 on modules, e.g. `pydoc3 sys` or `pydoc3 sys.argv`. Sometimes it might look a bit intimidating, but its usually much better than using google.
  5102. Try also `pydoc3 pgzero`, `pydoc3 pygame` and `pydoc3 pygame.Rect`. There is also a way to find documentation for the command line programs, try `man python3`, `man` from `manual`, if you want to search for something use `man -k something` for example `man -k python`.
  5103. ## [DAY-94] Editors - Ed/Nano/Vi/Emacs..
  5104. Command line editors:
  5105. * nano, pico
  5106. super easy to use, press ctrl+x to exit, ctrl+k to cut text, and ctrl+u to uncut (paste)
  5107. * vi
  5108. Type `vimtutor` to see how it works, to quit use `ESC` then type `:` and then `q!`
  5109. * emacs
  5110. emacs is my favorite editor, in in fact I am writing this book using it. type `ctrl+x ctrl+c` to quit, and `ctrl+x ctrl+s` to save.
  5111. * ed
  5112. ed is super old editor, it is somewhat similar to xed.py that you wrote, its called 'line editor'. To quit use `q` or `Q` if you want to quit without saving, to print the contents of the file use `1,$n` which prints the lines from 1 to $, or you can print specific line with `1n` or `2n` where 1 or 2 is the linue number.
  5113. try this:
  5114. ```
  5115. $ ed zzz
  5116. a
  5117. for i in range(10);
  5118. print(i)
  5119. .
  5120. w
  5121. 31
  5122. 1,$n
  5123. 1 for i in range(10);
  5124. 2 print(i)
  5125. q
  5126. ```
  5127. `a` will append to the file, `w` will save the file, `1,$n` will print the contents, and `q` will quit. Commands like `a,i,d` (append,insert,delete) take line numbers as parameters as well. Use `man ed` to see the docs.
  5128. I don't think anyone uses `ed` anymore, at least not as a text editor, but sometimes its handy to know how to use it.
  5129. ---
  5130. There are many many text editors, and some are better for you than others, but to me I dont really care, I want to type in my program and save it.. its not the end of the world if I use one or another editor.
  5131. So use the one you like most, but sometimes you will go on another computer and they wont have your editor there, so be be sure to be 'ok' with vim, nano or emacs, because they are on virtually any system.
  5132. ## [DAY-95] Memory; Virtual Computer; Instructions; Strings; Lists
  5133. Memory.
  5134. Lets make a huuuuuge list.
  5135. ```
  5136. memory = []
  5137. for i in range(1000000):
  5138. memory.append(0)
  5139. ```
  5140. Our memory looks like this:
  5141. ```
  5142. [0,0,0,..............0,0,0,0....0,0,0,0,0]
  5143. ```
  5144. Now we can make variables in this list of numbers, by addressing each variable with its index in the list, for exampke `x` can be at index 1000 and `y` can be at position 1001.
  5145. ```
  5146. def add(a_address,b_address):
  5147. return memory[a_address] + memory[b_address]
  5148. x_address = 1000
  5149. y_address = 1001
  5150. memory[x_address] = 5
  5151. memory[y_address] = 10
  5152. r = add(x_address,y_address)
  5153. print(r)
  5154. ```
  5155. This is cheating though, because python uses its own memory to store the result from x and y, lets fix that:
  5156. ```
  5157. def add(a_address,b_address,r_address):
  5158. memory[r_address] = memory[a_address] + memory[b_address]
  5159. x_address = 1000
  5160. memory[x_address] = 5
  5161. y_address = 1001
  5162. memory[y_address] = 10
  5163. r_address = 1002
  5164. add(x_address,y_address,r_address)
  5165. print(memory[r_address])
  5166. ```
  5167. This is how our memory looks like
  5168. ```
  5169. [....0,0,0,5,10,15,0,...]
  5170. ^ ^ ^
  5171. | | |
  5172. x | |
  5173. y |
  5174. r
  5175. x at index 1000
  5176. y at index 1001
  5177. r at index 1002
  5178. ```
  5179. The code above translates roughly to:
  5180. ```
  5181. x = 5
  5182. y = 10
  5183. r = x + y
  5184. print(r)
  5185. ```
  5186. How about strings? We can store strings by just defining how big the string is, and then follow with the characters of the string. You see how it is continous piece of memory.
  5187. ```
  5188. h_address = 2000
  5189. memory[h_address] = 5
  5190. memory[h_address+1] = ord('h')
  5191. memory[h_address+2] = ord('e')
  5192. memory[h_address+3] = ord('l')
  5193. memory[h_address+4] = ord('l')
  5194. memory[h_address+5] = ord('o')
  5195. def xprint(address):
  5196. l = memory[address]
  5197. for i in range(l):
  5198. # +1 is because of the length
  5199. c = memory[address + 1 + i]
  5200. print(chr(c), end = '')
  5201. print('')
  5202. ```
  5203. Strings with without length. We can also just say 'the string ends with 0' so start reading and stop when you see 0.
  5204. ```
  5205. n_address = 3000
  5206. memory[n_address+0] = ord('h')
  5207. memory[n_address+1] = ord('e')
  5208. memory[n_address+2] = ord('l')
  5209. memory[n_address+3] = ord('l')
  5210. memory[n_address+4] = ord('o')
  5211. def nprint(address):
  5212. for addr in range(address, len(memory)):
  5213. c = memory[addr]
  5214. if c == 0:
  5215. break
  5216. print(chr(c), end = '')
  5217. print('')
  5218. nprint(n_address)
  5219. ```
  5220. Now lets add a funciton to add two strings:
  5221. ```
  5222. a_address = 4000
  5223. memory[a_address] = 5
  5224. memory[a_address+1] = ord('h')
  5225. memory[a_address+2] = ord('e')
  5226. memory[a_address+3] = ord('l')
  5227. memory[a_address+4] = ord('l')
  5228. memory[a_address+5] = ord('o')
  5229. b_address = 4006
  5230. memory[b_address] = 5
  5231. memory[b_address+1] = ord('w')
  5232. memory[b_address+2] = ord('o')
  5233. memory[b_address+3] = ord('r')
  5234. memory[b_address+4] = ord('l')
  5235. memory[b_address+5] = ord('d')
  5236. c_address = 7000
  5237. def xadd(a,b,dst):
  5238. len_a = memory[a]
  5239. len_b = memory[b]
  5240. memory[dst] = len_a + len_b
  5241. for i in range(len_a):
  5242. c = memory[a + 1 + i]
  5243. memory[dst + 1 + i] = c
  5244. for i in range(len_b):
  5245. c = memory[b + 1 +i]
  5246. memory[dst + 1 + len_a + i] = c
  5247. xadd(a_address, b_address, c_address)
  5248. xprint(c_address)
  5249. ```
  5250. You see, the list is just a list with 1 million numbers, but we decide what those numbers mean, if we are reading a string, we *know* that the first number represents the length of the string, so its just an integer, but we know that the other numbers are actually characters.
  5251. ```
  5252. i_address = 3996
  5253. memory[i_address] = 9999
  5254. [....9999,0,0,0,5,104,101,108,108,111,5,119,111,114,108,100....]
  5255. ^ ^ ^
  5256. i this is a this is b
  5257. idx: 3996 idx: 4000 idx: 4006
  5258. ```
  5259. The memory doesnt care, string integers, characters,, its all the same. It doesn't know where one array ends or begins. You just read and write to specific address and thats all it cares about. *WHERE* to read and write.
  5260. Think about what it means to remove a character from our string, if its the last character we can sinply reduce the lengthm but lets say we want to remove 'o' from 'world', that would mean something like:
  5261. ```
  5262. world
  5263. * reduce the length to 4
  5264. * move r to the left
  5265. * move l to the left
  5266. * move d to the left
  5267. ```
  5268. You see we had to do 4 things to remove 1 character, and imagine if the string is 10000 chars long and we want to remove the first one, we wikl have to do 999 things, moving each character to the left.
  5269. In the same time, it is super easy to go to specific character, if I want to print the 3rd char, I can just do memory[address + 1 + 3] and thats it, add 1 because of the length and then add however many characters i want to skip.
  5270. There are different way to store collections of things, Linked Lists are one example
  5271. ```
  5272. [0, value] # w
  5273. |
  5274. [next_address, value] # o
  5275. |
  5276. [next_address, value] # r
  5277. |
  5278. [next_address, value] # l
  5279. |
  5280. [0, value ] # d
  5281. ```
  5282. Arrays and Lists are very differentm arrays are *always* continous, like strings, actually string is just an array of characters. Lists however can be on scattered amongst the memory, and each element can point to the next one.
  5283. So with a linked list it is hard to get to position 3 for example, because we have to start from the top, and go down until we see 3 elements, so we have to do 3 things to get to position 3, or 1000 things to get to position 1000. In the same time if we want to remove something, we can simply make it disappear, by making the previous element point to the next one, e.g. make `o` point to `l`, and then `r` will disappear.
  5284. Our format will be (next element from the list, value)
  5285. ```
  5286. memory[20000] = 30000
  5287. memory[20001] = 1
  5288. memory[30000] = 30500
  5289. memory[30001] = 2
  5290. memory[30500] = 30605
  5291. memory[30501] = 3
  5292. memory[30605] = 0
  5293. memory[30606] = 4
  5294. ```
  5295. the memory now looks like this:
  5296. ```
  5297. [ ....30000, 1, .... 30500, 2, .... 30605, 3, .... 0, 4, ...]
  5298. ^ ^ ^ ^
  5299. first second third forth element
  5300. ```
  5301. This is an example function that will print all the values in a linked list, following the links.
  5302. ```
  5303. def lprint(start_address):
  5304. done = False
  5305. while not done:
  5306. # check if this is the last element of the list
  5307. done = memory[start_address] == 0
  5308. # print the value at address + 1
  5309. print(memory[start_address+1])
  5310. # go to the next element from the list
  5311. start_address = memory[start_address]
  5312. lprint(20000)
  5313. ```
  5314. You see, having a flat area of memory is so powerfull! it doesnt know anything about what we store in it, so of course we can store pointers to other parts of the memory, we can have lists of lists of lists of lists that just point around, and of course we can have infinite loops, imagine a linked list where one of the elements points to a previous elemnent.
  5315. Check this out:
  5316. ```
  5317. memory[20000] = 30000
  5318. memory[20001] = 1
  5319. memory[30000] = 20000
  5320. memory[30001] = 2
  5321. lprint(20000)
  5322. ```
  5323. Inifinite loop! How cool is that!
  5324. ```
  5325. 1
  5326. 2
  5327. 1
  5328. 2
  5329. 1
  5330. 2
  5331. 1
  5332. 2
  5333. 1
  5334. 2
  5335. 1
  5336. 2
  5337. 1
  5338. 2
  5339. 1
  5340. 2
  5341. ```
  5342. Lets make a computer, it needs Memory and CPU, the CPU will read instructions from memory and produce results back in memory.
  5343. ```
  5344. memory = []
  5345. for i in range(1000000):
  5346. memory.append(0)
  5347. memory[1000] = 5 # a
  5348. memory[1001] = 10 # b
  5349. memory[1002] = 0 # result
  5350. # lets multiply a * b
  5351. # the code looks like this
  5352. # counter = b
  5353. # while counter > 0:
  5354. # r = r + a
  5355. # counter -= 1
  5356. # print(r)
  5357. # counter = b
  5358. memory[1003] = memory[1001]
  5359. # jump to position 10 if counter is 0
  5360. memory[0] = 4
  5361. memory[1] = 1003
  5362. memory[2] = 13
  5363. # r = r + a
  5364. memory[3] = 1
  5365. memory[4] = 1002
  5366. memory[5] = 1000
  5367. memory[6] = 1002
  5368. # since our add operation adds two things in memory, we
  5369. # need to store the value -1 somewhere to subtract it from the counter
  5370. #
  5371. # counter -= 1
  5372. memory[9999] = -1
  5373. memory[7] = 1
  5374. memory[8] = 1003
  5375. memory[9] = 9999
  5376. memory[10] = 1003
  5377. # go back to the if counter == 0 instruction
  5378. memory[11] = 5
  5379. memory[12] = 0
  5380. # print(r)
  5381. memory[13] = 3
  5382. memory[14] = 1002
  5383. # stop the program
  5384. memory[15] = 0
  5385. position = 0
  5386. while True:
  5387. instruction = memory[position]
  5388. print('instruction',instruction, 'position',position)
  5389. # quit if instruction is 0
  5390. if instruction == 0:
  5391. break
  5392. # add position+1 and position+2 and write result in position+3
  5393. elif instruction == 1:
  5394. a_address = memory[position+1]
  5395. b_address = memory[position+2]
  5396. r_address = memory[position+3]
  5397. memory[r_address] = memory[a_address] + memory[b_address]
  5398. position += 4
  5399. # print position + 1
  5400. elif instruction == 3:
  5401. address = memory[position+1]
  5402. print(memory[address])
  5403. position+=2
  5404. # if memory[position+1] is 0 jump to positon+2, else continue to position+3
  5405. elif instruction == 4:
  5406. address = memory[position+1]
  5407. if memory[address] == 0:
  5408. position = memory[position+2]
  5409. else:
  5410. position += 3
  5411. # jump to value of position+1
  5412. elif instruction == 5:
  5413. position = memory[position+1]
  5414. ```
  5415. start the computer and see the result!
  5416. ```
  5417. ('instruction', 4, 'position', 0)
  5418. ('instruction', 1, 'position', 3)
  5419. ('instruction', 1, 'position', 7)
  5420. ('instruction', 5, 'position', 11)
  5421. ('instruction', 4, 'position', 0)
  5422. ('instruction', 1, 'position', 3)
  5423. ('instruction', 1, 'position', 7)
  5424. ('instruction', 5, 'position', 11)
  5425. ('instruction', 4, 'position', 0)
  5426. ('instruction', 1, 'position', 3)
  5427. ('instruction', 1, 'position', 7)
  5428. ('instruction', 5, 'position', 11)
  5429. ('instruction', 4, 'position', 0)
  5430. ('instruction', 1, 'position', 3)
  5431. ('instruction', 1, 'position', 7)
  5432. ('instruction', 5, 'position', 11)
  5433. ('instruction', 4, 'position', 0)
  5434. ('instruction', 1, 'position', 3)
  5435. ('instruction', 1, 'position', 7)
  5436. ('instruction', 5, 'position', 11)
  5437. ('instruction', 4, 'position', 0)
  5438. ('instruction', 1, 'position', 3)
  5439. ('instruction', 1, 'position', 7)
  5440. ('instruction', 5, 'position', 11)
  5441. ('instruction', 4, 'position', 0)
  5442. ('instruction', 1, 'position', 3)
  5443. ('instruction', 1, 'position', 7)
  5444. ('instruction', 5, 'position', 11)
  5445. ('instruction', 4, 'position', 0)
  5446. ('instruction', 1, 'position', 3)
  5447. ('instruction', 1, 'position', 7)
  5448. ('instruction', 5, 'position', 11)
  5449. ('instruction', 4, 'position', 0)
  5450. ('instruction', 1, 'position', 3)
  5451. ('instruction', 1, 'position', 7)
  5452. ('instruction', 5, 'position', 11)
  5453. ('instruction', 4, 'position', 0)
  5454. ('instruction', 1, 'position', 3)
  5455. ('instruction', 1, 'position', 7)
  5456. ('instruction', 5, 'position', 11)
  5457. ('instruction', 4, 'position', 0)
  5458. ('instruction', 3, 'position', 13)
  5459. 50
  5460. ('instruction', 0, 'position', 15)
  5461. ```
  5462. Now lets get into variables from first principles, they are nothing but handy pointers to memory, that you can name yourself, and then you can access this memory by the name you chose.
  5463. This is the same program, but we are gonna use A, B, R, COUNTER and MINUS_1 as names for the specific addressess, and you can immidiately see how much cleaner the program looks. We will also name our instructions ADD, JUMP_IF_ZERO (or JZ), PRINT and HALT
  5464. ```
  5465. ...
  5466. # instructions
  5467. HALT = 0
  5468. ADD = 1
  5469. PRINT = 3
  5470. JUMP_IF_ZERO = 4
  5471. JUMP = 5
  5472. # variabnles
  5473. A = 1000
  5474. B = 1001
  5475. R = 1002
  5476. MINUS_1 = 9999
  5477. COUNTER = 1003
  5478. # program
  5479. memory[A] = 5 # A = 5
  5480. memory[B] = 10 # B = 5
  5481. memory[R] = 0 # R = 0
  5482. memory[COUNTER] = memory[B] # COUNTER = B
  5483. # jump to position 10 if counter is 0
  5484. memory[0] = JUMP_IF_ZERO
  5485. memory[1] = COUNTER
  5486. memory[2] = 13
  5487. # r = r + a
  5488. memory[3] = ADD
  5489. memory[4] = R
  5490. memory[5] = A
  5491. memory[6] = R
  5492. # counter -= 1
  5493. memory[MINUS_1] = -1
  5494. # counter = counter + minus_1
  5495. memory[7] = ADD
  5496. memory[8] = COUNTER
  5497. memory[9] = MINUS_1
  5498. memory[10] = COUNTER
  5499. # go back to the if counter == 0 instruction
  5500. memory[11] = JUMP
  5501. memory[12] = 0
  5502. # print(r)
  5503. memory[13] = PRINT
  5504. memory[14] = R
  5505. # stop the program
  5506. memory[15] = HALT
  5507. ...
  5508. ```
  5509. The whole program is actually quite small:
  5510. ```
  5511. [4, 1003, 13, 1, 1000, 1002, 1002, 1, 1003, 9999, 1003, 5, 0, 3, 1002, 0]
  5512. ^ ^
  5513. jump to 13 if memory[1003] is zero jump to 0
  5514. ```
  5515. ## [DAY-95] Memory; Machine Code; Virtual Computer
  5516. It will be super nice if our multiply program can be used from multiple places from a bigger program:
  5517. ```
  5518. ...
  5519. r = multiply(5, 10)
  5520. print(r)
  5521. ...
  5522. ```
  5523. We can kind of do that, by just using jump, and carefully writing the multiply function in such a way, that when it is done, to jump back to where we called it. We also have to give it some values to work with, in our case 5 and 10.
  5524. We will use a simple list to append the values and the return address, and then pop them out in the right order to use them. Our multiply function has to know how many values to read and it must know which one of them is the return address. `[5, 10, ZZZ]` imagine ZZZ is the address where we should return after we have computed the result. And then the function will just do POP, POP, POP and know, first POP will be ZZZ, second pop will be one parameter, third pop will be another parameter. Do what it does with the parameters, and then append its result into the stack, then the caller must know to POP it.
  5525. It is called a stack because it is like a stack of things on top of each other (cards for example), you can append(push) one to the top, or remove one from the top (pop). When we pop() we will remove the last thing we push()ed.
  5526. If I push 1,2,3 then if i pop 3 times I will print 3 2 1
  5527. ```
  5528. stack = [1,2,3]
  5529. print(stack.pop())
  5530. print(stack.pop())
  5531. print(stack.pop())
  5532. ```
  5533. Here is our updated program, and computer:
  5534. ```
  5535. memory = []
  5536. for i in range(1000000):
  5537. memory.append(0)
  5538. HALT = 0
  5539. ADD = 1
  5540. PRINT = 3
  5541. JUMP_IF_ZERO = 4
  5542. JUMP = 5
  5543. PUSH = 8
  5544. POP = 9
  5545. SET = 10
  5546. JUMPV = 11 # same as jump, but jumps to the
  5547. # value of the address instead of the address itself
  5548. # so jumpv 9, will jump to the value of memory[9]
  5549. PUSHV = 12 # same as jumpv but for push
  5550. # just used for debug
  5551. instruction_lookup = dict([
  5552. (HALT , 'HALT'),
  5553. (ADD , 'ADD'),
  5554. (PRINT , 'PRINT'),
  5555. (JUMP_IF_ZERO , 'JUMP_IF_ZERO'),
  5556. (JUMP , 'JUMP'),
  5557. (PUSH , 'PUSH'),
  5558. (POP , 'POP'),
  5559. (SET , 'SET'),
  5560. (PUSHV , 'PUSHV'),
  5561. (JUMPV , 'JUMPV')
  5562. ])
  5563. # pushv 9, will push memory[9] instead of 9
  5564. # constants addressess
  5565. # there is no such thing as constants though, we just think of them as such
  5566. MINUS_1 = 9999
  5567. # set "global" variable MINUS_1 to -1
  5568. memory[MINUS_1] = -1 # minus_1 = -1
  5569. # MAIN FUNCTION
  5570. # main function has only one variable, the MULTIPLY_RESULT
  5571. MULTIPLY_RESULT = 1000
  5572. # MULTIPLY_RESULT = multiply (5, 10)
  5573. memory[0] = PUSH # | |
  5574. memory[1] = 5 # ^ |
  5575. memory[2] = PUSH # |
  5576. memory[3] = 10 # >--+
  5577. memory[4] = PUSH # >-------------+
  5578. memory[5] = 8 # | after the function is called
  5579. memory[6] = JUMP # | jump to get the value
  5580. memory[7] = 198 # | from the stack
  5581. memory[8] = POP # <-------------+
  5582. memory[9] = MULTIPLY_RESULT #
  5583. memory[10] = PRINT
  5584. memory[11] = MULTIPLY_RESULT
  5585. ####### MULTIPLY FUNCTION ######
  5586. # get the value of A
  5587. A = 9000
  5588. B = 9001
  5589. COUNTER = 9003
  5590. R = 9004
  5591. BACK_TO_ADDRESS = 9005
  5592. # get the value for where to return to
  5593. memory[198] = POP
  5594. memory[199] = BACK_TO_ADDRESS
  5595. # get the value for A
  5596. memory[200] = POP
  5597. memory[201] = A
  5598. # get the value for B
  5599. memory[202] = POP
  5600. memory[203] = B
  5601. # COUNTER = B (which is counter = 0 ; counter = counter + b)
  5602. # COUNTER = 0
  5603. memory[204] = SET
  5604. memory[205] = COUNTER
  5605. memory[206] = 0
  5606. # COUNTER = COUNTER + B
  5607. memory[207] = ADD
  5608. memory[208] = COUNTER
  5609. memory[209] = B
  5610. memory[210] = COUNTER
  5611. # the actual loop
  5612. memory[211] = JUMP_IF_ZERO
  5613. memory[212] = COUNTER
  5614. memory[213] = 224
  5615. # r = r + a
  5616. memory[214] = ADD
  5617. memory[215] = A
  5618. memory[216] = R
  5619. memory[217] = R
  5620. # since our add operation adds two things in memory, we
  5621. # need to store the value -1 somewhere to subtract it from the counter
  5622. #
  5623. # counter -= 1
  5624. memory[218] = ADD
  5625. memory[219] = COUNTER
  5626. memory[220] = MINUS_1
  5627. memory[221] = COUNTER
  5628. # go back to the if counter == 0 instruction
  5629. memory[222] = JUMP
  5630. memory[223] = 211
  5631. # return(r)
  5632. memory[224] = PUSHV
  5633. memory[225] = R
  5634. memory[226] = JUMPV
  5635. memory[227] = BACK_TO_ADDRESS
  5636. # start the computer from position 80, we will use positions up-to 80 for our function call stack
  5637. position = 0
  5638. stack = []
  5639. while True:
  5640. instruction = memory[position]
  5641. print(instruction_lookup[instruction], 'position',position, 'stack', stack)
  5642. # quit if instruction is 0
  5643. if instruction == HALT:
  5644. break
  5645. # add position+1 and position+2 and write result in position+3
  5646. elif instruction == ADD:
  5647. a_address = memory[position+1]
  5648. b_address = memory[position+2]
  5649. r_address = memory[position+3]
  5650. memory[r_address] = memory[a_address] + memory[b_address]
  5651. position += 4
  5652. # print position + 1
  5653. elif instruction == PRINT:
  5654. address = memory[position+1]
  5655. print(memory[address])
  5656. position+=2
  5657. # if memory[position+1] is 0 jump to positon+2, else continue to position+3
  5658. elif instruction == JUMP_IF_ZERO:
  5659. address = memory[position+1]
  5660. if memory[address] == 0:
  5661. position = memory[position+2]
  5662. else:
  5663. position += 3
  5664. # jump to value of position+1
  5665. elif instruction == JUMP:
  5666. position = memory[position+1]
  5667. elif instruction == JUMPV:
  5668. position = memory[memory[position+1]]
  5669. elif instruction == PUSH:
  5670. stack.append(memory[position+1])
  5671. position += 2
  5672. elif instruction == PUSHV:
  5673. stack.append(memory[memory[position+1]])
  5674. position += 2
  5675. elif instruction == POP:
  5676. memory[memory[position+1]] = stack.pop()
  5677. position += 2
  5678. elif instruction == SET:
  5679. memory[position+1] = memory[position+2]
  5680. position += 3
  5681. ```
  5682. We cheated a bit by using python's lists instead of our own list to do the stack. We could reserve some memory (e.g. 100000 to 200000) and just push and pop the values there, memory[100000] will just say how many elements we have in the stack, and PUSH will do `memory[[memory[100000]] = value, memory[100000] += 1`, and pop will do `memory[100000] -= 1` and use `memory[memory[100000]]` as value.
  5683. You see how powerfull are continous pieces of memory? Arrays and Lists are how computers are built!
  5684. Look. In reallity more things happen, and actually normal machine code is easier than this, you can store values in temporary places called registers, and access them really fast and nobody actually writes code like that, we use languages such as Assembler to help us, and using assemblers we built other languages, such as C, and with C we built others, such as python, and then with python we build whole systems, like instagram or dropbox. You can of course build instagram with machine code if you want, it will just take incredible amount of time, and will be gazillion times more buggy. C is good at some things that python is not, and the other way around.
  5685. The one thing you have to remember, is whatever language you are using, whatever program you are looking at, it must have some memory, and some way of modifying that memory, and execute instructions over it.
  5686. There is no magic, it is all built on this. Built with few numbers in a block of memory.
  5687. Lets examine the output of the program, you see how the stack is empty, then we add 5, 10, and then 8 which will be used from the function to go back to us.
  5688. ```
  5689. PUSH position 0 stack-before [] stack-after [5]
  5690. PUSH position 2 stack-before [5] stack-after [5, 10]
  5691. PUSH position 4 stack-before [5, 10] stack-after [5, 10, 8]
  5692. JUMP position 6 stack-before [5, 10, 8] stack-after [5, 10, 8]
  5693. POP position 198 stack-before [5, 10, 8] stack-after [5, 10]
  5694. POP position 200 stack-before [5, 10] stack-after [5]
  5695. POP position 202 stack-before [5] stack-after []
  5696. SET position 204 stack-before [] stack-after []
  5697. ADD position 207 stack-before [] stack-after []
  5698. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5699. ADD position 214 stack-before [] stack-after []
  5700. ADD position 218 stack-before [] stack-after []
  5701. JUMP position 222 stack-before [] stack-after []
  5702. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5703. ADD position 214 stack-before [] stack-after []
  5704. ADD position 218 stack-before [] stack-after []
  5705. JUMP position 222 stack-before [] stack-after []
  5706. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5707. ADD position 214 stack-before [] stack-after []
  5708. ADD position 218 stack-before [] stack-after []
  5709. JUMP position 222 stack-before [] stack-after []
  5710. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5711. ADD position 214 stack-before [] stack-after []
  5712. ADD position 218 stack-before [] stack-after []
  5713. JUMP position 222 stack-before [] stack-after []
  5714. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5715. ADD position 214 stack-before [] stack-after []
  5716. ADD position 218 stack-before [] stack-after []
  5717. JUMP position 222 stack-before [] stack-after []
  5718. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5719. PUSHV position 224 stack-before [] stack-after [50]
  5720. JUMPV position 226 stack-before [50] stack-after [50]
  5721. POP position 8 stack-before [50] stack-after []
  5722. PRINT position 10 stack-before [] stack-after []
  5723. 50
  5724. HALT position 12 stack-before []
  5725. ```
  5726. We could do it the other way, first push the address to go back to, and then the values, which will be the same, we just have to decide, this is called a 'calling convention', convention is just the usuall way to do things. So each program on your computer obeys the calling convention, otherwise a chaos will arrive, imagine multiplying the return address by first paremeter and then returning to some random position in memory.
  5727. By now you can see how fragile this is, if one mistake is made, you can corrupt rest of the program, we can easilly write something into where the next instruciton is read, and make the computer halt, or go into infinite loop.
  5728. Sometimes we can find bugs in a program that we can exploit, if we can simply control the corruption, we can make it jump to somewhere where we have our own code, and then we can control what the program does.
  5729. ## [DAY-96] Binary; ASCII; Memory
  5730. Lets spend a day on bits and bytes.
  5731. One bit is the minimum amount of information you can hold, it is either 1 or 0, on or off. If we have a variable that has to store the heads or tails value of a coin, we can store it in 1 bit, lets say 1 is heads, 0 is tails. To store the values of two coins we can use 2 bits.
  5732. ```
  5733. 0 # tails
  5734. 1 # heads
  5735. ```
  5736. 2 possible
  5737. ```
  5738. 0 0 # both coins are tails
  5739. 0 1 # second coin is heads
  5740. 1 0 # first coin is heads
  5741. 1 1 # both coins are heads
  5742. ```
  5743. 2 * 2 possible
  5744. We have 4 distinct values, in 2 bits, lets try 3 coins
  5745. ```
  5746. 000
  5747. 001
  5748. 010
  5749. 011
  5750. 100
  5751. 101
  5752. 110
  5753. 111
  5754. ```
  5755. 2 * 2 * 2 possible
  5756. we have 8 distinct values in 3 bits, and in 4 bits we have 16 distinct values
  5757. ```
  5758. 0000
  5759. 0001
  5760. 0010
  5761. 0011
  5762. 0100
  5763. 0101
  5764. 0110
  5765. 0111
  5766. 1000
  5767. 1001
  5768. 1010
  5769. 1011
  5770. 1100
  5771. 1101
  5772. 1110
  5773. 1111
  5774. ```
  5775. 2 * 2 * 2 * 2 possible
  5776. in 32 bits we can store 4294967295 distinct values! and in 64 bits we can store 18446744073709551615.
  5777. But what about if we want to store the value of a dice? Possible values are 1 2 3 4 5 6. We can do that in just 3 bits.
  5778. 8 bits make a byte. Usually we need 1 bit of information for the sign of the number, is it - or +, so sometimes you will hear "signed integer" or "unsigned integer", and the difference is the unsigned integers get one more bit to work with, which is a big deal, if the integer is 4 bytes, that is 32 bits, the maximum possible numbmer for signed integer is 2147483647, and the minimum is -2147483647, but unsigned one is from 0 to 4294967295.
  5779. The reason is 2 * 2 * 2 * 2 * 2 * 2... 31 times is twice smaller than 2 * 2 * 2 * 2 ... 32 times.
  5780. We can also count in this system (called binary system) to make it represent numbers.
  5781. try this:
  5782. ```
  5783. for i in range(255):
  5784. print(i, ' -> ', format(i, '08b'))
  5785. ```
  5786. in python format can take a number and print it as binary number:
  5787. ```
  5788. 0 -> 00000000
  5789. 1 -> 00000001
  5790. 2 -> 00000010
  5791. 3 -> 00000011
  5792. 4 -> 00000100
  5793. 5 -> 00000101
  5794. 6 -> 00000110
  5795. 7 -> 00000111
  5796. 8 -> 00001000
  5797. 9 -> 00001001
  5798. 10 -> 00001010
  5799. 11 -> 00001011
  5800. 12 -> 00001100
  5801. 13 -> 00001101
  5802. 14 -> 00001110
  5803. 15 -> 00001111
  5804. 16 -> 00010000
  5805. ...
  5806. ```
  5807. the rules to count in the binary system are the same in the decimal system, when you go from 9 to 10 you increase the number of digits, but here.. you havbe to do it many more because you habe only 0 and 1.
  5808. so you start with 0, then 1, then you are out of numbers, so you add one more and then ext one is 1 0, then 1 1 and then you are out of space again, and go 1 0 0, 1 0 1, 1 1 0, 1 1 1 and so on.
  5809. So if you need to store the number `x = 47917437`, which in binary is 10110110110010100101111101, you will need 27 bits of space. However there are more limitations, you can usually store only 4 or 8 bytes (so 32 or 64 bits) because of the way the computer is made, so we will just pad it with zeros, and what will get stored on the memory chip is 0000010110110110010100101111101, and python will know the address of that, so when you say 'a = x + 1' it will go to the specific address, read the value, add one to it, and store it back.
  5810. example if we want to store `5, h e l l o`, the computer memory might look like this:
  5811. ```
  5812. 5 h e l l o
  5813. 5 104 101 108 108 111
  5814. 0,0,0,0,0,1,0,1, 0,1,1,0,1,0,0,0, 0,1,1,0,0,1,0,1, 0,1,1,0,1,1,0,0, 0,1,1,0,1,1,0,0, 0,1,1,0,1,1,1,1
  5815. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5816. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5817. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5818. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5819. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5820. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5821. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5822. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5823. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5824. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5825. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5826. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5827. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5828. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5829. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5830. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5831. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5832. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5833. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5834. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5835. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5836. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5837. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5838. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5839. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5840. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5841. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5842. ...
  5843. ```
  5844. If we use 1 byte per character, ASCII actuaklly fitst in 7 bits (its called 7 bit ascii) as the maximum value is 127, but we store things aligned to 1 byte, the way processors are made, they have certain restrictions,m they cant just go and read/write at a specific bit position in the memory, so many times when we want to store 7 bits of data we need to use 8 bits, Unless we come with something to store in the extra bit, it will be just waste.
  5845. ## [DAY-97] Lists;
  5846. ![game-97.png](./screenshots/game-97.png "game 97 screenshot")
  5847. Catch all the falling snakes.
  5848. Take this skeleton, and fill in the blanks.
  5849. ```
  5850. import pgzrun
  5851. import random
  5852. HEIGHT = 400
  5853. WIDTH = 300
  5854. falling = []
  5855. game_area = Rect(0,0,WIDTH,HEIGHT)
  5856. elf = Actor("c1")
  5857. elf.y = HEIGHT - 10
  5858. elf.x = WIDTH/2
  5859. game_over = False
  5860. def drop():
  5861. f = Actor("snake")
  5862. f.x = random.randint(0,WIDTH)
  5863. f.y = random.randint(0, 150)
  5864. falling.append(f)
  5865. def update():
  5866. global game_over
  5867. # move the elf left or right
  5868. ...
  5869. # detect the collisions between snakes and elf
  5870. # and remove them if they collide
  5871. ...
  5872. # advance the snakes downwards
  5873. ...
  5874. # check if the snakes are outside of the game area, and set game over
  5875. ...
  5876. # add new snakes if there are less than 5 on the screen
  5877. ...
  5878. def draw():
  5879. if game_over:
  5880. screen.fill('pink')
  5881. else:
  5882. screen.fill('black')
  5883. for f in falling:
  5884. f.draw()
  5885. screen.draw.rect(game_area, (255,0,0))
  5886. elf.draw()
  5887. pgzrun.go()
  5888. ```
  5889. This is one example of implementing it, can you think of another?
  5890. ```
  5891. import pgzrun
  5892. import random
  5893. HEIGHT = 400
  5894. WIDTH = 300
  5895. falling = []
  5896. game_area = Rect(0,0,WIDTH,HEIGHT)
  5897. elf = Actor("c1")
  5898. elf.y = HEIGHT - 10
  5899. elf.x = WIDTH/2
  5900. game_over = False
  5901. def drop():
  5902. f = Actor("snake")
  5903. f.x = random.randint(0,WIDTH)
  5904. f.y = random.randint(0, 150)
  5905. falling.append(f)
  5906. def update():
  5907. global game_over
  5908. # move the elf left or right
  5909. if keyboard.left:
  5910. elf.x = elf.x-5
  5911. if keyboard.right:
  5912. elf.x = elf.x+5
  5913. # detect the collisions between snakes and elf
  5914. # and remove them if they collide
  5915. remove = []
  5916. for f in falling:
  5917. if f.colliderect(elf):
  5918. remove.append(f)
  5919. for r in remove:
  5920. falling.remove(r)
  5921. # advance the snakes downwards
  5922. for f in falling:
  5923. f.y += 1
  5924. # check if the snakes are outside of the game area, and set game over
  5925. for f in falling:
  5926. if not f.colliderect(game_area):
  5927. game_over = True
  5928. # add new snakes if there are less than 5 on the screen
  5929. if len(falling) < 5:
  5930. drop()
  5931. def draw():
  5932. if game_over:
  5933. screen.fill('pink')
  5934. else:
  5935. screen.fill('black')
  5936. for f in falling:
  5937. f.draw()
  5938. screen.draw.rect(game_area, (255,0,0))
  5939. elf.draw()
  5940. pgzrun.go()
  5941. ```
  5942. Another possible implementation, this one uses `list()` to make a copy of the falling list and also has score and lives.
  5943. ```
  5944. import pgzrun
  5945. import random
  5946. HEIGHT = 400
  5947. WIDTH = 300
  5948. falling = []
  5949. game_area = Rect(0,0,WIDTH,HEIGHT)
  5950. elf = Actor("c1")
  5951. elf.y = HEIGHT - 10
  5952. elf.x = WIDTH/2
  5953. game_over = False
  5954. score = 0
  5955. lives = 5
  5956. def drop():
  5957. f = Actor("snake")
  5958. f.x = random.randint(0,WIDTH)
  5959. f.y = random.randint(0, 150)
  5960. falling.append(f)
  5961. def update():
  5962. global game_over, score, lives
  5963. if keyboard.A:
  5964. elf.x -= 5
  5965. if keyboard.D:
  5966. elf.x += 5
  5967. for i in falling:
  5968. i.y += 1
  5969. for i in list(falling):
  5970. if not i.colliderect(game_area):
  5971. falling.remove(i)
  5972. lives -= 1
  5973. game_over = lives <= 0
  5974. if len(falling) < 5:
  5975. drop()
  5976. for i in list(falling):
  5977. if i.colliderect(elf):
  5978. falling.remove(i)
  5979. score += 1
  5980. def draw():
  5981. if game_over:
  5982. screen.fill('pink')
  5983. else:
  5984. screen.fill('black')
  5985. screen.draw.text("score: " + str(score) + " lives: " + str(lives), topleft=(10,10))
  5986. for f in falling:
  5987. f.draw()
  5988. screen.draw.rect(game_area, (255,0,0))
  5989. elf.draw()
  5990. pgzrun.go()
  5991. ```
  5992. ## [DAY-98] Lists; Read/Write File
  5993. ![game-98-a.png](./screenshots/game-98-a.png "game 98-a screenshot")
  5994. ```
  5995. import pgzrun
  5996. import sys # for sys.exit()
  5997. HEIGHT = 300
  5998. WIDTH = 300
  5999. elf = Actor("c1")
  6000. colors = [
  6001. [(255,0,0), Rect(0,0,40,40)],
  6002. [(0,255,0), Rect(60,0,40,40)],
  6003. [(0,0,255), Rect(120,0,40,40)],
  6004. ]
  6005. color = None
  6006. pixels = []
  6007. def update():
  6008. global color, pixels
  6009. if keyboard.LEFT:
  6010. elf.x -= 2
  6011. if keyboard.RIGHT:
  6012. elf.x += 2
  6013. if keyboard.UP:
  6014. elf.y -= 2
  6015. if keyboard.DOWN:
  6016. elf.y += 2
  6017. if keyboard.Q:
  6018. sys.exit(0)
  6019. if keyboard.SPACE and color != None:
  6020. pixels.append([
  6021. color,
  6022. Rect(elf.x,elf.y,40,40)
  6023. ])
  6024. if keyboard.C:
  6025. pixels = []
  6026. color = None
  6027. if keyboard.D:
  6028. drop = Rect(elf.x,elf.y,40,40)
  6029. for p in list(pixels):
  6030. if drop.colliderect(p[1]):
  6031. pixels.remove(p)
  6032. for c in colors:
  6033. if elf.colliderect(c[1]):
  6034. color = c[0]
  6035. def draw():
  6036. screen.fill('black')
  6037. for c in colors:
  6038. screen.draw.filled_rect(c[1], c[0])
  6039. for p in pixels:
  6040. screen.draw.filled_rect(p[1], p[0])
  6041. if color != None:
  6042. screen.draw.rect(Rect(elf.x,elf.y,40,40), color)
  6043. elf.draw()
  6044. screen.draw.text(str(len(pixels)), topleft=(10,10))
  6045. pgzrun.go()
  6046. ```
  6047. Simple catch the flower game
  6048. ![game-98-b.png](./screenshots/game-98-b.png "game 98-b screenshot")
  6049. ```
  6050. import pgzrun
  6051. import sys # for sys.exit()
  6052. HEIGHT = 300
  6053. WIDTH = 300
  6054. elf = Actor("c1")
  6055. flower = Actor("flower")
  6056. def update():
  6057. if keyboard.LEFT:
  6058. elf.x -= 5
  6059. # add RIGHT/UP/DONW
  6060. if keyboard.Q:
  6061. sys.exit(0)
  6062. # check if the elf collides the flower
  6063. # and if it does, increment the score
  6064. # and place the flower on some random place
  6065. # ...
  6066. def draw():
  6067. screen.fill('black')
  6068. elf.draw()
  6069. flower.draw()
  6070. # show the score
  6071. # ...
  6072. pgzrun.go()
  6073. ```
  6074. Example implementation:
  6075. ```
  6076. import pgzrun
  6077. import random
  6078. import sys # for sys.exit()
  6079. HEIGHT = 300
  6080. WIDTH = 300
  6081. elf = Actor("c1")
  6082. elf.x = WIDTH/2
  6083. elf.y = HEIGHT/2
  6084. flower = Actor("flower")
  6085. flower.x = 10
  6086. flower.y = 10
  6087. score = 0
  6088. def update():
  6089. global score
  6090. if keyboard.LEFT:
  6091. elf.x -= 5
  6092. if keyboard.RIGHT:
  6093. elf.x += 5
  6094. if keyboard.UP:
  6095. elf.y -= 5
  6096. if keyboard.DOWN:
  6097. elf.y += 5
  6098. if keyboard.Q:
  6099. sys.exit(0)
  6100. if elf.colliderect(flower):
  6101. flower.x = random.randint(10,WIDTH-10)
  6102. flower.y = random.randint(10,HEIGHT-10)
  6103. score += 1
  6104. def draw():
  6105. screen.fill('black')
  6106. elf.draw()
  6107. flower.draw()
  6108. screen.draw.text(str(score), topleft=(10,10))
  6109. pgzrun.go()
  6110. ```
  6111. Same program but with Load and Save
  6112. ```
  6113. import pgzrun
  6114. import sys # for sys.exit()
  6115. HEIGHT = 300
  6116. WIDTH = 300
  6117. elf = Actor("c1")
  6118. colors = [
  6119. [(255,0,0), Rect(0,0,40,40)],
  6120. [(0,255,0), Rect(60,0,40,40)],
  6121. [(0,0,255), Rect(120,0,40,40)],
  6122. ]
  6123. color = None
  6124. pixels = []
  6125. def make_rect_around_actor(a):
  6126. return Rect(a.x,a.y,40,40)
  6127. def update():
  6128. global color, pixels
  6129. if keyboard.LEFT:
  6130. elf.x -= 2
  6131. if keyboard.RIGHT:
  6132. elf.x += 2
  6133. if keyboard.UP:
  6134. elf.y -= 2
  6135. if keyboard.DOWN:
  6136. elf.y += 2
  6137. if keyboard.Q:
  6138. sys.exit(0)
  6139. if keyboard.SPACE and color != None:
  6140. pixels.append([
  6141. color,
  6142. make_rect_around_actor(elf),
  6143. ])
  6144. if keyboard.C:
  6145. pixels = []
  6146. color = None
  6147. if keyboard.S:
  6148. f = open("save.txt", "w")
  6149. for p in pixels:
  6150. (red,green,blue) = p[0]
  6151. f.write(str(red))
  6152. f.write(",")
  6153. f.write(str(green))
  6154. f.write(",")
  6155. f.write(str(blue))
  6156. f.write(",")
  6157. f.write(str(p[1].x))
  6158. f.write(",")
  6159. f.write(str(p[1].y))
  6160. f.write(",")
  6161. f.write(str(p[1].width))
  6162. f.write(",")
  6163. f.write(str(p[1].height))
  6164. f.write("\n")
  6165. f.close()
  6166. if keyboard.L:
  6167. pixels = []
  6168. f = open("save.txt", "r")
  6169. lines = f.readlines()
  6170. for l in lines:
  6171. (red,green,blue,x,y,w,h) = l.split(",")
  6172. pixels.append([
  6173. (float(red),float(green),float(blue)),
  6174. Rect(float(x),float(y), float(w), float(h))
  6175. ])
  6176. f.close()
  6177. if keyboard.D:
  6178. drop = make_rect_around_actor(elf)
  6179. for p in list(pixels):
  6180. if drop.colliderect(p[1]):
  6181. pixels.remove(p)
  6182. for c in colors:
  6183. if elf.colliderect(c[1]):
  6184. color = c[0]
  6185. def draw():
  6186. screen.fill('black')
  6187. for c in colors:
  6188. screen.draw.filled_rect(c[1], c[0])
  6189. for p in pixels:
  6190. screen.draw.filled_rect(p[1], p[0])
  6191. if color != None:
  6192. screen.draw.rect(make_rect_around_actor(elf), color)
  6193. elf.draw()
  6194. screen.draw.text(str(len(pixels)), topleft=(10,10))
  6195. pgzrun.go()
  6196. ```
  6197. ## [DAY-99] Classes; Lists; Functions; Cartesian Coordinates
  6198. Today we talk about classes and instances.
  6199. Classes are a bit like the houses you buy in roblox, its just a recepie for a house, and when you buy it you can customize it.
  6200. If two people have houses made from the same blueprint, we call them instances, they are seperate entities, you can lock one and that does not mean the other is locked. One can have a couch the other one doesn't.
  6201. The blueprint or recipe we call 'class' and the real thing that comes out of it we call 'instance'.
  6202. The class can define functions, and those functions will take a magic `self` parameter, where `self` will be the instance. For example in roblox, the house probably has a function 'lock()' that does something like `self.is_locked = True`.
  6203. Those functions are called 'methods' and the instance is also called an object. A method is supposed to be a bit like a message to the object, `p.colliderect(r)` for example you can look at sending the message `colliderect` to the object `p` with parameter `r`. Or you can look at it just as a function with hidden `self` parameter. In the following example you can see a method `def colliderect(self,r)` in the Point class, and also a standalone function `def collidepoint(rect, point)` that just expects a rect and a point objects.
  6204. ```
  6205. class Point:
  6206. x = 0
  6207. y = 0
  6208. def __init__(self, name):
  6209. self.name = name
  6210. def print(self):
  6211. print('point',self.x,self.y,self.name)
  6212. def colliderect(self,r):
  6213. return self.x > r.x and self.x < r.x + r.w and self.y > r.y and self.y < r.y + r.h
  6214. class Rect:
  6215. x = 0
  6216. y = 0
  6217. w = 0
  6218. h = 0
  6219. def print(self):
  6220. print('rect',self.x,self.y,self.w,self.h)
  6221. #
  6222. # |-----------------------+
  6223. # | |
  6224. # 6 +-------+ |
  6225. # | | | |
  6226. # 4--|---x | |
  6227. # | | | | |
  6228. # 2--+-------+ |
  6229. # | | | | |
  6230. # +--2---6---9------------+
  6231. # 0,0
  6232. def collidepoint(rect, point):
  6233. if point.x > rect.x and point.x < rect.x + rect.w and point.y > rect.y and point.y < rect.y + rect.h:
  6234. return True
  6235. else:
  6236. return False
  6237. p = Point("blue") # instance
  6238. p.x = 6
  6239. p.y = 4
  6240. r = Rect() # instance
  6241. r.x = 2
  6242. r.y = 2
  6243. r.w = 7
  6244. r.h = 4
  6245. if collidepoint(r,p):
  6246. print("COLLIDES")
  6247. r.print()
  6248. p.print()
  6249. p2 = Point("red")
  6250. p2.x = 10
  6251. p2.y = 10
  6252. if not collidepoint(r,p2):
  6253. print("NO COLLISION")
  6254. r.print()
  6255. p.print()
  6256. if p.colliderect(r):
  6257. print("p collides")
  6258. ```
  6259. ```
  6260. import pgzrun
  6261. import sys # for sys.exit()
  6262. import random
  6263. HEIGHT = 600
  6264. WIDTH = 600
  6265. elf = Actor("c1")
  6266. speed = 3
  6267. back = []
  6268. def update():
  6269. global score
  6270. if keyboard.A:
  6271. elf.x -= speed
  6272. if keyboard.D:
  6273. elf.x += speed
  6274. if keyboard.W:
  6275. elf.y -= speed
  6276. if keyboard.S:
  6277. elf.y += speed
  6278. if keyboard.J:
  6279. f = Actor('flower')
  6280. f.x = elf.x
  6281. f.y = elf.y
  6282. back.append(f)
  6283. if keyboard.M:
  6284. f = open("save.txt", "w")
  6285. for x in back:
  6286. f.write(str(x.x))
  6287. f.write(",")
  6288. f.write(str(x.y))
  6289. f.write("\n")
  6290. f.close()
  6291. if keyboard.L:
  6292. f = open("save.txt", "r")
  6293. for line in f.readlines():
  6294. (x,y) = line.split(",") # 30,20
  6295. a = Actor('flower')
  6296. a.x = float(x)
  6297. a.y = float(y)
  6298. back.append(a)
  6299. f.close()
  6300. if keyboard.Q:
  6301. sys.exit(0)
  6302. def draw():
  6303. screen.fill('black')
  6304. for i in back:
  6305. i.draw()
  6306. elf.draw()
  6307. pgzrun.go()
  6308. ```
  6309. ![game-99.png](./screenshots/game-99.png "game 99 screenshot")
  6310. simpler painting game:
  6311. ```
  6312. import pgzrun
  6313. import sys # for sys.exit()
  6314. import random
  6315. HEIGHT = 600
  6316. WIDTH = 600
  6317. elf = Actor("c1")
  6318. speed = 3
  6319. back = []
  6320. def update():
  6321. global score
  6322. if keyboard.A:
  6323. elf.x -= speed
  6324. if keyboard.D:
  6325. elf.x += speed
  6326. if keyboard.W:
  6327. elf.y -= speed
  6328. if keyboard.S:
  6329. elf.y += speed
  6330. if keyboard.J:
  6331. f = Actor('flower')
  6332. f.x = elf.x
  6333. f.y = elf.y
  6334. back.append(f)
  6335. if keyboard.M:
  6336. f = open("save.txt", "w")
  6337. for x in back:
  6338. f.write(str(x.x))
  6339. f.write(",")
  6340. f.write(str(x.y))
  6341. f.write("\n")
  6342. f.close()
  6343. if keyboard.L:
  6344. f = open("save.txt", "r")
  6345. for line in f.readlines():
  6346. (x,y) = line.split(",") # 30,20
  6347. a = Actor('flower')
  6348. a.x = float(x)
  6349. a.y = float(y)
  6350. back.append(a)
  6351. f.close()
  6352. if keyboard.Q:
  6353. sys.exit(0)
  6354. def draw():
  6355. screen.fill('black')
  6356. for i in back:
  6357. i.draw()
  6358. elf.draw()
  6359. pgzrun.go()
  6360. ```
  6361. ## [DAY-100] Touch Typing; Lists
  6362. Day 100 party!
  6363. We will make another touch typing game
  6364. ![game-100.png](./screenshots/game-100.png "game 100 screenshot")
  6365. ```
  6366. import pgzrun
  6367. import random
  6368. HEIGHT = 400
  6369. WIDTH = 600
  6370. words = []
  6371. text = ''
  6372. game_over = False
  6373. beep = tone.create('A3', 0.5)
  6374. def move():
  6375. global game_over
  6376. for w in words:
  6377. w[1]+= random.randint(10,15)
  6378. if w[1] > HEIGHT:
  6379. game_over = True
  6380. def add_word():
  6381. common = ['a','about','all','also','and','as','at','be','because','but','by','can','come','could','day',
  6382. 'do','even','find','first','for','from','get','give','go','have','he','her','here','him','his',
  6383. 'how','i','if','in','into','it','its','just','know','like','look','make','man','many','me',
  6384. 'more','my','new','no','not','now','of','on','one','only','or','other','our','out','people',
  6385. 'say','see','she','so','some','take','tell','than','that','the','their','them','then','there',
  6386. 'these','they','thing','think','this','those','time','to','two','up','use','very','want','way',
  6387. 'we','well','what','when','which','who','will','with','would','year','you','your',
  6388. ]
  6389. words.append([random.randint(10,WIDTH-50), random.randint(10,HEIGHT/2), random.choice(common)])
  6390. def on_key_down(key, mod, unicode):
  6391. global text
  6392. if key == keys.BACKSPACE:
  6393. if len(text) > 0:
  6394. text = text[:-1]
  6395. elif len(unicode) > 0 and ord(unicode) >= 65 and ord(unicode) <= 125:
  6396. text += unicode
  6397. for w in list(words):
  6398. if w[2] == text:
  6399. words.remove(w)
  6400. text = ''
  6401. beep.play()
  6402. def draw():
  6403. if game_over:
  6404. screen.fill('pink')
  6405. else:
  6406. screen.fill('black')
  6407. for w in words:
  6408. screen.draw.text(w[2], (w[0],w[1]), fontsize=20,fontname="437-win")
  6409. screen.draw.text(text, (WIDTH/2,HEIGHT - 40), color=(255,0,0), fontsize=40,fontname="437-win")
  6410. for i in range(5):
  6411. add_word()
  6412. clock.schedule_interval(add_word, 2)
  6413. clock.schedule_interval(move, 1)
  6414. pgzrun.go()
  6415. ```
  6416. ghost!
  6417. ```
  6418. import random
  6419. score = 0
  6420. while True:
  6421. ghost = random.randint(1,3)
  6422. choice = input('Pick a door from 1,2, or 3: ')
  6423. if choice == str(ghost):
  6424. print ('there is a ghost :O GAME OVER !!!')
  6425. break
  6426. else:
  6427. score += 1
  6428. print('lucky no gosht')
  6429. print('your score is ' + str(score))
  6430. ```
  6431. ## [DAY-101] Functions; Strings
  6432. invert a list
  6433. ```
  6434. def invert(l):
  6435. #...
  6436. print(invert([1,2,3]))
  6437. ```
  6438. invert a string
  6439. ```
  6440. def invert(s):
  6441. #...
  6442. print(invert("hello"))
  6443. ```
  6444. invert a number
  6445. ```
  6446. def invert(n):
  6447. #...
  6448. print(invert(123456))
  6449. ```
  6450. Check if a string is a palindrome, a palindrome is a string that you can read backwards and it sounds the same.
  6451. ```
  6452. Anna
  6453. civic
  6454. kayak
  6455. level
  6456. madam
  6457. mom
  6458. noon
  6459. racecar
  6460. radar
  6461. redder
  6462. refer
  6463. repaper
  6464. rotator
  6465. rotor
  6466. sagas
  6467. solos
  6468. stats
  6469. tenet
  6470. wow
  6471. Never odd or even.
  6472. We panic in a pew.
  6473. Won’t lovers revolt now?
  6474. Don’t nod.
  6475. Sir, I demand, I am a maid named Iris.
  6476. Don't nod.
  6477. I did, did I?
  6478. Step on no pets.
  6479. Eva, can I see bees in a cave?
  6480. Was it a cat I saw?
  6481. ```
  6482. example:
  6483. ```
  6484. while True:
  6485. n = input("which string you want to check: )
  6486. if is_palindrome(n):
  6487. print(n + " is a palindrome")
  6488. else:
  6489. print(n + " is not a palindrome")
  6490. ```
  6491. # Chapter 14 - Week 14
  6492. ```
  6493. day0: Basics of Basics
  6494. day1: Basics of Basics
  6495. day2: Basics of Basics
  6496. day3: Basics of Basics
  6497. day4: Basics of Basics
  6498. day5: Basics of Basics
  6499. day6: Basics of Basics
  6500. ```
  6501. ## [DAY-102] Touch Typing day
  6502. Whole day touch typing!
  6503. Modify the program to print some score and words per minute, and try to improve your score.
  6504. ```
  6505. import pgzrun
  6506. import random
  6507. import time
  6508. HEIGHT = 800
  6509. WIDTH = 600
  6510. words = []
  6511. text = ''
  6512. game_over = False
  6513. beep = tone.create('A3', 0.5)
  6514. pause = False
  6515. score = 0
  6516. times = []
  6517. def words_per_minute():
  6518. if len(times) < 2:
  6519. return 0
  6520. return int(len(times) / ((times[-1] - times[0]) / 60.0))
  6521. def move():
  6522. global game_over
  6523. if pause:
  6524. return
  6525. for w in words:
  6526. w[1]+= random.randint(10,15)
  6527. if w[1] > HEIGHT:
  6528. game_over = True
  6529. def add_word():
  6530. if pause:
  6531. return
  6532. common = ['a','about','all','also','and','as','at','be','because','but','by','can','come','could','day',
  6533. 'do','even','find','first','for','from','get','give','go','have','he','her','here','him','his',
  6534. 'how','i','if','in','into','it','its','just','know','like','look','make','man','many','me',
  6535. 'more','my','new','no','not','now','of','on','one','only','or','other','our','out','people',
  6536. 'say','see','she','so','some','take','tell','than','that','the','their','them','then','there',
  6537. 'these','they','thing','think','this','those','time','to','two','up','use','very','want','way',
  6538. 'we','well','what','when','which','who','will','with','would','year','you','your',
  6539. 'paper','game','remember','person','english','dutch','amsterdam','nothing','sleep','product','natural',
  6540. 'juice','orange','blue','green','together','friends','between','music','book','bookstore','fish','complete',
  6541. 'width','weight','height','length','string','python','unicode','backspace','random','choice','string','integer',
  6542. 'function','print','print','print','for','range','range',
  6543. ]
  6544. w = random.choice(common)
  6545. words.append([random.randint(10,WIDTH-(len(w) * 15)), random.randint(10,int(HEIGHT/3)), w])
  6546. def on_key_down(key, mod, unicode):
  6547. global text, pause, score_words, score
  6548. if key == keys.BACKSPACE:
  6549. if len(text) > 0:
  6550. text = text[:-1]
  6551. elif key == keys.SPACE:
  6552. pause = not pause
  6553. elif len(unicode) > 0 and ord(unicode) >= 65 and ord(unicode) <= 125:
  6554. text += unicode
  6555. for w in list(words):
  6556. if w[2] == text:
  6557. score += 1
  6558. words.remove(w)
  6559. if len(words) < 4:
  6560. add_word()
  6561. text = ''
  6562. beep.play()
  6563. times.append(time.time())
  6564. def draw():
  6565. if game_over:
  6566. screen.fill('pink')
  6567. elif pause:
  6568. screen.fill('magenta')
  6569. else:
  6570. screen.fill('black')
  6571. screen.draw.text("score: " + str(score) + " wpm: " + str(words_per_minute()), (10,10), color=(0,255,0), fontsize=15,fontname="437-win")
  6572. for w in words:
  6573. screen.draw.text(w[2], (w[0],w[1]), fontsize=20,fontname="437-win")
  6574. screen.draw.text(text, (WIDTH/2,HEIGHT - 40), color=(255,0,0), fontsize=40,fontname="437-win")
  6575. for i in range(5):
  6576. add_word()
  6577. clock.schedule_interval(add_word, 5)
  6578. clock.schedule_interval(move, 5)
  6579. pgzrun.go()
  6580. ```
  6581. get more words with the characters you need to train from your dictionary file
  6582. use a simple program like this:
  6583. ```
  6584. import sys
  6585. need = ['k','l','i','o']
  6586. for line in sys.stdin:
  6587. missing = False
  6588. s = line.rstrip()
  6589. for n in need:
  6590. if n not in s:
  6591. missing = True
  6592. if not missing and len(s) <= 7:
  6593. print(s)
  6594. ```
  6595. and then get the list:
  6596. ```
  6597. cat /usr/share/dict/words | python3 words.py | tr "[A-Z]" "[a-z]" | sort | uniq | sed -e "s/^/'/g" -e "s/$/',/g" | pbcopy
  6598. ```
  6599. ## [DAY-103] Read File; Command Line Arguments
  6600. Search all the books!
  6601. First download https://www.gutenberg.org/cache/epub/feeds/pg_catalog.csv.zip, this is a list of all the books available from the gutenberg project.
  6602. Oh! the gutenberg project is absolutely amazing, they have more than 60000 books that have expired copyright.
  6603. ```
  6604. import csv
  6605. import sys
  6606. import argparse
  6607. parser = argparse.ArgumentParser()
  6608. parser.add_argument('--author', help='match author name')
  6609. parser.add_argument('--title', help='match title')
  6610. parser.add_argument('--subject', help='match subject')
  6611. args = parser.parse_args()
  6612. def show(id, title, authors, subjects, issued, language):
  6613. print(">>> " + title + " <<<")
  6614. print(" " + issued)
  6615. print(" https://www.gutenberg.org/ebooks/" + id)
  6616. print('')
  6617. for a in authors:
  6618. print(" Author: " + a)
  6619. print('')
  6620. for s in subjects:
  6621. print(" Subject: " + s)
  6622. print(" Language: " + language)
  6623. print("-" * 40)
  6624. file = open('pg_catalog.csv')
  6625. reader = csv.reader(file)
  6626. for row in reader:
  6627. # ['Text#', 'Type', 'Issued', 'Title', 'Language', 'Authors', 'Subjects', 'LoCC', 'Bookshelves']
  6628. id = row[0]
  6629. if id == "Text#":
  6630. # skip the first row (header)
  6631. continue
  6632. issued = row[2]
  6633. title = row[3].replace("\n","; ")
  6634. language = row[4]
  6635. authors = row[5].split("; ")
  6636. subjects = row[6].split("; ")
  6637. match = 0
  6638. need = 0
  6639. if args.title != None:
  6640. need += 1
  6641. if args.title in title:
  6642. match += 1
  6643. if args.subject != None:
  6644. need += 1
  6645. for s in subjects:
  6646. if args.subject in s:
  6647. match += 1
  6648. break
  6649. if args.author != None:
  6650. need += 1
  6651. for a in authors:
  6652. if args.author in a:
  6653. match += 1
  6654. break
  6655. if match == need:
  6656. show(id,title,authors,subjects,issued,language)
  6657. file.close()
  6658. ```
  6659. now try this:
  6660. ```
  6661. python3 search.py --title Alice --author Carroll | less
  6662. ```
  6663. CSV stands for comma separated value, its a neat way to encode a table, each column is separated by a `,`. Python has csv module in its standard library, and its very easy to load and parse csv files.
  6664. ## [DAY-104] Read File; Command Line Arguments; Dictionary
  6665. The previous approach can match only with substrings, for example we can not match "Lewis Carroll", because the author name is stored "Carroll, Lewis", in fact we can not even match on "Carroll Lewis" because we will be missing a comma.
  6666. Another way to search is if we actually split the strings, and then create an index of which word is contained in which books, very similar to whe you open the back of a book, you see a word(or a topic) and then pages at which it appears.
  6667. First just copy paste the program, and try to read it, we will go over it step by step later.
  6668. ```
  6669. import sys
  6670. import re
  6671. import json
  6672. def show(book):
  6673. id = book["id"]
  6674. title = book["title"]
  6675. authors = book["authors"]
  6676. subjects = book["subjects"]
  6677. issued = book["issued"]
  6678. language = book["language"]
  6679. print(">>> " + title + " <<<")
  6680. print(" " + issued)
  6681. print(" https://www.gutenberg.org/ebooks/" + str(id))
  6682. print('')
  6683. for a in authors:
  6684. print(" Author: " + a)
  6685. print('')
  6686. for s in subjects:
  6687. print(" Subject: " + s)
  6688. print(" Language: " + language)
  6689. print("-" * 40)
  6690. def parse(filename):
  6691. file = open(filename)
  6692. reader = csv.reader(file)
  6693. books = []
  6694. for row in reader:
  6695. # ['Text#', 'Type', 'Issued', 'Title', 'Language', 'Authors', 'Subjects', 'LoCC', 'Bookshelves']
  6696. if row[0] == "Text#":
  6697. # skip the first row (header)
  6698. continue
  6699. id = int(row[0])
  6700. issued = row[2]
  6701. title = row[3].replace("\n","; ")
  6702. language = row[4]
  6703. authors = row[5].split("; ")
  6704. subjects = row[6].split("; ")
  6705. book = {
  6706. "title": title,
  6707. "language": language,
  6708. "authors": authors,
  6709. "subjects": subjects,
  6710. "issued": issued,
  6711. "id": id
  6712. }
  6713. books.append(book)
  6714. file.close()
  6715. return books
  6716. def normalize(s):
  6717. # 'Alice's Adventures in Wonderland' -> 'alice's adventures in wonderland'
  6718. return s.lower()
  6719. def tokenize(s):
  6720. # 'alice's adventures in wonderland' -> ['alice','s','adventures','in','wonderland']
  6721. return re.split("[^\w+]",s)
  6722. def build_search_index(books):
  6723. index = {}
  6724. for i,book in enumerate(books):
  6725. tokens = set()
  6726. for token in tokenize(normalize(book["title"])):
  6727. k = "title:" + token
  6728. tokens.add(k)
  6729. for token in tokenize(normalize(book["language"])):
  6730. k = "language:" + token
  6731. tokens.add(k)
  6732. for author in book["authors"]:
  6733. for token in tokenize(normalize(author)):
  6734. k = "author:" + token
  6735. tokens.add(k)
  6736. for subject in book["subjects"]:
  6737. for token in tokenize(normalize(subject)):
  6738. k = "subject:" + token
  6739. tokens.add(k)
  6740. for t in tokens:
  6741. if not t in index:
  6742. index[t] = []
  6743. index[t].append(i)
  6744. return index
  6745. def search(books, index, query):
  6746. matching = None
  6747. for q in query:
  6748. if q in index:
  6749. if matching == None:
  6750. matching = set(index[q])
  6751. else:
  6752. matching.intersection_update(index[q])
  6753. else:
  6754. matching = set() # if one of the terms is not matching, return empty
  6755. result = []
  6756. if matching == None:
  6757. return result
  6758. for book_index in matching:
  6759. book = books[book_index]
  6760. result.append(book)
  6761. return result
  6762. if len(sys.argv) == 1:
  6763. print("usage:\n\t" + sys.argv[0] + " title:alice author:lewis")
  6764. sys.exit(1)
  6765. data = None
  6766. try:
  6767. f = open("search.json", mode="r")
  6768. data = json.load(f)
  6769. f.close()
  6770. except IOError:
  6771. books = parse("pg_catalog.csv")
  6772. search_index = build_search_index(books)
  6773. data = {}
  6774. data["search"] = search_index
  6775. data["books"] = books
  6776. f = open("search.json", mode="w")
  6777. json.dump(data,f)
  6778. f.close()
  6779. query = []
  6780. for arg in sys.argv[1:]:
  6781. query.append(normalize(arg))
  6782. for book in search(data["books"], data["search"], query):
  6783. show(book)
  6784. ```
  6785. lets try it:
  6786. ```
  6787. % python3 search.py title:Alice author:carroll author:lewis subject:children
  6788. >>> Alice's Adventures in Wonderland <<<
  6789. 2008-06-27
  6790. https://www.gutenberg.org/ebooks/11
  6791. Author: Carroll, Lewis, 1832-1898
  6792. Subject: Fantasy fiction
  6793. Subject: Children's stories
  6794. Subject: Imaginary places -- Juvenile fiction
  6795. Subject: Alice (Fictitious character from Carroll) -- Juvenile fiction
  6796. Language: en
  6797. ...
  6798. ```
  6799. The first time you search it will be slower, but then we will persist the search index on disk, in the search.json file, and then the second time it will be significantly faster because we will not have to do the work of parsing and building the index again, but directly load the precomputed index.
  6800. So many new concepts here, but the biggest one are maps and sets.
  6801. A map is a data structure (list is a data structure as well), that allows you to find something by a key you store it with.
  6802. ```
  6803. episodes = {}
  6804. episodes["naruto"] = 220
  6805. episodes["naruto shippuuden"] = 500
  6806. episodes["boruto"] = 215
  6807. print(episodes)
  6808. print(episodes["naruto"])
  6809. if "naruto" in episodes:
  6810. print("naruto is in the map")
  6811. for k in episodes:
  6812. print(k)
  6813. for k in episodes:
  6814. print(k, episodes[k])
  6815. ```
  6816. A set is a just a bag of things, for example when you put your toys in a bag, the bag is a set containing your toys. Lets make a set of flowers.
  6817. ```
  6818. flowers = set()
  6819. flowers.add("rose")
  6820. flowers.add("camomile")
  6821. flowers.add("tulip")
  6822. if "tulip" in flowers:
  6823. print("tulip is in the set")
  6824. for f in flowers:
  6825. print(f)
  6826. ```
  6827. You can `union` two sets of yoys by placing them into a new bag and this will contain both sets of toys, or you can `intersect` them by only taking toys that exist in both bags.
  6828. Both maps and sets are somewhat related, imagine a map that only contains keys.
  6829. This is very very shallow explanation, but will do for now, we will spend the next 3-4 months with sets and maps things will get clearer.
  6830. ## [DAY-105] Basics of Basics
  6831. make the simple flower/rock drawing game by yourself
  6832. ```
  6833. import pgzrun
  6834. import sys # for sys.exit()
  6835. HEIGHT = 300
  6836. WIDTH = 300
  6837. elf = Actor("c1")
  6838. flowers = []
  6839. def update():
  6840. if keyboard.A:
  6841. elf.x -= 5
  6842. if keyboard.D:
  6843. elf.x += 5
  6844. if keyboard.W:
  6845. elf.y -= 5
  6846. if keyboard.S:
  6847. elf.y += 5
  6848. if keyboard.F:
  6849. flower = Actor("flower")
  6850. flower.x = elf.x
  6851. flower.y = elf.y
  6852. flowers.append(flower)
  6853. if keyboard.R:
  6854. flower = Actor("rock")
  6855. flower.x = elf.x
  6856. flower.y = elf.y
  6857. flowers.append(flower)
  6858. if keyboard.Q:
  6859. sys.exit(0)
  6860. if elf.x < 0:
  6861. elf.x = 10
  6862. if elf.y < 0:
  6863. elf.y = 10
  6864. if elf.x > WIDTH:
  6865. elf.x = WIDTH - 10
  6866. if elf.y > HEIGHT:
  6867. elf.y = HEIGHT - 10
  6868. def draw():
  6869. screen.fill('black')
  6870. elf.draw()
  6871. for flower in flowers:
  6872. flower.draw()
  6873. pgzrun.go()
  6874. ```
  6875. ## [DAY-106] Read/Write File; Lists
  6876. Have some fun drawing, add more colors, change the size, enjoy!
  6877. ![game-106.png](./screenshots/game-106.png "game 106 screenshot")
  6878. ```
  6879. import pgzrun
  6880. import sys # for sys.exit()
  6881. HEIGHT = 800
  6882. WIDTH = 1000
  6883. elf = Actor("c1")
  6884. colors = [
  6885. [(255,0,0), Rect(0,0,40,40)],
  6886. [(0,255,0), Rect(60,0,40,40)],
  6887. [(0,0,255), Rect(120,0,40,40)],
  6888. [(0,128,128), Rect(180,0,40,40)],
  6889. [(0,191,255), Rect(240,0,40,40)],
  6890. [(255,215,0), Rect(300,0,40,40)],
  6891. ]
  6892. color = None
  6893. pixels = []
  6894. size = 40
  6895. def make_rect_around_actor(a):
  6896. return Rect(a.x,a.y,size,size)
  6897. def update():
  6898. global color, pixels,size
  6899. if keyboard.LEFT:
  6900. elf.x -= 2
  6901. if keyboard.RIGHT:
  6902. elf.x += 2
  6903. if keyboard.UP:
  6904. elf.y -= 2
  6905. if keyboard.DOWN:
  6906. elf.y += 2
  6907. if keyboard.MINUS:
  6908. size -= 1
  6909. if size < 1:
  6910. size = 1
  6911. if keyboard.EQUALS:
  6912. size += 1
  6913. if keyboard.Q:
  6914. sys.exit(0)
  6915. if keyboard.SPACE and color != None:
  6916. pixels.append([
  6917. color,
  6918. make_rect_around_actor(elf),
  6919. ])
  6920. if keyboard.C:
  6921. pixels = []
  6922. color = None
  6923. if keyboard.S:
  6924. f = open("save.txt", "w")
  6925. for p in pixels:
  6926. (red,green,blue) = p[0]
  6927. f.write(str(red))
  6928. f.write(",")
  6929. f.write(str(green))
  6930. f.write(",")
  6931. f.write(str(blue))
  6932. f.write(",")
  6933. f.write(str(p[1].x))
  6934. f.write(",")
  6935. f.write(str(p[1].y))
  6936. f.write(",")
  6937. f.write(str(p[1].width))
  6938. f.write(",")
  6939. f.write(str(p[1].height))
  6940. f.write("\n")
  6941. f.close()
  6942. if keyboard.L:
  6943. pixels = []
  6944. f = open("save.txt", "r")
  6945. lines = f.readlines()
  6946. for l in lines:
  6947. (red,green,blue,x,y,w,h) = l.split(",")
  6948. pixels.append([
  6949. (float(red),float(green),float(blue)),
  6950. Rect(float(x),float(y), float(w), float(h))
  6951. ])
  6952. f.close()
  6953. if keyboard.k_1:
  6954. color = colors[0][0]
  6955. if keyboard.k_2:
  6956. color = colors[1][0]
  6957. if keyboard.k_3:
  6958. color = colors[2][0]
  6959. if keyboard.k_4:
  6960. color = colors[3][0]
  6961. if keyboard.k_5:
  6962. color = colors[4][0]
  6963. if keyboard.k_6:
  6964. color = colors[5][0]
  6965. if keyboard.D:
  6966. drop = make_rect_around_actor(elf)
  6967. for p in list(pixels):
  6968. if drop.colliderect(p[1]):
  6969. pixels.remove(p)
  6970. for c in colors:
  6971. if elf.colliderect(c[1]):
  6972. color = c[0]
  6973. def draw():
  6974. screen.fill('black')
  6975. for c in colors:
  6976. screen.draw.filled_rect(c[1], c[0])
  6977. for p in pixels:
  6978. screen.draw.filled_rect(p[1], p[0])
  6979. if color != None:
  6980. screen.draw.rect(make_rect_around_actor(elf), color)
  6981. elf.draw()
  6982. screen.draw.text(str(len(pixels)), topleft=(10,10))
  6983. pgzrun.go()
  6984. ```
  6985. ## [DAY-107] Lists; Dictionaries
  6986. count the words in a file
  6987. ```
  6988. f = open("week-015.md","r")
  6989. count = []
  6990. for line in f.readlines():
  6991. for word in line.rstrip().split(" "):
  6992. found = False
  6993. for counted in count:
  6994. if counted[0] == word:
  6995. counted[1]+= 1
  6996. found = True
  6997. break
  6998. if not found:
  6999. count.append([word, 1])
  7000. f.close()
  7001. print(count)
  7002. ```
  7003. use a dictionary
  7004. ```
  7005. f = open("week-015.md","r")
  7006. count = {}
  7007. for line in f.readlines():
  7008. for word in line.rstrip().split(" "):
  7009. if word in count:
  7010. count[word] += 1
  7011. else:
  7012. count[word] = 1
  7013. f.close()
  7014. for k in count:
  7015. print(count[k], k)
  7016. ```
  7017. get the unique words in a file
  7018. ```
  7019. f = open("week-015.md","r")
  7020. unique = set()
  7021. for line in f.readlines():
  7022. for word in line.rstrip().split(" "):
  7023. unique.add(word)
  7024. f.close()
  7025. print(unique)
  7026. ```
  7027. lets read the file 1 byte at a time:
  7028. ```
  7029. f = open("week-015.md","r")
  7030. word = ''
  7031. count = {}
  7032. while True:
  7033. byte = f.read(1)
  7034. if not byte:
  7035. break
  7036. if byte == ' ' or byte == '\n':
  7037. if word in count:
  7038. count[word] += 1
  7039. else:
  7040. count[word] = 1
  7041. word = ''
  7042. else:
  7043. word += byte
  7044. f.close()
  7045. for k in count:
  7046. print(count[k], k)
  7047. ```
  7048. use sys.stdin to read the standard input
  7049. ```
  7050. import sys
  7051. count = {}
  7052. for line in sys.stdin.readlines():
  7053. for word in line.rstrip().split(" "):
  7054. if word in count:
  7055. count[word] += 1
  7056. else:
  7057. count[word] = 1
  7058. for k in count:
  7059. print(count[k], k)
  7060. ```
  7061. then try use the output of `cat` to print the contents of week-015.md and then `|` pipe it to your word counting program
  7062. ```
  7063. $ cat week-015.md | python3 count.py
  7064. ```
  7065. if you want to sort by most common words:
  7066. ```
  7067. cat week-015.md | python3 count.py | sort -n
  7068. ```
  7069. ## [DAY-108] Dictionaries
  7070. count how many times each character appears in a string
  7071. ```
  7072. line = "A quick brown fox jumps over the lazy dog"
  7073. count = {}
  7074. for s in line:
  7075. if s not in count:
  7076. count[s] = 1
  7077. else:
  7078. count[s] += 1
  7079. for s in count:
  7080. print(count[s], s)
  7081. ```
  7082. check if all characters from an alphabet are in a string
  7083. ```
  7084. alphabet = {
  7085. 'a': True,
  7086. 'b': True,
  7087. 'c': True,
  7088. 'd': True,
  7089. 'e': True,
  7090. 'f': True,
  7091. 'g': True,
  7092. 'h': True,
  7093. 'i': True,
  7094. 'j': True,
  7095. 'k': True,
  7096. 'l': True,
  7097. 'm': True,
  7098. 'n': True,
  7099. 'o': True,
  7100. 'p': True,
  7101. 'q': True,
  7102. 'r': True,
  7103. 's': True,
  7104. 't': True,
  7105. 'u': True,
  7106. 'v': True,
  7107. 'w': True,
  7108. 'x': True,
  7109. 'y': True,
  7110. 'z': True,
  7111. ' ': True,
  7112. }
  7113. line = "A quick brown fox jumps over the lazy dog"
  7114. for s in line:
  7115. lower_case = s.lower()
  7116. if lower_case not in alphabet:
  7117. print(lower_case + " is not in the alphabet")
  7118. break
  7119. ```
  7120. are two strings equal
  7121. ```
  7122. def equal(a,b):
  7123. if len(a) != len(b):
  7124. return False
  7125. for i in range(len(a)):
  7126. if a[i] != b[i]:
  7127. return False
  7128. return True
  7129. print(equal("hello","world"))
  7130. print(equal("hello","hello"))
  7131. print(equal("hello","roblox"))
  7132. ```
  7133. are two lists of integers equal:
  7134. ```
  7135. def equal(a,b):
  7136. if len(a) != len(b):
  7137. return False
  7138. for i in range(len(a)):
  7139. if a[i] != b[i]:
  7140. return False
  7141. return True
  7142. print(equal([1,2,3],[1,2,3,4]))
  7143. print(equal([1,2,3],[1,2,3]))
  7144. ```
  7145. are two dictionaries equal
  7146. ```
  7147. def equal(a,b):
  7148. for k in a:
  7149. if k not in b:
  7150. return False
  7151. if a[k] != b[k]:
  7152. return False
  7153. for k in b:
  7154. if k not in a:
  7155. return False
  7156. if b[k] != a[k]:
  7157. return False
  7158. return True
  7159. print(equal({'a':'hello','b':'world'},{'a':'hello','b':'world'}))
  7160. print(equal({'a':'hello','b':'world'},{'a':'hello','b':'earth'}))
  7161. print(equal({'a':'hello','roblox': True},{'a':'hello', 'roblox': False}))
  7162. print(equal({'a':'hello','b':'world','roblox': True},{'a':'hello','b':'world'}))
  7163. ```
  7164. ## [DAY-109] Touch Typing Day
  7165. Touchtyping day!
  7166. ## [DAY-110] Find Code on TikTok
  7167. ![game-109.png](./screenshots/game-109.png "game 109 screenshot")
  7168. follow zippycode on tiktok https://www.tiktok.com/@zippycode
  7169. try some of their ideas, like:
  7170. ```
  7171. from turtle import *
  7172. bgcolor('black')
  7173. n = 0
  7174. colormode(255)
  7175. while n < 200:
  7176. right(n)
  7177. forward(n*3)
  7178. color(n,255-n,n%30*8)
  7179. n+=1
  7180. ```
  7181. ```
  7182. from turtle import *
  7183. color('green')
  7184. speed(11)
  7185. i = 0
  7186. while True:
  7187. circle(i*1.5)
  7188. right(4)
  7189. i+=1
  7190. ```
  7191. ## [DAY-111] Lists; Random
  7192. ![game-110.png](./screenshots/game-110.png "game 110 screenshot")
  7193. ```
  7194. import pgzrun
  7195. import random
  7196. WIDTH = 400
  7197. HEIGHT = 400
  7198. fox = Actor("c1")
  7199. fox.x = WIDTH/2
  7200. fox.y =HEIGHT/2
  7201. other = [
  7202. Actor("c2", pos=(100,100)),
  7203. Actor("c2", pos=(100,300)),
  7204. Actor("c2",pos=(300,300)),
  7205. Actor("c2",pos=(300,100))
  7206. ]
  7207. def update():
  7208. if keyboard.left:
  7209. for o in other:
  7210. o.x += 5
  7211. if keyboard.right:
  7212. for o in other:
  7213. o.x -= 5
  7214. if keyboard.up:
  7215. for o in other:
  7216. o.y += 5
  7217. if keyboard.down:
  7218. for o in other:
  7219. o.y -= 5
  7220. for o in list(other):
  7221. if o.colliderect(fox):
  7222. other.remove(o)
  7223. if len(other) < 4:
  7224. other.append(Actor("c2",pos=(random.randint(10,WIDTH-10), random.randint(10,HEIGHT-10))))
  7225. for o in other:
  7226. o.y -=1
  7227. def draw():
  7228. screen.clear()
  7229. screen.fill("deepskyblue")
  7230. fox.draw()
  7231. for o in other:
  7232. o.draw()
  7233. pgzrun.go()
  7234. ```
  7235. ## [DAY-112] Use Simple Dictionary
  7236. Count the words in a song
  7237. ```
  7238. song = """There once was a ship that put to sea
  7239. The name of the ship was the Billy of Tea
  7240. The winds blew up, her bow dipped down
  7241. O blow, my bully boys, blow (huh)
  7242. She had not been two weeks from shore
  7243. When down on her a right whale bore
  7244. The captain called all hands and swore
  7245. He'd take that whale in tow (huh)
  7246. Soon may the Wellerman come
  7247. To bring us sugar and tea and rum (hey)
  7248. One day, when the tonguin' is done
  7249. We'll take our leave and go
  7250. Take our leave and go
  7251. Soon may the Wellerman come
  7252. To bring us sugar and tea and rum
  7253. One day, when the tonguin' is done
  7254. We'll take our leave and go
  7255. Before the boat had hit the water
  7256. The whale's tail came up and caught her
  7257. All hands to the side harpooned and fought her
  7258. When she dived down below (huh)
  7259. She had not been two weeks from shore
  7260. When down on her a right whale bore
  7261. The captain called all hands and swore
  7262. He'd take that whale in tow (huh)
  7263. Soon may the Wellerman come
  7264. To bring us sugar and tea and rum (hey)
  7265. One day, when the tonguin' is done
  7266. We'll take our leave and go
  7267. Take our leave and go
  7268. Soon may the Wellerman come
  7269. To bring us sugar and tea and rum
  7270. One day, when the tonguin' is done
  7271. We'll take our leave and go
  7272. Soon may the Wellerman come
  7273. To bring us sugar and tea and rum (hey)
  7274. One day, when the tonguin' is done
  7275. We'll take our leave and go
  7276. Take our leave and go
  7277. Take our leave and go
  7278. """
  7279. words = {}
  7280. word = ''
  7281. for c in song:
  7282. if c == ' ' or c == '\n':
  7283. if word not in words:
  7284. words[word] = 1
  7285. else:
  7286. words[word] += 1
  7287. word = ''
  7288. else:
  7289. word += c
  7290. for word in words:
  7291. print(words[word],word)
  7292. ```
  7293. This program has a bug, if the file does not end with empty line, it wont count the last word.
  7294. Print the length:
  7295. ```
  7296. ...
  7297. l = 0
  7298. for c in song:
  7299. l += 1
  7300. print(l)
  7301. print(len(song))
  7302. ```
  7303. ## [DAY-113] Discover Pythontutor
  7304. use https://pythontutor.com/visualize.html with the folloowing code:
  7305. ```
  7306. song = """Soon may the Wellerman come
  7307. To bring us sugar and tea and rum (hey)
  7308. One day, when the tonguin' is done
  7309. We'll take our leave and go
  7310. Take our leave and go
  7311. Soon may the Wellerman come
  7312. To bring us sugar and tea and rum (hey)
  7313. One day, when the tonguin' is done
  7314. """
  7315. words = {}
  7316. word = ''
  7317. for c in song:
  7318. if c == ' ' or c == '\n':
  7319. if word not in words:
  7320. words[word] = 1
  7321. else:
  7322. words[word] += 1
  7323. word = ''
  7324. else:
  7325. word += c
  7326. for word in words:
  7327. print(words[word],word)
  7328. ```
  7329. ![game-113-a.png](./screenshots/game-113-a.png "game 113-a screenshot")
  7330. ![game-113-b.png](./screenshots/game-113-b.png "game 113-b screenshot")
  7331. try it with other programs as well.
  7332. ## [DAY-114] Simple Turtle
  7333. ![game-114.png](./screenshots/game-114.png "game 114 screenshot")
  7334. random walk
  7335. ```
  7336. from turtle import *
  7337. from random import randint,choice
  7338. colors = ['red','deepskyblue','lawngreen']
  7339. screen = Screen()
  7340. width, height = screen.window_width(), screen.window_height()
  7341. pensize(5)
  7342. speed(20)
  7343. while True:
  7344. pencolor(choice(colors))
  7345. setheading(randint(0,360))
  7346. forward(randint(1,100))
  7347. (x,y) = pos()
  7348. if x > width/2 or y > height/2 or x < -width/2 or y < -height/2:
  7349. setpos(0,0)
  7350. ```
  7351. ## [DAY-115] Practical Coding, Control Roblox with python
  7352. ![game-115.png](./screenshots/game-115.jpg "game 115 screenshot")
  7353. Control Roblox with python
  7354. NB: That might be considered cheating, even though its just for fun, so be ready to get your account banned.
  7355. First `pip install pyautogui` and `pip install pydirectinput`.
  7356. ```
  7357. import pyautogui
  7358. import pydirectinput
  7359. import time
  7360. time.sleep(2)
  7361. while True:
  7362. for key in ['w','a','s','d']:
  7363. print('executing',key)
  7364. pydirectinput.keyDown(key)
  7365. time.sleep(1.6)
  7366. pydirectinput.keyUp(key)
  7367. time.sleep(0.5)
  7368. ```
  7369. This is a simple program that presses w a s d, each for 1.6 seconds and then waits 0.5 seconds for the next one.
  7370. After you start the program, you have 2 seconds to click on Roblox otherwise the sequence will be wrong
  7371. ## [DAY-116] Many Turtles
  7372. Many Turtles.
  7373. The ideas are borrowed from [Redisovering Logo with Bob the Turtle](https://notes.ayushsharma.in/2019/06/rediscovering-logo-with-bob-the-turtle), Ayush Sharma's amazing blog post!
  7374. ![game-116-a.png](./screenshots/game-116-a.png "game 116-a screenshot")
  7375. ```
  7376. import turtle
  7377. turtle.setup(width=800, height=800)
  7378. bob = turtle.Turtle(shape='turtle')
  7379. bob.color('orange')
  7380. bob.speed(3000)
  7381. alice = turtle.Turtle(shape='turtle')
  7382. alice.color('lawngreen')
  7383. alice.speed(3000)
  7384. for i in range(500):
  7385. bob.forward(i)
  7386. bob.left(91)
  7387. alice.backward(i)
  7388. alice.right(91)
  7389. turtle.exitonclick()
  7390. ```
  7391. even more turtles
  7392. ![game-116-b.png](./screenshots/game-116-b.png "game 116-b screenshot")
  7393. ```
  7394. import turtle
  7395. turtle.setup(width=800, height=800)
  7396. bob = turtle.Turtle(shape='turtle')
  7397. bob.color('orange')
  7398. bob.speed(3000)
  7399. alice = turtle.Turtle(shape='turtle')
  7400. alice.color('lawngreen')
  7401. alice.speed(3000)
  7402. charlie = turtle.Turtle(shape='turtle')
  7403. charlie.color('deepskyblue')
  7404. charlie.speed(3000)
  7405. for i in range(500):
  7406. bob.forward(i)
  7407. bob.left(91)
  7408. alice.backward(i)
  7409. alice.right(91)
  7410. charlie.forward(i)
  7411. charlie.right(101)
  7412. turtle.exitonclick()
  7413. ```
  7414. ```
  7415. import turtle
  7416. turtle.setup(width=800, height=800)
  7417. bob = turtle.Turtle(shape='turtle')
  7418. bob.color('orange')
  7419. alice = turtle.Turtle(shape='turtle')
  7420. alice.color('lawngreen')
  7421. angle = 10
  7422. while True:
  7423. alice.backward(20)
  7424. bob.forward(20)
  7425. alice.right(angle)
  7426. bob.left(angle)
  7427. angle += 1
  7428. ```
  7429. Again this is the same as in roblox's houses, you have the blueprint of the house, and you can create an instance of it, and then you can modify it. so `turtle.Turtle()` creates an instance, and then you see, bob, alice and charlie have their own changes. In the same time they have the same functionality, like `forward` `up` and etc coming from the blueprint and each of those methods work on the instance itself.
  7430. ## [DAY-117] Another Text Editor
  7431. ![game-117.png](./screenshots/game-117.png "game 117 screenshot")
  7432. And lets discuss another text editor.
  7433. (if you are on windows make sure you `pip3 install windows-curses`)
  7434. Start super simple, what do we need to make a text editor? first we need to show the text being edited, and second we need to capture user input and modify this text.
  7435. First show some text:
  7436. ```
  7437. import curses
  7438. import time
  7439. screen = curses.initscr()
  7440. screen.addstr(0, 0, "hello world",curses.A_NORMAL)
  7441. screen.refresh()
  7442. time.sleep(2)
  7443. ```
  7444. Capture input and modify the text:
  7445. ```
  7446. import curses
  7447. screen = curses.initscr()
  7448. text = ''
  7449. while True:
  7450. screen.addstr(0, 0, text,curses.A_NORMAL)
  7451. screen.refresh()
  7452. c = screen.getch()
  7453. text += chr(c)
  7454. ```
  7455. In order to Read and Write the file we are editing, we need to have some control keys, like Ctrl+S to save, and Ctrl+C to quit without saving. Also we need to add support for backspace to be able to delete from the text string.
  7456. Hint: use `text += str(c)` to actually see the codes you need.
  7457. ```
  7458. import curses
  7459. import sys
  7460. screen = curses.initscr()
  7461. curses.curs_set(2)
  7462. if len(sys.argv) != 2:
  7463. print("usage:")
  7464. print(sys.argv[0] + " filename")
  7465. sys.exit(1)
  7466. text = ''
  7467. try:
  7468. file = open(sys.argv[1],"r")
  7469. text = file.read()
  7470. file.close()
  7471. except:
  7472. pass
  7473. status = 'file: ' + sys.argv[1]
  7474. while True:
  7475. screen.clear()
  7476. screen.addstr(0, 0, status + ' (len: ' + str(len(text)) + ')',curses.A_NORMAL)
  7477. screen.addstr(2, 0, text,curses.A_NORMAL)
  7478. screen.refresh()
  7479. c = screen.getch()
  7480. if c == 3:
  7481. # quit Ctrl+C
  7482. break
  7483. if c == 19:
  7484. # save Ctrl+S
  7485. file = open(sys.argv[1],"w")
  7486. file.write(text)
  7487. file.close()
  7488. status = 'file: ' + sys.argv[1]
  7489. screen.addstr(0, 0, text,curses.A_NORMAL)
  7490. continue
  7491. if c == 8:
  7492. # backspace
  7493. if len(text) > 0:
  7494. text = text[:len(text)-1]
  7495. continue
  7496. if (c < 127 and c > 30) or c == 10:
  7497. text += chr(c)
  7498. status = 'file: ' + sys.argv[1] + " (modified)"
  7499. ```
  7500. ## [DAY-118] Search Lyrics
  7501. Search for your favorite lyrics, dont forget to `pip3 install lyricsgenius`
  7502. ```
  7503. import lyricsgenius
  7504. genius = lyricsgenius.Genius('get api key from genius.com')
  7505. genius.verbose = False
  7506. while True:
  7507. artist = input("🔥 Artist: ")
  7508. song_name = input("🔥 Song: ")
  7509. song = genius.search_song(song_name, artist)
  7510. if song == None:
  7511. print(song_name + " / " + artist + " not found")
  7512. else:
  7513. print('-' * 40)
  7514. print(song.lyrics)
  7515. print('-' * 40)
  7516. ```
  7517. ## [DAY-119] Facial Recognition; Move 78
  7518. ![game-119.png](./screenshots/game-119.png "game 119 screenshot")
  7519. Use https://github.com/ageitgey/face_recognition to see how easy it is to track people through a video stream only using 1 picture from them.
  7520. Recognize that if it is cheap and easy, it is done to you.
  7521. It will be done in the mall, to show you personalized ads, it will be done on the street to track where you go so they can sell you better things on tiktok.
  7522. They only need 1 picture.
  7523. If you are not paying, you are the product.
  7524. It is also not very easy to be tricked with mascara.
  7525. ![game-119-a.png](./screenshots/game-119-a.png "game 119a screenshot")
  7526. ![game-119-b.png](./screenshots/game-119-b.png "game 119b screenshot")
  7527. ![game-119-c.png](./screenshots/game-119-c.png "game 119c screenshot")
  7528. even thought it was easy in 2014, https://www.theatlantic.com/technology/archive/2014/07/makeup/374929/
  7529. ## [DAY-120] Program on your own form a book
  7530. Today you are on your own. We start with: https://www.amazon.de/-/en/DK/dp/1465461884 chapter 2, read it for 1 hour and make the programs and exercieses.
  7531. Write down your experience and what you struggle with.
  7532. Simple ping pong game
  7533. ```
  7534. import pgzrun
  7535. import random
  7536. HEIGHT = 600
  7537. WIDTH = 600
  7538. elf = Actor('c1')
  7539. king = Actor('c2')
  7540. ball = Actor('bullet')
  7541. king.y = HEIGHT/2
  7542. elf.y = HEIGHT/2
  7543. elf.x = WIDTH-10
  7544. ball.x = WIDTH/2
  7545. ball.y = HEIGHT/2
  7546. d = 1
  7547. game_over = False
  7548. speed = 1
  7549. def update():
  7550. global d,game_over,speed
  7551. if keyboard.up:
  7552. elf.y -= 5
  7553. if keyboard.down:
  7554. elf.y += 5
  7555. if keyboard.S:
  7556. king.y += 5
  7557. if keyboard.W:
  7558. king.y -= 5
  7559. if ball.x < 0 or ball.x > WIDTH:
  7560. game_over = True
  7561. if d == 1:
  7562. ball.x += speed
  7563. else:
  7564. ball.x -= speed
  7565. if elf.colliderect(ball):
  7566. d = 0
  7567. ball.y = random.randint(10,HEIGHT-10)
  7568. speed += 1
  7569. if king.colliderect(ball):
  7570. d = 1
  7571. ball.y = random.randint(10,HEIGHT-10)
  7572. speed += 1
  7573. def draw():
  7574. screen.clear()
  7575. screen.fill("deepskyblue")
  7576. elf.draw()
  7577. king.draw()
  7578. ball.draw()
  7579. if game_over:
  7580. screen.fill('red')
  7581. pgzrun.go()
  7582. ```
  7583. ## [DAY-121] Scam Check List
  7584. Scams.. Scams everywhere.
  7585. Our phone numbers, names, address are everywhere we have registered to buy something, be it bol.com, amazon, some random website we bought fidgets from, etc. So people can find out your number and name also by stealing your friends's contact list, Overall you must assume the bad guys have your information, so when you receive a call or email or even people talk to you on the street, always think sus.
  7586. Follow this list:
  7587. * Always Think Sus
  7588. * Call your parents
  7589. * If you cant reach your parents, call adult you know
  7590. * If you cant reach adult you know, go and find a mother with a child, they are the safest to talk to.
  7591. * If you can not find any adult to help hang up.
  7592. * If you think it is serious and you must act, hang up, and *you* call wherever they claim to be calling from. For example if they say they are from your bank, or from roblox, or fortnite, you google and find a contact for your bank/fortnite and *you* call them and ask what is going on.
  7593. The scammers are very smart, and have a lot of experience to trick you into doing what they want, sometimes they will call claiming your parents are in trouble and you have to give them a credit card number, sometimes they will call to tell you you win the new iPhone if you just give them a credit card number. They are very inventive as well, so the best thing is just think sus.
  7594. ## [DAY-122] Lists; Random; Mutate
  7595. Hide and Seek
  7596. Ask someone to count to 10, then you hide, and ask him to find you
  7597. ![game-122-a.png](./screenshots/game-122-a.png "game 122a screenshot")
  7598. ```
  7599. import pgzrun
  7600. import random
  7601. HEIGHT = 600
  7602. WIDTH = 600
  7603. elf = Actor('c1')
  7604. elf.x = 20
  7605. elf.y = random.randint(0,HEIGHT)
  7606. def update():
  7607. if keyboard.UP:
  7608. elf.y -= 5
  7609. if keyboard.DOWN:
  7610. elf.y += 5
  7611. if keyboard.RIGHT:
  7612. elf.x += 5
  7613. if keyboard.LEFT:
  7614. elf.x -= 5
  7615. def draw():
  7616. elf.draw()
  7617. pgzrun.go()
  7618. ```
  7619. ![game-122-b.png](./screenshots/game-122-b.png "game 122b screenshot")
  7620. Practice walking over a list with `for i in range(len(x))` and `for item in x`.
  7621. ```
  7622. import pgzrun
  7623. import random
  7624. HEIGHT = 600
  7625. WIDTH = 600
  7626. elf = Actor('c1')
  7627. king = Actor('c2')
  7628. elf.x = 20
  7629. elf.y = random.randint(0,HEIGHT)
  7630. king.y = random.randint(0,HEIGHT)
  7631. king.x = WIDTH-20
  7632. things = []
  7633. def add_new_obsticle(l):
  7634. image = random.choice(["snake","bullet","flower","rock"])
  7635. x = Actor(image)
  7636. x.x = random.randint(0,WIDTH)
  7637. x.y = random.randint(0,HEIGHT)
  7638. l.append(x)
  7639. for i in range(10):
  7640. add_new_obsticle(things)
  7641. def update():
  7642. if keyboard.UP:
  7643. elf.y -= 5
  7644. if keyboard.DOWN:
  7645. elf.y += 5
  7646. if keyboard.RIGHT:
  7647. elf.x += 5
  7648. if keyboard.LEFT:
  7649. elf.x -= 5
  7650. if keyboard.W:
  7651. king.y -= 5
  7652. if keyboard.S:
  7653. king.y += 5
  7654. if keyboard.D:
  7655. king.x += 5
  7656. if keyboard.A:
  7657. king.x -= 5
  7658. for s in range(len(things)):
  7659. if things[s].colliderect(elf):
  7660. elf.image = things[s].image
  7661. if king.colliderect(elf):
  7662. king.image = "c3"
  7663. def draw():
  7664. screen.fill('azure')
  7665. king.draw()
  7666. elf.draw()
  7667. for thing in things:
  7668. thing.draw()
  7669. pgzrun.go()
  7670. ```
  7671. ## [DAY-123] Lists; Callbacks
  7672. ![game-123.png](./screenshots/game-123.png "game 123 screenshot")
  7673. a bit more complicated game
  7674. ```
  7675. import pgzrun
  7676. import random
  7677. from itertools import cycle
  7678. WIDTH = 300
  7679. HEIGHT = 300
  7680. game_over = False
  7681. player = Actor("c1", pos=((WIDTH/2), (HEIGHT-16)), anchor=("center","bottom"))
  7682. obsticles = []
  7683. def jump_up(jumper):
  7684. sounds.jump.play()
  7685. animate(jumper, tween='decelerate', duration=0.3, pos=(jumper.x, jumper.y - 16),on_finished=lambda: jump_down(jumper))
  7686. def jump_down(jumper):
  7687. animate(jumper, tween='accelerate', duration=0.3, pos=(jumper.x, HEIGHT-16))
  7688. def on_key_down(key):
  7689. if key == keys.SPACE:
  7690. jump_up(player)
  7691. def make_obsticles():
  7692. for i in range(0, 5 - len(obsticles)):
  7693. # check if colliding, add random + 20 to it
  7694. actor = Actor(random.choice(["o1","o2","o3","o4","o5","o6","o7","o8","o9","o10","o11"]), anchor=("center","bottom"))
  7695. actor.x = WIDTH + 40 + random.randint(10, WIDTH*2)
  7696. actor.y = HEIGHT - 16
  7697. while True:
  7698. actor.x += random.randint(30, 50)
  7699. conflict = False
  7700. for o in obsticles:
  7701. if o.colliderect(actor):
  7702. conflict = True
  7703. if not conflict:
  7704. break
  7705. obsticles.append(actor)
  7706. def update():
  7707. global game_over
  7708. if len(obsticles) < 5:
  7709. make_obsticles()
  7710. for o in list(obsticles):
  7711. # shrink the collision rects so the game is more fun to play
  7712. if o.inflate(-4,-4).colliderect(player.inflate(-16,-16)):
  7713. game_over = True
  7714. # remove the obsticles out of screen
  7715. o.x -= 2
  7716. if o.x < -10:
  7717. obsticles.remove(o)
  7718. # player animation
  7719. # we just change the image of the actor every 0.4 seconds
  7720. poses = cycle(["player/tiles-46","player/tiles-47","player/tiles-48","player/tiles-49","player/tiles-50","player/tiles-51"])
  7721. def make_actor_move():
  7722. player.image = next(poses)
  7723. clock.schedule_interval(make_actor_move, 0.4)
  7724. def draw():
  7725. screen.fill("black")
  7726. player.draw()
  7727. for o in obsticles:
  7728. o.draw()
  7729. for i in range(100):
  7730. screen.blit('floor',(i * 16, HEIGHT - 16))
  7731. if game_over:
  7732. screen.fill("red")
  7733. pgzrun.go()
  7734. ```
  7735. ## [DAY-124] BMP format, Images; Encoding/Decoding
  7736. Images
  7737. The way we store image is very similar to the way we store text. It is just a bunch of bytes, but when we read them we decide to interpret them differently.
  7738. Open images/joshi-100.bmp and you will see:
  7739. ![joshi-100.bmp](./images/joshi-100.bmp "joshi")
  7740. Now lets just read the bytes, and just show the numbers, starting at position 54, when we print new line every 106, and also we are gonna print every 4th byte.
  7741. first just print the bytes:
  7742. ```
  7743. file = open("images/joshi-100.bmp","rb")
  7744. data = file.read()
  7745. file.close()
  7746. for b in data:
  7747. print("%3d" % b,end='')
  7748. ```
  7749. now lets print them in specific order:
  7750. ```
  7751. file = open("images/joshi-100.bmp","rb")
  7752. data = file.read()
  7753. file.close()
  7754. width = 100
  7755. height = 106
  7756. offset = 54
  7757. for y in range(width):
  7758. for x in range(height):
  7759. off = offset + ((y * width + x) * 4)
  7760. print("%3d" % data[off+2],end='')
  7761. print()
  7762. ```
  7763. ![game-124.png](./screenshots/game-124.png "game 124 screenshot")
  7764. looks familiar!
  7765. The image itself actually contains information about how big it is, and where the data starts, it is specified in the bitmap format itself.
  7766. Here is the bitmap header information, copied from: http://www.ece.ualberta.ca/~elliott/ee552/studentAppNotes/2003_w/misc/bmp_file_format/bmp_file_format.htm
  7767. | Name | Size | Offset | Description |
  7768. | - | - | - | - |
  7769. | **Header** | 14 bytes | | Windows Structure: BITMAPFILEHEADER |
  7770. | Signature | 2 bytes | 0000h | 'BM' |
  7771. | FileSize | 4 bytes | 0002h | File size in bytes |
  7772. | reserved | 4 bytes | 0006h | unused (=0) |
  7773. | DataOffset | 4 bytes | 000Ah | Offset from beginning of file to the beginning of the bitmap data |
  7774. | **InfoHeader** | 40 bytes | | Windows Structure: BITMAPINFOHEADER |
  7775. | Size | 4 bytes | 000Eh | Size of InfoHeader =40 |
  7776. | Width | 4 bytes | 0012h | Horizontal width of bitmap in pixels |
  7777. | Height | 4 bytes | 0016h | Vertical height of bitmap in pixels |
  7778. | Planes | 2 bytes | 001Ah | Number of Planes (=1) |
  7779. | Bits Per Pixel | 2 bytes | 001Ch | Bits per Pixel used to store palette entry information. This also identifies in an indirect way the number of possible colors. Possible values are:<br>1 = monochrome palette. NumColors = 1 <br>4 = 4bit palletized. NumColors = 16 <br>8 = 8bit palletized. NumColors = 256 <br>16 = 16bit RGB. NumColors = 65536<br>24 = 24bit RGB. NumColors = 16M |
  7780. | Compression | 4 bytes | 001Eh | Type of Compression <br>0 = BI\_RGB no compression <br>1 = BI\_RLE8 8bit RLE encoding <br>2 = BI\_RLE4 4bit RLE encoding |
  7781. | ImageSize | 4 bytes | 0022h | (compressed) Size of Image <br>It is valid to set this =0 if Compression = 0 |
  7782. | XpixelsPerM | 4 bytes | 0026h | horizontal resolution: Pixels/meter |
  7783. | YpixelsPerM | 4 bytes | 002Ah | vertical resolution: Pixels/meter |
  7784. | Colors Used | 4 bytes | 002Eh | Number of actually used colors. For a 8-bit / pixel bitmap this will be 100h or 256. |
  7785. | Important Colors | 4 bytes | 0032h | Number of important colors <br>0 = all |
  7786. | **ColorTable** | 4 \* NumColors bytes | 0036h | present only if Info.BitsPerPixel less than 8 <br>colors should be ordered by importance |
  7787. | Red | 1 byte | | Red intensity |
  7788. | Green | 1 byte | | Green intensity |
  7789. | Blue | 1 byte | | Blue intensity |
  7790. | reserved | 1 byte | | unused (=0) |
  7791. | repeated NumColors times |
  7792. | **Pixel Data** | InfoHeader.ImageSize bytes | | The image data
  7793. Now using the header information, we can get the width, height and data offset directly from there:
  7794. ```
  7795. file = open("images/joshi-100.bmp","rb")
  7796. data = file.read()
  7797. file.close()
  7798. offset = int.from_bytes(data[10:14], byteorder='little')
  7799. width = int.from_bytes(data[18:22], byteorder='little')
  7800. height = int.from_bytes(data[22:26], byteorder='little')
  7801. for y in range(width):
  7802. for x in range(height):
  7803. off = offset + ((y * width + x) * 4)
  7804. print("%3d" % data[off+2],end='')
  7805. print()
  7806. ```
  7807. You see when we read `data[10:14]` we want to skip `signature` (2 bytes), `file size` (4 bytes) and `reserved` (4 bytes) and read exactly 4 bytes after that.
  7808. And we can make 4 bytes into a integer with `int.from_bytes`. We will get into that later. For now the important thing to focus on is the format itself.
  7809. It has a header, followed up by data. This is very common method and you will see it in all kinds of places. Even in our virtual computer when we were storing the strings we used a similar method, the first byte was always the length of the string.
  7810. ## [DAY-125] Lists; Dictionaries
  7811. ![game-125-a.png](./screenshots/game-125-a.png "game 125 a screenshot")
  7812. ![game-125-b.png](./screenshots/game-125-b.png "game 125 b screenshot")
  7813. ![game-125-c.png](./screenshots/game-125-c.png "game 125 c screenshot")
  7814. ![game-125-d.png](./screenshots/game-125-d.png "game 125 d screenshot")
  7815. Write code to destroy your enemies!
  7816. You have access to your `heroes` and `enemies` positions. When you collide you destroy each other.
  7817. ```
  7818. import pgzrun
  7819. import random
  7820. from itertools import cycle
  7821. WIDTH=600
  7822. HEIGHT=600
  7823. enemies = []
  7824. heroes = []
  7825. text = """
  7826. for h in heroes:
  7827. h.x += random.randint(-10,10)
  7828. h.y += random.randint(-10,10)
  7829. """
  7830. enemy_programs = cycle([
  7831. """
  7832. i = 0
  7833. for e in enemies:
  7834. e.x = i * 10
  7835. e.y = i * 10
  7836. i += 1
  7837. """,
  7838. """
  7839. for e in enemies:
  7840. e.x += random.randint(-10,10)
  7841. e.y += random.randint(-10,10)
  7842. """,
  7843. """
  7844. for e in enemies:
  7845. (x,y) = random.choice(heroes)
  7846. e.x = x
  7847. e.y = y
  7848. """
  7849. ])
  7850. enemy_code = None
  7851. def reset():
  7852. global heroes, enemies, enemy_code
  7853. enemy_code = next(enemy_programs)
  7854. enemies = []
  7855. heroes = []
  7856. for i in range(20):
  7857. enemies.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))
  7858. heroes.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))
  7859. def on_key_down(key, mod, unicode):
  7860. global text, pause, score_words, score
  7861. if key == keys.BACKSPACE:
  7862. if mod == 1024 or mod == 256:
  7863. text = ''
  7864. if len(text) > 0:
  7865. text = text[:-1]
  7866. elif key == keys.SPACE:
  7867. text += ' '
  7868. elif key == keys.TAB:
  7869. text += ' '
  7870. elif key == keys.RETURN:
  7871. text += '\n'
  7872. elif len(unicode) > 0 and ord(unicode) >= 34 and ord(unicode) <= 126:
  7873. text += unicode
  7874. def run_code():
  7875. try:
  7876. enemy_positions = []
  7877. for e in enemies:
  7878. enemy_positions.append((e.x, e.y))
  7879. hero_positions = []
  7880. for h in heroes:
  7881. hero_positions.append((e.x, e.y))
  7882. exec(text, {"heroes": heroes,"random":random, "enemies": enemy_positions})
  7883. exec(enemy_code, {"enemies": enemies, "random":random, "heroes": hero_positions})
  7884. for h in list(heroes):
  7885. collided = False
  7886. for e in list(enemies):
  7887. if e.colliderect(h):
  7888. enemies.remove(e)
  7889. if collided:
  7890. heroes.remove(h)
  7891. if len(enemies) < 50:
  7892. enemies.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))
  7893. heroes.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))
  7894. if len(enemies) < 5:
  7895. reset()
  7896. except Exception as err:
  7897. print(err)
  7898. pass
  7899. reset()
  7900. clock.schedule_interval(run_code, 1)
  7901. def draw():
  7902. screen.fill("black")
  7903. screen.draw.text("heroes: " + str(len(heroes)) + " enemies: " + str(len(enemies)), (0, 0), align='left',fontname="437-win", fontsize=20)
  7904. for (i,l) in enumerate(enemy_code.split('\n')):
  7905. screen.draw.text(l, (0, (20 + (i * 16))), align='left',fontname="437-win", fontsize=14)
  7906. for (i,l) in enumerate(text.split('\n')):
  7907. screen.draw.text(l, (0, (HEIGHT - 200 + (i * 16))), align='left',fontname="437-win", fontsize=14)
  7908. for e in enemies:
  7909. screen.draw.rect(e, (255,0,0))
  7910. for h in heroes:
  7911. screen.draw.rect(h, (0,255,255))
  7912. pgzrun.go()
  7913. ```
  7914. ## [DAY-126] Read/Write File
  7915. ![game-126.png](./screenshots/game-126.png "game 126 screenshot")
  7916. Save and load the position of the elf
  7917. Play hide and seek after that!
  7918. ```
  7919. import pgzrun
  7920. HEIGHT = 600
  7921. WIDTH = 600
  7922. elf = Actor('c1')
  7923. elf.x = WIDTH/2
  7924. elf.y = HEIGHT/2
  7925. def update():
  7926. if keyboard.UP:
  7927. elf.y -= 5
  7928. if keyboard.LEFT:
  7929. elf.x -= 5
  7930. if keyboard.RIGHT:
  7931. elf.x += 5
  7932. if keyboard.DOWN:
  7933. elf.y += 5
  7934. if keyboard.S:
  7935. f = open('save','w')
  7936. f.write('MAGIC HEADER\n' + str(elf.x) + '\n' + str(elf.y) + '\n')
  7937. f.close()
  7938. if keyboard.B:
  7939. f = open("save","r")
  7940. lines = f.readlines()
  7941. if (lines[0].startswith('MAGIC HEADER')):
  7942. elf.x = float(lines[1])
  7943. elf.y = float(lines[2])
  7944. f.close()
  7945. def draw():
  7946. elf.draw()
  7947. pgzrun.go()
  7948. ```
  7949. ## [DAY-127] Callbacks; Schedule Interval
  7950. super short, make the actor walk
  7951. ```
  7952. from itertools import cycle
  7953. import pgzrun
  7954. WIDTH=200
  7955. HEIGHT=200
  7956. elf = Actor("c1")
  7957. elf.x = WIDTH/2
  7958. elf.y = HEIGHT/2
  7959. poses = cycle(["player/tiles-46","player/tiles-47","player/tiles-48","player/tiles-49","player/tiles-50","player/tiles-51"])
  7960. def make_actor_move():
  7961. elf.image = next(poses)
  7962. clock.schedule_interval(make_actor_move, 0.4)
  7963. def draw():
  7964. screen.fill("black")
  7965. elf.draw()
  7966. pgzrun.go()
  7967. ```
  7968. ## [DAY-128] Lists; CPU usage; Resources
  7969. ![game-128.png](./screenshots/game-128.png "game 128 screenshot")
  7970. See how slow you can make your computer, by making it draw 100 000 actors 60 times per second.
  7971. See how slow it moves, open the activity monitor or the task manager to see how it eats all your resources.
  7972. After that chabnge it to 100 actors and see the difference.
  7973. ```
  7974. import random
  7975. import pgzrun
  7976. WIDTH = 800
  7977. HEIGHT = 800
  7978. actors = []
  7979. for i in range(0, 100000):
  7980. elf = Actor("c1")
  7981. elf.x = WIDTH/2
  7982. elf.y = HEIGHT/2
  7983. actors.append(elf)
  7984. def update():
  7985. if keyboard.UP:
  7986. for i in range(0, len(actors)):
  7987. a = actors[i]
  7988. a.y -= i
  7989. if keyboard.DOWN:
  7990. for i in range(0, len(actors)):
  7991. a = actors[i]
  7992. a.y += i
  7993. if keyboard.LEFT:
  7994. for i in range(0, len(actors)):
  7995. a = actors[i]
  7996. a.x -= i
  7997. if keyboard.RIGHT:
  7998. for i in range(0, len(actors)):
  7999. a = actors[i]
  8000. a.x += i
  8001. def draw():
  8002. screen.fill("black")
  8003. for a in actors:
  8004. a.draw()
  8005. pgzrun.go()
  8006. ```
  8007. ## [DAY-129] Eat your computer; Memory; CPU
  8008. consume one CPU on your computer
  8009. ```
  8010. while True:
  8011. x = 1
  8012. ```
  8013. Open activity monitor/task manager and see how it will consume 100% of one CPU, your computer has more than one CPU, this code will totally consume one, and in a bit you will see the computer will get hot, and the fans will start spinning. This is because each cycle of the CPU requires energy. So when you consume 100% of the CPU it will consume the maximum possible energy, and every time you use energy something is lost, and the loss is radiated as heat, even when you run, and you sweat you can see heat coming out of you.
  8014. It might seem like `x = 1` is doing nothing, but it actually has to go to the memory address of the variable x and set it to value 1
  8015. Now, lets consume all the memory.
  8016. ```
  8017. a = []
  8018. for i in range(10000000000):
  8019. a.append(i)
  8020. ```
  8021. This will create a list with 10000000000 items in it, in python the size of an integer is a bit bigger than you think, usually numbers are stored in 4 byte or 8 byte memory slots; so 10000000000 * 4 is approximately 40 gigabytes of memory, your computer has 16 or 32 gigabytes. If you let the program run long enough you will see how it grows, and it consumes more and more memory.
  8022. Now you might be surprised when it reaches your computer's max memory and it keeps going, and this is because your operating system will start taking memory out and writing it to your hard disk, this is called swapping. You will see your swap grow. If you wait long enough your computer will become slower and slower, and at some point it will be unusable.
  8023. ## [DAY-130] turtle; lists; classes
  8024. ![game-130.png](./screenshots/game-130.png "game 130 screenshot")
  8025. many turtles
  8026. ```
  8027. import turtle
  8028. import random
  8029. colors = ['violet', 'turquoise', 'black',
  8030. 'deepskyblue','lawngreen', 'seagreen ',
  8031. 'royalblue', 'purple', 'red','orange']
  8032. turtles = []
  8033. for i in range(10):
  8034. t = turtle.Turtle()
  8035. t.color(random.choice(colors))
  8036. t.speed(9000)
  8037. turtles.append(t)
  8038. while True:
  8039. for i in range(len(turtles)):
  8040. t = turtles[i]
  8041. t.setheading(random.randint(0,360))
  8042. t.forward(10)
  8043. ```
  8044. Lets practice making a new class, you see when we say Turtle() or Actor() we make a new instance of the class Turtle and the class Actor
  8045. The Class itself is like a blueprint of how to make a new instance of itself, for example lets make a class Point that has two properties, `x` and `y`
  8046. ```
  8047. class Point:
  8048. x = 0
  8049. y = 0
  8050. points = []
  8051. for i in range(10):
  8052. p = Point()
  8053. p.x = i * 20
  8054. p.y = i * 20
  8055. points.append(p)
  8056. for p in points:
  8057. print(p, p.x, p.y)
  8058. ```
  8059. When you define a function in a class, you have access to special parameter, `self` which is the instance on which this function is called:
  8060. ```
  8061. class Dog:
  8062. name = ''
  8063. def bark(self):
  8064. print(self.name+' woof woof woof')
  8065. max = Dog()
  8066. max.name = 'Maxie'
  8067. max.bark()
  8068. rocky = Dog()
  8069. rocky.name = "Rocky"
  8070. rocky.bark()
  8071. ```
  8072. There is also a special `__init__` function, called constructor that lets you pass parameters directly when you create the instance.
  8073. ```
  8074. class Point:
  8075. x = 0
  8076. y = 0
  8077. def __init__(self, x,y):
  8078. self.x = x
  8079. self.y = y
  8080. points = []
  8081. for i in range(10):
  8082. p = Point(i * 10, i * 20)
  8083. points.append(p)
  8084. for p in points:
  8085. print(p, p.x, p.y)
  8086. ```
  8087. ## [DAY-131] Lists; Files; Dictionaries
  8088. Example dictionary, List and String
  8089. ```
  8090. words = {}
  8091. words["some long key"] = True
  8092. words["x"] = 10
  8093. for k in words:
  8094. print(k)
  8095. print(words[k])
  8096. list_of_characters = ['a','b','c']
  8097. for i in range(len(list_of_characters)):
  8098. print(i)
  8099. print(list_of_characters[i])
  8100. s = "hello"
  8101. for i in range(len(s)):
  8102. print(i)
  8103. print(s[i])
  8104. ```
  8105. You see how in the list and string we can address individual element or character by its index? In the dictionary we address things by their key, for example if i want to see the value of `some long key` I do `print(words["some long key"])`.
  8106. Now unrelated, but lets practice printing the first 100 numbers from a list.
  8107. ```
  8108. a = []
  8109. for i in range(100):
  8110. a.append(i)
  8111. for i in range(100):
  8112. print(a[i])
  8113. ```
  8114. Append to file, whatever command line agurments 1 and 2 are
  8115. ```
  8116. import sys
  8117. f = open("account.txt", "a")
  8118. f.write(sys.argv[1] + " " + sys.argv[2] + "\n")
  8119. f.close()
  8120. ```
  8121. ## [DAY-132] Lists; Classes
  8122. ![game-132.png](./screenshots/game-132.png "game 132 screenshot")
  8123. a tower defense game
  8124. ```
  8125. import pgzrun
  8126. import random
  8127. WIDTH=1024
  8128. HEIGHT=576
  8129. towers = []
  8130. enemies = []
  8131. bullets = []
  8132. game_over = False
  8133. background = Actor("grass_template2", pos=(0,0), anchor=(0,0))
  8134. player = Actor("c1", pos=(WIDTH/2, HEIGHT/2), anchor=('center','bottom'))
  8135. lives = 100
  8136. cash = 100
  8137. current_wave = 1
  8138. class Tower:
  8139. def __init__(self, image, x,y, size):
  8140. self.actor = Actor(image, pos=(x,y), )
  8141. self.rect = Rect((x-size/2,y-size/2), (size,size))
  8142. self.color = (random.randint(100,250),random.randint(100,250),random.randint(100,250))
  8143. def shoot(self):
  8144. for e in enemies:
  8145. if e.colliderect(self.rect):
  8146. b = Actor("bullet3")
  8147. b.x = self.actor.x
  8148. b.y = self.actor.y
  8149. b.hit = False
  8150. animate(b, pos=(e.x,e.y), tween='accelerate', on_finished=lambda: bullets.remove(b))
  8151. bullets.append(b)
  8152. break
  8153. def colliderect(self,other):
  8154. return self.actor.colliderect(other)
  8155. def draw(self):
  8156. self.actor.draw()
  8157. #screen.draw.rect(self.rect,self.color)
  8158. def shoot():
  8159. global cash
  8160. for t in towers:
  8161. t.shoot()
  8162. for e in list(enemies):
  8163. if e.image == 'exploded':
  8164. enemies.remove(e)
  8165. cash+=1
  8166. def new_wave():
  8167. global current_wave
  8168. for i in range(current_wave * 10):
  8169. e = Actor("c3")
  8170. e.y = HEIGHT
  8171. e.x = random.randint(int(WIDTH/3), int(WIDTH-WIDTH/3))
  8172. enemies.append(e)
  8173. current_wave += 1
  8174. def on_key_down(key):
  8175. global cash
  8176. if key == keys.K_1:
  8177. if cash >= 10:
  8178. conflict = False
  8179. for t in towers:
  8180. if t.colliderect(player):
  8181. conflict = True
  8182. if not conflict:
  8183. t = Tower("tower_grass",player.x, player.y, 150)
  8184. towers.append(t)
  8185. cash -= 10
  8186. def update():
  8187. global game_over
  8188. if keyboard.UP:
  8189. player.y -= 5
  8190. if keyboard.DOWN:
  8191. player.y += 5
  8192. if keyboard.LEFT:
  8193. player.x -= 5
  8194. if keyboard.RIGHT:
  8195. player.x += 5
  8196. for e in enemies:
  8197. if e.image != 'exploded':
  8198. e.y -= random.randint(-1,2)
  8199. for b in bullets:
  8200. if b.colliderect(e):
  8201. e.image = 'exploded'
  8202. b.hit = True
  8203. break
  8204. if not background.colliderect(e):
  8205. game_over = True
  8206. pass
  8207. clock.schedule_interval(shoot, 1)
  8208. clock.schedule_interval(new_wave, 10)
  8209. new_wave()
  8210. def draw():
  8211. screen.clear()
  8212. if game_over:
  8213. screen.fill('blue')
  8214. else:
  8215. background.draw()
  8216. screen.draw.text("current_wave: " + str(current_wave) + ", cash: " + str(cash) + ", lives: " + str(lives), (5,0),fontname="437-win")
  8217. for b in bullets:
  8218. if not b.hit:
  8219. b.draw()
  8220. for e in enemies:
  8221. e.draw()
  8222. for t in towers:
  8223. t.draw()
  8224. player.draw()
  8225. pgzrun.go()
  8226. ```
  8227. ## [DAY-133] Touch Typing; Lists
  8228. ![game-133.png](./screenshots/game-133.png "game 133 screenshot")
  8229. Spend 15 minutes touch typing.
  8230. Add a path for the enemies to walk on.
  8231. The most important part is to think about, how would you follow a path, in this example we will follow a path by picking a next element to walk towards.
  8232. This is the most important part of the change, it is an what is called an algorithm, it is a sequence of steps to solve a problem. We can describe it in words: **find the current square you are colliding it, find which square is next in the list, start walking towards it**. Now lets write it down:
  8233. ```
  8234. [...]
  8235. path = [
  8236. Rect(0, HEIGHT/2, 50, 50),
  8237. Rect(50, HEIGHT/2, 50, 50),
  8238. [...]
  8239. def update():
  8240. [...]
  8241. for e in enemies:
  8242. if e.image != 'exploded':
  8243. destination = None
  8244. for (i, p) in enumerate(path):
  8245. if e.colliderect(p) and i < len(path) - 1:
  8246. destination = path[i+1]
  8247. break
  8248. if destination != None:
  8249. center_x = destination.x + 25
  8250. center_y = destination.y + 25
  8251. if e.x < center_x:
  8252. e.x += random.randint(0, 2)
  8253. if e.x > center_x:
  8254. e.x -= random.randint(0, 2)
  8255. if e.y > center_y:
  8256. e.y -= random.randint(0, 2)
  8257. if e.y < center_y:
  8258. e.y += random.randint(0, 2)
  8259. [...]
  8260. ```
  8261. ```
  8262. import pgzrun
  8263. import random
  8264. WIDTH = 1024
  8265. HEIGHT = 576
  8266. towers = []
  8267. enemies = []
  8268. bullets = []
  8269. game_over = False
  8270. background = Actor("grass_template2", pos=(0, 0), anchor=(0, 0))
  8271. path_size = 50
  8272. path = [
  8273. Rect(0, HEIGHT/2, 50, 50),
  8274. Rect(50, HEIGHT/2, 50, 50),
  8275. Rect(50, HEIGHT/2 + 50, 50, 50),
  8276. Rect(100, HEIGHT/2 + 50, 50, 50),
  8277. Rect(150, HEIGHT/2 + 50, 50, 50),
  8278. Rect(200, HEIGHT/2 + 50, 50, 50),
  8279. Rect(250, HEIGHT/2 + 50, 50, 50),
  8280. Rect(250, HEIGHT/2 + 100, 50, 50),
  8281. Rect(300, HEIGHT/2 + 100, 50, 50),
  8282. Rect(350, HEIGHT/2 + 100, 50, 50),
  8283. Rect(400, HEIGHT/2 + 100, 50, 50),
  8284. Rect(450, HEIGHT/2 + 100, 50, 50),
  8285. Rect(500, HEIGHT/2 + 100, 50, 50),
  8286. Rect(500, HEIGHT/2 + 150, 50, 50),
  8287. Rect(550, HEIGHT/2 + 150, 50, 50),
  8288. Rect(600, HEIGHT/2 + 150, 50, 50),
  8289. Rect(650, HEIGHT/2 + 150, 50, 50),
  8290. Rect(650, HEIGHT/2 + 200, 50, 50),
  8291. Rect(700, HEIGHT/2 + 200, 50, 50),
  8292. Rect(750, HEIGHT/2 + 200, 50, 50),
  8293. Rect(800, HEIGHT/2 + 200, 50, 50),
  8294. Rect(850, HEIGHT/2 + 200, 50, 50),
  8295. Rect(850, HEIGHT/2 + 150, 50, 50),
  8296. Rect(850, HEIGHT/2 + 100, 50, 50),
  8297. Rect(850, HEIGHT/2 + 50, 50, 50),
  8298. Rect(850, HEIGHT/2 + 0, 50, 50),
  8299. Rect(850, HEIGHT/2 - 50, 50, 50),
  8300. Rect(850, HEIGHT/2 - 100, 50, 50),
  8301. Rect(900, HEIGHT/2 - 100, 50, 50),
  8302. Rect(950, HEIGHT/2 - 100, 50, 50),
  8303. Rect(1000, HEIGHT/2 - 100, 50, 50),
  8304. Rect(1050, HEIGHT/2 - 100, 50, 50),
  8305. Rect(1100, HEIGHT/2 - 100, 50, 50),
  8306. ]
  8307. player = Actor("c1", pos=(WIDTH/2, HEIGHT/2), anchor=('center', 'bottom'))
  8308. lives = 100
  8309. cash = 100
  8310. current_wave = 1
  8311. class Tower:
  8312. def __init__(self, image, x, y, size):
  8313. self.actor = Actor(image, pos=(x, y), )
  8314. self.rect = Rect((x-size/2, y-size/2), (size, size))
  8315. self.color = (random.randint(100, 250), random.randint(
  8316. 100, 250), random.randint(100, 250))
  8317. def shoot(self):
  8318. for e in enemies:
  8319. if e.colliderect(self.rect):
  8320. b = Actor("bullet3")
  8321. b.x = self.actor.x
  8322. b.y = self.actor.y
  8323. b.hit = False
  8324. animate(b, pos=(e.x, e.y), tween='accelerate',
  8325. on_finished=lambda: bullets.remove(b))
  8326. bullets.append(b)
  8327. break
  8328. def colliderect(self, other):
  8329. return self.actor.colliderect(other)
  8330. def draw(self):
  8331. self.actor.draw()
  8332. screen.draw.rect(self.rect,self.color)
  8333. def shoot():
  8334. global cash
  8335. for t in towers:
  8336. t.shoot()
  8337. for e in list(enemies):
  8338. if e.image == 'exploded':
  8339. enemies.remove(e)
  8340. cash += 1
  8341. def new_wave():
  8342. global current_wave
  8343. for i in range(10 + (current_wave * 2)):
  8344. e = Actor("c3")
  8345. e.y = HEIGHT/2+10
  8346. e.x = 0
  8347. enemies.append(e)
  8348. current_wave += 1
  8349. def on_key_down(key):
  8350. global cash
  8351. if key == keys.K_1:
  8352. if cash >= 10:
  8353. conflict = False
  8354. for t in towers:
  8355. if t.colliderect(player):
  8356. conflict = True
  8357. for p in path:
  8358. if player.colliderect(p):
  8359. conflict = True
  8360. if not conflict:
  8361. t = Tower("tower_grass", player.x, player.y, 150)
  8362. towers.append(t)
  8363. cash -= 10
  8364. def update():
  8365. global game_over
  8366. if keyboard.UP:
  8367. player.y -= 5
  8368. if keyboard.DOWN:
  8369. player.y += 5
  8370. if keyboard.LEFT:
  8371. player.x -= 5
  8372. if keyboard.RIGHT:
  8373. player.x += 5
  8374. for e in enemies:
  8375. if e.image != 'exploded':
  8376. destination = None
  8377. for (i, p) in enumerate(path):
  8378. if e.colliderect(p) and i < len(path) - 1:
  8379. destination = path[i+1]
  8380. break
  8381. if destination != None:
  8382. center_x = destination.x + 25
  8383. center_y = destination.y + 25
  8384. if e.x < center_x:
  8385. e.x += random.randint(0, 2)
  8386. if e.x > center_x:
  8387. e.x -= random.randint(0, 2)
  8388. if e.y > center_y:
  8389. e.y -= random.randint(0, 2)
  8390. if e.y < center_y:
  8391. e.y += random.randint(0, 2)
  8392. for b in bullets:
  8393. if b.colliderect(e):
  8394. e.image = 'exploded'
  8395. b.hit = True
  8396. break
  8397. if not background.colliderect(e):
  8398. game_over = True
  8399. pass
  8400. clock.schedule_interval(shoot, 1)
  8401. clock.schedule_interval(new_wave, 10)
  8402. new_wave()
  8403. def draw():
  8404. screen.clear()
  8405. if game_over:
  8406. screen.fill('blue')
  8407. else:
  8408. background.draw()
  8409. screen.draw.text("current_wave: " + str(current_wave) + ", cash: " +
  8410. str(cash) + ", lives: " + str(lives), (5, 0), fontname="437-win")
  8411. for i in range(len(path)):
  8412. p = path[i]
  8413. screen.draw.filled_rect(p,(255,0,0))
  8414. screen.draw.text(str(p.x), (p.x,p.y))
  8415. for b in bullets:
  8416. if not b.hit:
  8417. b.draw()
  8418. for e in enemies:
  8419. e.draw()
  8420. for t in towers:
  8421. t.draw()
  8422. player.draw()
  8423. pgzrun.go()
  8424. ```
  8425. ## [DAY-134] Lists; Methods
  8426. Upgrade our tower game, make it possible to:
  8427. * delete towers and get some money back
  8428. * be able to upgrade the tower's range
  8429. First we will store original `x`,`y` and `size` in the tower's instance, and then use it to increase its range.
  8430. Again pay attention when deleting from a list we are walking on (iterating on), we actually make a clone of the list and iterate over the clone, but remove items from the original list by value.
  8431. ```
  8432. [...]
  8433. class Tower:
  8434. [...]
  8435. def __init__(self, image, x, y, size):
  8436. self.size = size
  8437. self.x = x
  8438. self.y = y
  8439. self.actor = Actor(image, pos=(x, y))
  8440. self.rect = Rect((x-size/2, y-size/2), (size, size))
  8441. self.color = (random.randint(100, 250), random.randint(100, 250), random.randint(100, 250))
  8442. def resize(self, bump):
  8443. new_size = self.size + bump
  8444. self.size = new_size
  8445. self.rect = Rect((self.x-new_size/2, self.y-new_size/2), (new_size, new_size))
  8446. [...]
  8447. def on_key_down(key):
  8448. global cash
  8449. if key == keys.K_2:
  8450. for t in towers:
  8451. if t.colliderect(player):
  8452. t.resize(5)
  8453. cash -= 10
  8454. if key == keys.D:
  8455. for t in list(towers):
  8456. if t.colliderect(player):
  8457. cash += 15
  8458. towers.remove(t)
  8459. [...]
  8460. ```
  8461. ## [DAY-134] If
  8462. ![game-134.png](./screenshots/game-134.png "game 134 screenshot")
  8463. Relax day.
  8464. Make super simple game to draw with two players, because we dont clear the screen.
  8465. ```
  8466. import pgzrun
  8467. HEIGHT = 800
  8468. WIDTH = 800
  8469. elf = Actor('c1')
  8470. king = Actor('c2')
  8471. def update():
  8472. if keyboard.W:
  8473. elf.y -= 5
  8474. if keyboard.S:
  8475. elf.y += 5
  8476. if keyboard.A:
  8477. elf.x -= 5
  8478. if keyboard.D:
  8479. elf.x += 5
  8480. if keyboard.UP:
  8481. king.y -= 5
  8482. if keyboard.DOWN:
  8483. king.y += 5
  8484. if keyboard.LEFT:
  8485. king.x -= 5
  8486. if keyboard.RIGHT:
  8487. king.x += 5
  8488. def draw():
  8489. elf.draw()
  8490. king.draw()
  8491. pgzrun.go()
  8492. ```
  8493. ## [DAY-135] Dictionary; For
  8494. [game-135](screenshots/game-135.mp3)
  8495. Make a morse code machine!
  8496. ```
  8497. import pgzrun
  8498. import time
  8499. short = tone.create('A3', 0.3)
  8500. long = tone.create('D3', 0.7)
  8501. morse = {
  8502. 'a': [short, long],
  8503. 'b': [long, short, short, short],
  8504. 'c': [long, short, long, short],
  8505. 'd': [long, short, short],
  8506. 'e': [short],
  8507. 'f': [short, short, long, short],
  8508. 'g': [long, long, short],
  8509. 'h': [short, short, short, short],
  8510. 'i': [short, short],
  8511. 'j': [short, long, long, long],
  8512. 'k': [long, short, long],
  8513. 'l': [short, long, short, short],
  8514. 'm': [long, long],
  8515. 'n': [long, short],
  8516. 'o': [long, long, long],
  8517. 'p': [short, long, long, short],
  8518. 'q': [long, long, short, long],
  8519. 'r': [short, long, short],
  8520. 's': [short, short, short],
  8521. 't': [long],
  8522. 'u': [short, short, long],
  8523. 'v': [short, short, short, long],
  8524. 'w': [short, long, long],
  8525. 'x': [long, short, short, long],
  8526. 'y': [long, short, long, long],
  8527. 'z': [long, long, short, short]
  8528. }
  8529. def play(key):
  8530. for t in morse[key]:
  8531. t.play()
  8532. time.sleep(1)
  8533. time.sleep(1)
  8534. def on_key_down(key):
  8535. if key == keys.A:
  8536. play('a')
  8537. if key == keys.B:
  8538. play('b')
  8539. if key == keys.C:
  8540. play('c')
  8541. if key == keys.D:
  8542. play('d')
  8543. if key == keys.E:
  8544. play('e')
  8545. if key == keys.F:
  8546. play('f')
  8547. if key == keys.G:
  8548. play('g')
  8549. if key == keys.H:
  8550. play('h')
  8551. if key == keys.I:
  8552. play('i')
  8553. if key == keys.J:
  8554. play('j')
  8555. if key == keys.K:
  8556. play('k')
  8557. if key == keys.L:
  8558. play('l')
  8559. if key == keys.M:
  8560. play('m')
  8561. if key == keys.N:
  8562. play('n')
  8563. if key == keys.O:
  8564. play('o')
  8565. if key == keys.P:
  8566. play('p')
  8567. if key == keys.Q:
  8568. play('q')
  8569. if key == keys.R:
  8570. play('r')
  8571. if key == keys.S:
  8572. play('s')
  8573. if key == keys.T:
  8574. play('t')
  8575. if key == keys.U:
  8576. play('u')
  8577. if key == keys.V:
  8578. play('v')
  8579. if key == keys.W:
  8580. play('w')
  8581. if key == keys.X:
  8582. play('x')
  8583. if key == keys.Y:
  8584. play('y')
  8585. if key == keys.Z:
  8586. play('z')
  8587. def update():
  8588. pass
  8589. def draw():
  8590. pass
  8591. pgzrun.go()
  8592. ```
  8593. ## [DAY-136] For; Arrays; Memory
  8594. Lets make a super simple C program
  8595. Just to get familiar witht he syntax, it does not use indentation to group code, but {}, and also each variable has to have known type (size), e.g we have to tell the C compiler (compiler is a program that takes the text code and transforms it into machine code) that `i` is of type `int` which on our computer is exactly 4 bytes long.
  8596. ```
  8597. #include <stdio.h>
  8598. int main() {
  8599. int sum = 0;
  8600. for (int i = 0; i < 100; i++) {
  8601. sum += 10;
  8602. }
  8603. printf("%d\n", sum);
  8604. }
  8605. ```
  8606. When you execute `gcc -o foo foo.c` (if you save the program in foo.c), it will make the binary `foo`, do `cat foo` to see the actual binary made from the compiler. If you run `objdump -D foo` you will see the assembly code and the machine code corresponding to it.
  8607. `cat foo`:
  8608. ```
  8609. ????X? H__PAGEZERO?__TEXT@@__text__TEXT0?X0??__stubs__TEXT????__stub_helper__TEXT?????__cstring__TEXT????__unwind_info__TEXT??H???__DATA_CONST@@@@__got__DATA_CONST@?__DATA?@?@__la_symbol_ptr__DATA?__data__DA?H__LINKEDIT?@?"?? ?0?0h???H
  8610. P??
  8611. /usr/lib/dyld9??
  8612. f:^?[c?υ02
  8613. ?*(?0?
  8614. 8d
  8615. /usr/lib/libSystem.B.dylib&`)h?UH??H???E??E??E??}?d??E???
  8616. ?E??E???E???????u?H?=2?? ?E?H??]??%r@L?q@AS?%a?h?????%d
  8617. 0?44??4
  8618. ??#Q@dyld_stub_binderQr?s@_printf?__mh_execute_header!main%?~??0?$ __mh_execute_header_main_printfdyld_stub_binder__dyld_privat
  8619. ```
  8620. Because its a binary file, most of the bytes are not actually printable ASCII characters, you can use `hexdump` to see the byte's values:
  8621. `hexdump -C foo`
  8622. ```
  8623. 00000000 cf fa ed fe 07 00 00 01 03 00 00 00 02 00 00 00 |................|
  8624. 00000010 10 00 00 00 58 05 00 00 85 00 20 00 00 00 00 00 |....X..... .....|
  8625. 00000020 19 00 00 00 48 00 00 00 5f 5f 50 41 47 45 5a 45 |....H...__PAGEZE|
  8626. 00000030 52 4f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |RO..............|
  8627. 00000040 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
  8628. 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  8629. 00000060 00 00 00 00 00 00 00 00 19 00 00 00 d8 01 00 00 |................|
  8630. 00000070 5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 |__TEXT..........|
  8631. 00000080 00 00 00 00 01 00 00 00 00 40 00 00 00 00 00 00 |.........@......|
  8632. 00000090 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 |.........@......|
  8633. 000000a0 05 00 00 00 05 00 00 00 05 00 00 00 00 00 00 00 |................|
  8634. 000000b0 5f 5f 74 65 78 74 00 00 00 00 00 00 00 00 00 00 |__text..........|
  8635. 000000c0 5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 |__TEXT..........|
  8636. 000000d0 30 3f 00 00 01 00 00 00 58 00 00 00 00 00 00 00 |0?......X.......|
  8637. 000000e0 30 3f 00 00 04 00 00 00 00 00 00 00 00 00 00 00 |0?..............|
  8638. 000000f0 00 04 00 80 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  8639. 00000100 5f 5f 73 74 75 62 73 00 00 00 00 00 00 00 00 00 |__stubs.........|
  8640. 00000110 5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 |__TEXT..........|
  8641. 00000120 88 3f 00 00 01 00 00 00 06 00 00 00 00 00 00 00 |.?..............|
  8642. 00000130 88 3f 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |.?..............|
  8643. 00000140 08 04 00 80 00 00 00 00 06 00 00 00 00 00 00 00 |................|
  8644. [...]
  8645. ```
  8646. `objdump -D foo`
  8647. ```
  8648. [...]
  8649. 100003f30: 55 pushq %rbp
  8650. 100003f31: 48 89 e5 movq %rsp, %rbp
  8651. 100003f34: 48 83 ec 10 subq $16, %rsp
  8652. 100003f38: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
  8653. 100003f3f: c7 45 f8 00 00 00 00 movl $0, -8(%rbp)
  8654. 100003f46: c7 45 f4 00 00 00 00 movl $0, -12(%rbp)
  8655. 100003f4d: 83 7d f4 64 cmpl $100, -12(%rbp)
  8656. 100003f51: 0f 8d 17 00 00 00 jge 0x100003f6e <_main+0x3e>
  8657. 100003f57: 8b 45 f8 movl -8(%rbp), %eax
  8658. 100003f5a: 83 c0 0a addl $10, %eax
  8659. 100003f5d: 89 45 f8 movl %eax, -8(%rbp)
  8660. 100003f60: 8b 45 f4 movl -12(%rbp), %eax
  8661. 100003f63: 83 c0 01 addl $1, %eax
  8662. 100003f66: 89 45 f4 movl %eax, -12(%rbp)
  8663. 100003f69: e9 df ff ff ff jmp 0x100003f4d <_main+0x1d>
  8664. [...]
  8665. ```
  8666. `addl` meand `add`, `jmp` means jump and so forth. This is not important for now, the point is that `gcc` which is a popular C compiler, will take your code and make it into machine code.
  8667. Lets have another example:
  8668. FizzBuzz
  8669. ```
  8670. #include <stdio.h>
  8671. int main() {
  8672. for (int i = 0; i < 100; i++) {
  8673. if (i % 15 == 0) {
  8674. printf("fizzbuzz\n");
  8675. } else if (i % 5 == 0) {
  8676. printf("buzz\n");
  8677. } else if (i % 3 == 0) {
  8678. printf("fizz\n");
  8679. } else {
  8680. printf("%d\n",i);
  8681. }
  8682. }
  8683. }
  8684. ```
  8685. What is your name?
  8686. ```
  8687. #include <stdio.h>
  8688. int main() {
  8689. char input[20] = {0};
  8690. while(1) {
  8691. printf("What is your name: ");
  8692. scanf("%s",input);
  8693. printf("\nHello %s\n",input);
  8694. }
  8695. }
  8696. ```
  8697. You see how we say `char input[20]` which means we habe 20 elements of type `char` pointed by the input variable, it is literally just a pointer to some memory, and we can use `input[1]` to go to the address `input` plus 1 byte. Same with `int x[10]`, if we do x[3], it will go to the address pointed by `x` and add 3 * 4 to it.
  8698. We can make interesting bugs like that, because nobody will check if we go and read somewhere outside of the defined array:
  8699. ```
  8700. #include <stdio.h>
  8701. int main() {
  8702. char input[20] = {0};
  8703. int b = 5;
  8704. while(1) {
  8705. printf("What is your name: ");
  8706. scanf("%s",input);
  8707. printf("\nHello %s\n",input);
  8708. for (int i = 0; i < 40; i++) {
  8709. printf(" %d -> %d -> %c\n", i, input[i],input[i]);
  8710. }
  8711. }
  8712. }
  8713. ```
  8714. You will see some garbage from element 20 to 39, because it will actually go and read beyond the input bounderioes.
  8715. ## [DAY-137] For; File; If
  8716. Play with [words.txt](words.txt)
  8717. Open the file and print all the lines:
  8718. ```
  8719. f = open("words.txt")
  8720. for line in f:
  8721. print(line)
  8722. ```
  8723. Remove the newline:
  8724. ```
  8725. f = open("words.txt")
  8726. for line in f:
  8727. word = line.strip()
  8728. print(word)
  8729. ```
  8730. Print only words with more than 10 characters:
  8731. ```
  8732. f = open("words.txt")
  8733. for line in f:
  8734. word = line.strip()
  8735. if len(word) > 10:
  8736. print(word)
  8737. ```
  8738. Print only words starting with 'ab':
  8739. ```
  8740. f = open("words.txt")
  8741. for line in f:
  8742. word = line.strip()
  8743. if word[0] == 'a' and word[1] == 'b':
  8744. print(word)
  8745. ```
  8746. Print words not containing a character
  8747. ```
  8748. f = open("words.txt")
  8749. for line in f:
  8750. word = line.strip()
  8751. if 'e' not in word:
  8752. print(word)
  8753. ```
  8754. Avoid words containing multiple characters
  8755. ```
  8756. f = open("words.txt")
  8757. def avoid(word, characters):
  8758. for c in characters:
  8759. for w in word:
  8760. if w == c:
  8761. return False
  8762. return True
  8763. for line in f:
  8764. word = line.strip()
  8765. if avoid(word, ['a','b','c']):
  8766. print(word)
  8767. ```
  8768. Another implementation using 'char' in 'string':
  8769. ```
  8770. f = open("words.txt")
  8771. def avoid(word, characters):
  8772. for c in characters:
  8773. for c in word:
  8774. return False
  8775. return True
  8776. for line in f:
  8777. word = line.strip()
  8778. if avoid(word, ['a','b','c']):
  8779. print(word)
  8780. ```
  8781. Spinning turtle
  8782. ![game-137.png](./screenshots/game-137.png "game 137 screenshot")
  8783. ```
  8784. import turtle as t
  8785. size = 10
  8786. t.speed(10000)
  8787. while True:
  8788. t.right(150)
  8789. t.forward(size)
  8790. size += 1
  8791. ```
  8792. ![game-137-3.png](./screenshots/game-137-3.png "game 137-3 screenshot")
  8793. ```
  8794. import turtle as t
  8795. size = 10
  8796. t.speed(10000)
  8797. while True:
  8798. t.right(150)
  8799. t.forward(size)
  8800. if size % 2 == 0:
  8801. t.color('cyan')
  8802. else:
  8803. t.color('magenta')
  8804. size += 1
  8805. ```
  8806. ![game-137-4.png](./screenshots/game-137-4.png "game 137-4 screenshot")
  8807. ```
  8808. import turtle as t
  8809. size = 1
  8810. t.speed(100000)
  8811. t.bgcolor('black')
  8812. t.hideturtle()
  8813. i = 0
  8814. while True:
  8815. if i % 2 == 0:
  8816. t.color('cyan')
  8817. else:
  8818. t.color('magenta')
  8819. t.forward(i*3)
  8820. t.left(91)
  8821. i+=1
  8822. ```
  8823. ![game-137-2.png](./screenshots/game-137-2.png "game 137-2 screenshot")
  8824. ```
  8825. from turtle import *
  8826. begin_fill()
  8827. color('red')
  8828. pensize(3)
  8829. left(48)
  8830. forward(133)
  8831. circle(50,200)
  8832. right(140)
  8833. circle(50,200)
  8834. forward(133)
  8835. end_fill()
  8836. done()
  8837. ```
  8838. ![game-137-1.png](./screenshots/game-137-1.png "game 137-1 screenshot")
  8839. ```
  8840. from turtle import *
  8841. size = 1
  8842. speed(10000)
  8843. while True:
  8844. if size % 2 == 0:
  8845. color('blue')
  8846. else:
  8847. color('red')
  8848. circle(size, size * 5)
  8849. size += 1
  8850. ```
  8851. ## [DAY-138] For; File; If
  8852. Take it easy.
  8853. Count how many lines have exactly 5 characters
  8854. ```
  8855. fi = open('words.txt')
  8856. n = 0
  8857. for line in fi:
  8858. w = line.strip()
  8859. if len(w) == 5:
  8860. n += 1
  8861. print(n)
  8862. ```
  8863. How many words have 7 and how many 5 characters?
  8864. ```
  8865. fi = open('words.txt')
  8866. n = 0
  8867. x = 0
  8868. for line in fi:
  8869. w = line.strip()
  8870. if len(w) == 5:
  8871. n += 1
  8872. if len(w) == 7:
  8873. x += 1
  8874. print(n)
  8875. print(x)
  8876. ```
  8877. ## [DAY-139] While; List; Counter
  8878. First touchtype for 20 minutes.
  8879. Then do some chill turtle shapes.
  8880. ![game-139-2.png](./screenshots/game-139-2.png "game 139-2 screenshot")
  8881. ```
  8882. from turtle import *
  8883. speed(100000)
  8884. pencolor('cyan')
  8885. size = 66
  8886. while True:
  8887. forward(size)
  8888. left(size)
  8889. size += 1
  8890. ```
  8891. ![game-139-1.png](./screenshots/game-139-1.png "game 139-1 screenshot")
  8892. ```
  8893. from turtle import *
  8894. c = ['cyan','magenta']
  8895. dist = 20
  8896. hideturtle()
  8897. speed(11)
  8898. while True:
  8899. color(c[dist%2])
  8900. forward(dist)
  8901. left(90)
  8902. dist = dist-3
  8903. ```
  8904. ## [DAY-140] While; Turtle; Strings
  8905. Read the strings chapter in the Thinking Python book.
  8906. Then do some chill turtle shapes.
  8907. ![game-140-1.png](./screenshots/game-140-1.png "game 140-1 screenshot")
  8908. ```
  8909. import turtle
  8910. import random
  8911. turtles = []
  8912. for i in range(5):
  8913. a = turtle.Turtle()
  8914. a.speed(10000)
  8915. a.hideturtle()
  8916. turtles.append(a)
  8917. while True:
  8918. for x in turtles:
  8919. size = random.randint(10,300)
  8920. extent = random.randint(0, 360)
  8921. x.circle(size, extent=extent)
  8922. ```
  8923. ![game-140-2.png](./screenshots/game-140-2.png "game 140-2 screenshot")
  8924. ```
  8925. import turtle
  8926. import random
  8927. turtles = []
  8928. for i in range(5):
  8929. a = turtle.Turtle()
  8930. a.speed(10000)
  8931. a.hideturtle()
  8932. turtles.append(a)
  8933. while True:
  8934. for x in turtles:
  8935. size = random.randint(10,300)
  8936. for i in range(4):
  8937. x.forward(size)
  8938. x.right(90)
  8939. x.circle(size)
  8940. ```
  8941. ![game-140-3.png](./screenshots/game-140-3.png "game 140-3 screenshot")
  8942. ```
  8943. import turtle
  8944. import random
  8945. turtles = []
  8946. for i in range(5):
  8947. a = turtle.Turtle()
  8948. a.speed(10000)
  8949. a.hideturtle()
  8950. turtles.append(a)
  8951. while True:
  8952. for x in turtles:
  8953. size = random.randint(10,300)
  8954. for i in range(4):
  8955. x.forward(size)
  8956. x.right(90)
  8957. ```
  8958. ![game-140-4.png](./screenshots/game-140-4.png "game 140-4 screenshot")
  8959. ```
  8960. import turtle
  8961. import random
  8962. turtles = []
  8963. for i in range(5):
  8964. a = turtle.Turtle()
  8965. a.speed(10000)
  8966. a.hideturtle()
  8967. turtles.append(a)
  8968. while True:
  8969. for x in turtles:
  8970. size = random.randint(10,300)
  8971. x.circle(size)
  8972. ```
  8973. ## [DAY-141] Wiki; API
  8974. Today we are going to make a small app that uses wikipedia. First install the wikipedia package:
  8975. ```
  8976. pip3 install wikipedia
  8977. ```
  8978. ```
  8979. import wikipedia as wiki
  8980. while True:
  8981. what = input("search> ")
  8982. summary = wiki.summary(what)
  8983. print(summary)
  8984. print('*' * 40)
  8985. ```
  8986. Will search wikipeadia the string you input, like this:
  8987. ```
  8988. search> leonadro da vinci
  8989. Leonardo da Vinci (15 April 1452 – 2 May 1519) was an Italian polymath of...
  8990. [...]
  8991. search>
  8992. ```
  8993. Lets do the same but with pygame:
  8994. ![game-141.png](./screenshots/game-141.png "game 141 screenshot")
  8995. ```
  8996. import wikipedia as wiki
  8997. import pgzrun
  8998. HEIGHT = 800
  8999. WIDTH = 800
  9000. text = ''
  9001. info = ''
  9002. def on_key_down(key, mod, unicode):
  9003. global text, info
  9004. if key == keys.BACKSPACE:
  9005. if len(text) > 0:
  9006. text = text[:-1]
  9007. elif key == keys.RETURN:
  9008. info = wiki.summary(text)
  9009. text = ''
  9010. elif len(unicode) > 0 and ord(unicode) >= 32 and ord(unicode) <= 126:
  9011. text += unicode
  9012. def draw():
  9013. screen.clear()
  9014. screen.draw.text(info, (10,10), fontsize=18,fontname="437-win", width=WIDTH-20)
  9015. screen.draw.text(text, (WIDTH/2,HEIGHT - 40), color=(255,0,0), fontsize=30,fontname="437-win")
  9016. pgzrun.go()
  9017. ```
  9018. What does this do actually? How does the wikipedia module work? First thing you want to check is the documentation page, https://pypi.org/project/wikipedia/ and then you can also check the source code: https://github.com/goldsmith/Wikipedia
  9019. Next you would like to think, how would this python module download the data from wikipedia.
  9020. What it actually does, is it opens a web page, just a page that is specifically made to be easier to be read with programs, try to open: https://en.wikipedia.org/w/api.php?action=query&prop=extracts&format=json&explaintext=&titles=Dog which will be the page for `Dog`, you will see:
  9021. ```
  9022. {"batchcomplete":"","query":{"pages":{"4269567":{"pageid":4269567,"ns":0,"title":"Dog","extract":"The dog or domestic dog
  9023. [...]
  9024. an end to the dinosaurs and the appearance of the first carnivoran...
  9025. [...]
  9026. Their personality traits include hypersocial behavior, boldnes
  9027. [...]
  9028. ```
  9029. You can see the equivalent HTML page at https://en.wikipedia.org/wiki/Dog, The other page, which had structured data easier to read by python and any other programming language, is called API, Application Proggramming Interface. It just means that someone thought explicitly that their output will be read by programs and not people, and so they designed the interface that way. In the wikipedia example they return JSON.
  9030. JSON is data serialization format, its goal is to make it easy for programs to exchange data, for example I can have an array, or dictionary, and I want to make it easy for some other program to read it, so I use JSON to make it into text with special rules, and they can use their JSON decoder to make it into data.
  9031. ```
  9032. >>> import json
  9033. >>> a = {"a":"b","c":3}
  9034. >>>
  9035. >>> print(json.dumps([1,2,a]))
  9036. [1, 2, {"a": "b", "c": 3}]
  9037. >>>
  9038. >>> d = json.loads('[1, 2, {"a": "b", "c": 3}]')
  9039. >>> d
  9040. [1, 2, {'a': 'b', 'c': 3}]
  9041. ```
  9042. You see how it looks similar to the wikipedia API output, we will go in depth in the JSON format some times later, the point now is to just recognize that there is a whole world of APIs that are gluing the programs on your computer, and even the internet together so they can communicate. JSON is one of the most common serialization protocol, but there are many many more.
  9043. ## [DAY-142] While
  9044. today is again, chill turtle art
  9045. ever growing circle
  9046. ![game-142-1.png](./screenshots/game-142-1.png "game 142-1 screenshot")
  9047. ```
  9048. from turtle import *
  9049. speed(0)
  9050. size = 0
  9051. hideturtle()
  9052. while True:
  9053. size += 1
  9054. circle(size)
  9055. ```
  9056. evergrowing circle and also go into negative radius
  9057. ![game-142-2.png](./screenshots/game-142-2.png "game 142-2 screenshot")
  9058. ```
  9059. from turtle import *
  9060. speed(0)
  9061. size = 300
  9062. hideturtle()
  9063. while True:
  9064. size -= 1
  9065. circle(size)
  9066. ```
  9067. stop when the bottom circle is the same as the top one
  9068. ![game-142-3.png](./screenshots/game-142-3.png "game 142-3 screenshot")
  9069. ```
  9070. from turtle import *
  9071. speed(0)
  9072. size = 300
  9073. hideturtle()
  9074. while True:
  9075. size -= 1
  9076. circle(size)
  9077. if size < -300:
  9078. break
  9079. done()
  9080. ```
  9081. make the circles more edgy
  9082. ![game-142-4.png](./screenshots/game-142-4.png "game 142-4 screenshot")
  9083. ```
  9084. from turtle import *
  9085. import random
  9086. speed(0)
  9087. size = 300
  9088. hideturtle()
  9089. while True:
  9090. #size -= 1
  9091. circle(size, steps=random.randint(10,20))
  9092. if size < -300:
  9093. break
  9094. done()
  9095. ```
  9096. ## [DAY-143] Strings
  9097. Print the characters of a string one by one:
  9098. ```
  9099. a = 'hello'
  9100. for i in a:
  9101. print(i)
  9102. ```
  9103. Print the characters and their index:
  9104. ```
  9105. a = 'hello'
  9106. for i in range(0,len(a)):
  9107. print(i, a[i])
  9108. ```
  9109. Reverse the characters:
  9110. ```
  9111. a = 'hey'
  9112. rev = ''
  9113. for i in range(0,len(a)):
  9114. # i = 0
  9115. # a[2 - 0] -> a[2] -> y
  9116. # i = 1
  9117. # a[2 - 1] -> a[1] -> e
  9118. # i = 2
  9119. # a[2 - 2] -> a[0] -> h
  9120. print(i,a[len(a)-1-i])
  9121. rev +=a[len(a)-1-i]
  9122. print(rev)
  9123. ```
  9124. Google 'how to reverse a string in python'
  9125. ```
  9126. a = 'hello'
  9127. b = a[len(a)::-1]
  9128. print(b)
  9129. ```
  9130. check out the stackoverflow explanation at https://stackoverflow.com/questions/509211
  9131. Answer by Greg Hewgill, https://stackoverflow.com/users/893/greg-hewgill
  9132. ```
  9133. It's pretty simple really:
  9134. a[start:stop] # items start through stop-1
  9135. a[start:] # items start through the rest of the array
  9136. a[:stop] # items from the beginning through stop-1
  9137. a[:] # a copy of the whole array
  9138. There is also the step value, which can be used with any of the above:
  9139. a[start:stop:step] # start through not past stop, by step
  9140. The key point to remember is that the :stop value represents the first value that
  9141. is not in the selected slice. So, the difference between stop and start is the
  9142. number of elements selected (if step is 1, the default).
  9143. The other feature is that start or stop may be a negative number, which means it
  9144. counts from the end of the array instead of the beginning. So:
  9145. a[-1] # last item in the array
  9146. a[-2:] # last two items in the array
  9147. a[:-2] # everything except the last two items
  9148. Similarly, step may be a negative number:
  9149. a[::-1] # all items in the array, reversed
  9150. a[1::-1] # the first two items, reversed
  9151. a[:-3:-1] # the last two items, reversed
  9152. a[-3::-1] # everything except the last two items, reversed
  9153. Python is kind to the programmer if there are fewer items than you ask for. For example,
  9154. if you ask for a[:-2] and a only contains one element, you get an empty list instead of
  9155. an error. Sometimes you would prefer the error, so you have to be aware that this may happen.
  9156. Relation to slice() object
  9157. The slicing operator [] is actually being used in the above code with a slice() object
  9158. using the : notation (which is only valid within []), i.e.:
  9159. a[start:stop:step]
  9160. is equivalent to:
  9161. a[slice(start, stop, step)]
  9162. Slice objects also behave slightly differently depending on the number of arguments,
  9163. similarly to range(), i.e. both slice(stop) and slice(start, stop[, step]) are
  9164. supported. To skip specifying a given argument, one might use None, so that e.g.
  9165. a[start:] is equivalent to a[slice(start, None)] or a[::-1] is equivalent to
  9166. a[slice(None, None, -1)].
  9167. While the :-based notation is very helpful for simple slicing, the explicit use of
  9168. slice() objects simplifies the programmatic generation of slicing.
  9169. ```
  9170. ## [DAY-144] Strings; Lists
  9171. Sum the ascii of the elements of a list.
  9172. ```
  9173. a = ['h','e','l','l','o']
  9174. sum = 0
  9175. for i in a:
  9176. sum += ord(a)
  9177. print(sum)
  9178. ```
  9179. Print its index, and the letter with the corresponding ascii
  9180. ```
  9181. a = ['h','e','l','l','o']
  9182. sum = 0
  9183. for i in range(len(a)):
  9184. m = ord(a[i])
  9185. print('index: ', i, a[i], '=', m)
  9186. sum += m
  9187. print(sum)
  9188. ```
  9189. Now do the same with a string
  9190. ```
  9191. a = 'hello'
  9192. sum = 0
  9193. for i in range(len(a)):
  9194. m = ord(a[i])
  9195. print('index: ', i, a[i], '=', m)
  9196. sum += m
  9197. print(sum)
  9198. ```
  9199. See how lists and strings both have len() and are indexable, meaning you can go to a specific index a[i] and do something.
  9200. You can mutate (change) the list, meaning you can change its content
  9201. ```
  9202. a = ['h','e','l','o']
  9203. a[2] = 'b'
  9204. print(a)
  9205. ```
  9206. But you can not change a string inplace:
  9207. ```
  9208. a = 'hello'
  9209. a[2] = 'b'
  9210. print(a)
  9211. ```
  9212. You will get `TypeError: 'str' object does not support item assignment`. If you want to change a string, you have to make a new one and reasign the variable to point to the new string.
  9213. ```
  9214. a = 'hello'
  9215. a = a[0:2] + 'b' + a[3:5]
  9216. ```
  9217. See how we make completely new string, made up from the parts of the old string, and also the letter 'b' in the middle, and we make the variable `a` point to the new string.
  9218. ## [DAY-145] While
  9219. More turtle
  9220. ![game-145.png](./screenshots/game-145.png "game 145 screenshot")
  9221. ```
  9222. import turtle as t
  9223. import random
  9224. t.bgcolor('black')
  9225. t.pensize(6)
  9226. t.speed(0)
  9227. size = 20
  9228. colors =['cyan','royalblue','lawngreen','red','purple','white','yellow']
  9229. while True:
  9230. t.pencolor(random.choice(colors))
  9231. t.circle(size)
  9232. t.left(12)
  9233. size += 1
  9234. ```
  9235. ![game-145-2.png](./screenshots/game-145-2.png "game 145-2 screenshot")
  9236. ```
  9237. from turtle import *
  9238. size = 20
  9239. speed(0)
  9240. hideturtle()
  9241. while True:
  9242. size += 5
  9243. circle(size)
  9244. ```
  9245. ![game-145-3.png](./screenshots/game-145-3.png "game 145-3 screenshot")
  9246. ```
  9247. import turtle as t
  9248. size = 0
  9249. t.speed(0)
  9250. while True:
  9251. t.forward(size)
  9252. t.left(90)
  9253. size += 1
  9254. ```
  9255. Lets talk again about Memory.
  9256. ```
  9257. a = 'hello'
  9258. print(len(a))
  9259. a += 'b'
  9260. print(len(a))
  9261. print(a[2])
  9262. ```
  9263. First lets imagine a simplified representation of the string 'hello' in memory.
  9264. Lets imagine the computer memory as a long line of numbered boxes, so we can go directly to specific box
  9265. ```
  9266. [-------------------------------------------------------------------------]
  9267. 0 1024
  9268. ```
  9269. Each of the boxes can contain value between 0 and 255, so in order to store our string, we need at least 5 boxes, one for each letter, the memory does not understand such thing as character, only numnbers between 0 and 255, that is why we have the ASCII table, to have a standard how to represent characters as numbers in a common way. So we will store `h` which is 104 and, `e` which is 101, etc
  9270. Lets say that python finds out some free memory at address 555, and we just store 104,101,108,108,111, The problem with that is that we dont know when the string actually ends, so either we have to read to the first `0`, or we have to store the length of the string, and usually you store the length. So we will store the number 5, which we know is the length, and then the ASCII characters.
  9271. ```
  9272. [--------------5 104 101 108 108 111----------------------------------------------]
  9273. 0 ^ 1024
  9274. 555
  9275. ```
  9276. Now the variable `a` just points to box 555, when we do `len(a)` we can just read the number stored at this address, and when we do `a[1]` we can read the value at address `555 + 1 + 1` which will give us (101)
  9277. What happens now when we do `a += 'b'`, this is the same as `a = a + 'b'`, which means ok, lets make a new string, with size `6` copy the original string there, and then add `b` (which is 98 in ascii) to the end. So python will try to find a space in memory for at least 7 bytes (6 for the string, and one for the lenth), and do the copy.
  9278. ```
  9279. [--------------5 104 101 108 108 111------6 104 101 108 108 111 98----------------]
  9280. 0 ^ ^ 1024
  9281. 555 763
  9282. ```
  9283. Imagine the next free space in memory is on address 763, it will copy the data from address 556 to 560 to address 764 to 769, it will put `98` on address 770 and of course it will place the number `7` (the length of the new string), on address 763. And now we have a new string, it will just re-assign the variable `a` to point to 763 instead of 555. Now the string on address 555 is not referenecd by any variable, and if it is not used by anything else (e.g. a list that also points to it), it can be garbage collected, and memory can be marked as free.
  9284. Lets talk about this code:
  9285. ```
  9286. a = 'he'
  9287. b = 'lo'
  9288. c = 6
  9289. d = [a,b,c]
  9290. print(d[1])
  9291. ```
  9292. One way python could represent a list is very similar to a string, you have length, and just addressess of the elements
  9293. ```
  9294. [---3 555 763 847-----------2 104 101 ----------------2 108 111 ------6-----------]
  9295. 0 ^ ^ ^ ^ 1024
  9296. 125 555 763 847
  9297. ```
  9298. The variable d will point to address `125`, from there you have first element on address 555, second on 763 and third on 847, to do `print(d[1]`) means go to 125 + 1 + 1, and follow the pointer, so go to 555 ... and so on.
  9299. See there is a small problem because now python does not know if certain address contains a string, number or a list, so usually you need one more byte of information for the type of the object. Imagine 1 is for integer, 2 for string and 3 for list.
  9300. ```
  9301. [---3 2 555 763 847-------2 2 104 101 --------------2 2 108 111 -----1 6----------]
  9302. 0 ^ ^ ^ ^ 1024
  9303. 125 555 763 847
  9304. ```
  9305. ok now its eaier :) we know when we go to certain address of some data what to expect, so we know if we should print ascii or the number itself, or follow the reference to wherever it goes.
  9306. ## [DAY-146] While; Classes
  9307. Circles And Squares.
  9308. ![game-146.png](./screenshots/game-146.png "game 146 screenshot")
  9309. ```
  9310. import turtle as t
  9311. a = t.Turtle()
  9312. a.speed(0)
  9313. a.pencolor('fuchsia')
  9314. b = t.Turtle()
  9315. b.speed(0)
  9316. b.pencolor('mediumspringgreen')
  9317. c = t.Turtle()
  9318. c.speed(0)
  9319. c.pencolor('deepskyblue')
  9320. size = 30
  9321. while True:
  9322. a.forward(size*2)
  9323. a.left(90)
  9324. b.forward(size*3)
  9325. b.right(90)
  9326. c.forward(size*4)
  9327. c.right(90)
  9328. c.circle(size+1)
  9329. size += 2
  9330. ```
  9331. ![game-146-1.png](./screenshots/game-146-1.png "game 146-1 screenshot")
  9332. ```
  9333. import turtle as t
  9334. import random
  9335. a = t.Turtle()
  9336. a.speed(0)
  9337. b = t.Turtle()
  9338. b.speed(0)
  9339. b.hideturtle()
  9340. a.hideturtle()
  9341. b.pensize(5)
  9342. a.pensize(4)
  9343. b.pencolor('chocolate')
  9344. b.right(90)
  9345. b.forward(300)
  9346. size = 0
  9347. for i in range(70):
  9348. a.pencolor(random.choice(['red','orange','yellow','hotpink','magenta','deepskyblue','mediumspringgreen']))
  9349. b.right(180)
  9350. a.circle(size,extent=90)
  9351. a.forward(10)
  9352. a.right(5)
  9353. size += 1
  9354. t.done()
  9355. ```
  9356. ## [DAY-147] While
  9357. Another flower
  9358. ![game-147.png](./screenshots/game-147.png "game 147 screenshot")
  9359. ```
  9360. import turtle as t
  9361. a = t.Turtle()
  9362. a.speed(0)
  9363. a.right(90)
  9364. a.forward(300)
  9365. a.hideturtle()
  9366. b = t.Turtle()
  9367. b.speed(0)
  9368. b.hideturtle()
  9369. def square(charlie, size):
  9370. for i in range(4):
  9371. charlie.forward(size)
  9372. if i == 1:
  9373. charlie.write(str(size))
  9374. charlie.right(90)
  9375. size = 0
  9376. while True:
  9377. square(b,size)
  9378. b.right(9)
  9379. size += 1
  9380. if size > 125:
  9381. break
  9382. t.done()
  9383. ```
  9384. ## [DAY-148] Money
  9385. Every time you use something, ask yourself how does the company that made it make money. How can it be so expensive or so cheap, or worse, how can it be free.
  9386. Most of the things you own and use are made by for-profit companies, for-profit means that the company tries to maximize its revenue and profit. This is in contrast with non-profit organizations, which does not try to make more money than it needs in order to function. For example Wikipedia is run by Wikimedia Foundation, which is a non profit organization.
  9387. Revenue means how much money comes in the company by selling its products, and profit means the revenue minus the expenses it has to produce the product. For example, if we have a company to make video games, and we pay ourselves 1000 euro in salary, and we sell each video game for 2 euro, then if we sell 600 video games, we will have 1200 euro in revenue, and 200 euro in profit: `1200 revenue - 1000 expense = 200 profit`.
  9388. The profit also taxed, so we have to pay some percent from the profit to the government, lets say its 10%, so from 200 euro profit, we will pay 20 euro to the government, it will use those money to pay its employees, and pay for health insurance, social insurance, build infrastructure, and maybe small percent of those will go to research and development projects, such as CERN (a huge 30 kilometer underground tunnel with magnets, that smashes protons together to see what happens when they collide with speeds closer to the speed of light) or the international space station.
  9389. After all that, we will be left with 180 euro profit. Almost every for-profit organization will try to maximize this number, for example one way we can increase this is if we try to reduce the expenses, imagine we pay less for the developers and we pay them 800 euro instead of 1000, then it seems we will get 400 euro in profit (or 360 after tax), but maybe those developers will make a worse game, so we wont eb able to sell 600 copies, and we sell 450, and then instead of getting 400 profit we get `900 revenue - 800 expense = 100 profit`, or 90 after tax.
  9390. Now think about what it means for something to be free, like Fortnite, or Roblox, or TikTok or Instagram, or when something is sold below its production cost, like the PlayStation 3.
  9391. Lets take the PlayStation as an example, they were selling the console for 600$, but it cost them 840$ to produce, why would they do that? First think how Sony makes money, each game you buy for 60$ Sony gets 30%, so 18$ goes to sony, when you buy 20 games through the year, which is what an average person spends on video games, they get 360$ profit, so in one year they will break even after 1 year, but people use the same video console for multiple years, so every consecutive year they get more and more profit.
  9392. So on the surface it might seem like Sony is making money on the console itself, but this is actually not true.
  9393. Lets go over Roblox, how do they make money? Every developer that makes a game there is taking a cut from all the robux spent by players, and Roblox is taking 75.5% of each transaction, so when you buy something for 10$ roblox gets 7.5$ and the developer gets 2.5$. Roblox is distributed through Apple's app store, how does Apple make money? they take 30% of all payments made oh the platform, so apple will take 30% as well, so the 10$ you pay, 3$ go to Apple, 5.3$ goes to Roblox and 1.7$ goes to the developers (the content creators of roblox).
  9394. Now there are other companies, such as Facebook, where they actually do not sell you anything, but they sell you to their customers. They are selling the fact that they can make you do something you did not intend to do, like buy a skateboard or buy karaoke machine, so they use that to sell it to for-profit corporations who make skateboards and karaoke machines.
  9395. In order for them to do that, they need to be very very precise with their predictions, what exactly they can make you do and when. That requires immense amount of data, so they have to track every possible thing. For example when you are walking, your phone has an accelerometer that can see how is the phone oriented in space so just by that they can see when you are walking to somebody, or when you are in the same mall with somebody, or are you in school? which people are in the same school because the basket you put your phones in is the same for all students in your class, etc. They must record every time you scroll a video, or you hesitate to scroll.
  9396. Facebook makes about 30 euros per month for each user they are selling.
  9397. Homework:
  9398. * Why do you think whatsapp is free?
  9399. * Why is primary education free?
  9400. * Why is google translate free?
  9401. * Why is google maps free?
  9402. * Why is google search free?
  9403. * Why is fortnite free?
  9404. * Why is youtube free?
  9405. * How is tocaboca making money?
  9406. * How are the youtube content creators making money?
  9407. * How does H&M make money?
  9408. * How does the government make money?
  9409. A good thing to think about is also why are some things so expensive, how can we have smartphones for 50$ and for 2000$, what is the difference, Apple's hardware is surely expensive but is the difference between 32G phone ans 128G phone really that much? Why are the airpods 200$ when there are better headphones for 100$. Apple's physical product is not just the product you are buying, you are also buying the apple brand, which is valued very highly by the people. So even if somebody makes "better" product physically, it is not better overall, and many people still prefer Apple.
  9410. It is important to think about the product sa s combination of things, the physical/virtual product, the experience, the story, the brand, the scarcity, the timing.. everything is important.
  9411. Interestingly Apple first makes money by selling you the devices, and secondly they make money from each in-app purchase you do on those devices (e.g. robux or fortnite money). Apple made 33 billion dollars from the app store alone.
  9412. How much can a company optimize its profits? Some companies are abusing humans in the other end of the world so the product is cheaper and more competitive. The moment one company does that, all other companies have no option but to do the same thing so they are competitive. Imagine H&M or C&A, how come a jacket costs 20$? and it comes in all the way from China, it is made, loaded on a ship, sailed for 1 month and came to Rotterdam, where it was put on a truck and then an employee unloaded it and put it on display in the Mall, where they have to pay at least 20000$ per month rent. How much does the cotton cost? How much it costs to be picked from the plants, and then made into fabric, sewed and packed? How can the jacket be 20$?
  9413. This is called 'race to the bottom', when one company discovers a way to make their products cheaper, the other companies have to immidiately adapt otherwise they will lose their customers. Imagine tomorrow a new company comes and starts selling jackets for 15$, then H&M has to figure out how to make them for 15$ instead of 20$. Maybe H&M will make a contract with Apple and put 'APPLE IS THE BEST' on their jackets and then reduce the cost to 15$, or it will find a way to reduce the amount of cotton it uses, or will come up with more innovative technology to make the sewing cheaper, or it will hire cheaper labor. Sometimes they will say, oh lets sell online so we dont have to pay 20000$ per month for rent in the mall.
  9414. The 'race to the bottom' is very interesting, because it seems its making things cheaper and faster, but it is also decreasing the salaries as much as it possibly can, the salaries of the very same people who are also buying products. So they actually have less money to buy products, which makes it even more important to build cheaper products. But there are certain minimums, like raw resources needed, for example how much ground you have to grow cotton on is fixed.
  9415. Another thing that H&M can do, is simply talk with C&A and agree that they wont sell jackets below 20$, regardless how much it costs them to make, so if someone finds a way to make them for 15$ they will just make 5$ more profit, because the consumers can only chose between 20$ jackets. Or they can buy all other manufacturers of jackets and start selling jackets for 60$ instead of 20, purely because they can. The government has rules about how companies can merge together, and is trying to protect its citizens from situations like that, but it is very very difficult thing to regulate.
  9416. A lot of people in the world work as much as it is required so they do not get fired, and their employers pay them the minimum so they dont quit. The relationship between worker and employer is very complicated. You will see when you grow up, you will have jobs that you hate, and jobs that you love. Be especially carefull with the jobs that you love.
  9417. They say 'do what you love and never work a day in your life', but what they dont say, is that you are consuming that love, little by little, like an artist who is paid to draw something she thinks is ugly, she will need the money, and the real price the artist will pay is love. The love for your craft is not infinite. It is ok to hate your job, it is also ok to love your job.
  9418. You will study a lot of theories when you grow up, about how money flows, or how the free market works, or how the capitalist or socialist system is flawed, the most important thig to remember is to go back to first principles: `how is something made, who makes it and who profits from it`, and profit does not have to be money, could be anything that people value such as: comfort, status, fame, pride, etc.
  9419. You see those forces, of the companies competing to get cheaper, sometimes they forget.. why do people use their product, even worse, sometimes they forget what their product really is. And then a new company comes, like a candle in a dark night, usually its only few people, maybe 2 or 3, working from their parent's garage, that can see what those companies can not see anymore. This is called disrupting the market. When new force appears, previously unknown, and people rejoice. The big corporations grinding their wheels create the right conditions, the right pressure, so a diamond is formed.
  9420. You can be that person, that disrupts. Every time you create something that people want, you disrupt it a bit, and sometimes your creation will resonate with the people's frequency, this is called product market fit.
  9421. ## [DAY-149] Creators, Consumers and Ideas
  9422. Every human in the world has brilliant ideas, multiple ideas per week. Most of the ideas are not good, but everyone has few great ideas per week. The problem is that nobody executes on those ideas, they just get forgotten and disappear. The execution of an idea is the real deal, the idea on its own is almost worthless. How many people do you think had the Fortnite idea before Epic games? Oh lets build Minecraft and Counter Strike together and booom Fortnite is born, I bet hundreds of developers thought about it, and many of them could've made it, but.. they didn't.
  9423. Today we will talk about why people do not make their ideas into being, and just forget them. There are usually many reasons, one of them is they think they cant make it, or they think its not good, or people wont like it. The problem is, it is extremely hard to evaluate an idea that is not obviously bad, withot putting a lot of effort and time into execution to actually see if it is worth it.
  9424. Lets just think outloud about some ideas:
  9425. * Ninja Fortnite where you die if you are seen
  9426. * Fifa Minecraft where you can build your field
  9427. * Neighbourhood Nintendo Switch game exchange library
  9428. * 1 year photo collage with your friends, one photo per day from 5 people joined in a video
  9429. * Dog meeting app, so you know when your dog's best friend is on a walk, so you can go together
  9430. * Neighbourhood book exchange platform
  9431. * make/write an augmented reality book
  9432. * AR minecraft
  9433. * AR lasertag
  9434. Those ideas came out just in few minutes. Now how would you decide which ones to buld? First, my advice is, build what you want to build **right now**. Just looking at this list, I could start working on AR minecraft right after I finish writing this sentence, just thinking about it it made me excited. However when you jump like that into execution of an idea, and you expect it to resonate with other people, you will be wrong most of the time, bencause your frequency is different than other people, so they might not like what you like.
  9435. If you want your product to be used by other people, you first have to carefully research if they would actually use and pay for what you are going to build. The process is as follows:
  9436. * have an idea
  9437. * build a super duper simple prototype that is totally broken, but good enough to illustrate the idea
  9438. * use your prototype for some time
  9439. * ask your friends to use your prototype
  9440. * delete the prototype and start from scratch
  9441. * build MVP - minimum viable product, which is a somewhat polished prototype that you can show to more people
  9442. * ask for money as soon as possible, nothing says that people like your product like them paying money for it.
  9443. * ask people if they like it, figure out what they do and dont like, and go back to change your MVP while you build on it
  9444. * keep iterating on the MVP while you are building features on it, and at some point it will become product, instead of minimum viable product
  9445. even more simplified
  9446. * step 1: build something [ with feedback ]
  9447. * step 2: ask for feedback
  9448. * step 3: ask for money if you can
  9449. * step 4: goto step 1
  9450. In most cases (but not all), there is no better signal than people paying for your product. In some rare cases, you may be so ahead of the market, or have an insight which is invisible to others, that people don't even know they would pay for your product yet. The key question here is 'who do you ask', 'who are your users', 'how many are they in the world', 'how many you can reach with ads/marketing', 'how much are they willing to pay'. There is a lot of skill into figuring the answers to those questions.
  9451. If you want to make your idea not fail, you have to put in the effort, work with designers, and artists to help you build the MVP or the proof of concept. It is really hard to say if ideas fail because they are bad, or because the creators did not do a good job making it.
  9452. It is unprecedented, how few people are needed for an idea to come to life, sometimes only 1 person, a good developer, or designer is enough to completely make the MVP. A lot of that is because in the last 50 years we have dramatically improved the programming languages and tools. From assembler to python, from paint to photoshop, the productivity of a single person now is like an army of people in 1991.
  9453. A single person can change the world, most of the people however wont even try. 95% of the content in the internet is made by 5% of the people. 95% of the games in roblox is made by 5% of the players. The 5% is where all the fun is, I promise you, its like a rollercoaster.
  9454. ## [DAY-150] While; Classes
  9455. Circles And Squares.
  9456. ![game-150.png](./screenshots/game-150.png "game 150 screenshot")
  9457. ```
  9458. from turtle import *
  9459. bgcolor('black')
  9460. a = Turtle()
  9461. a.speed(0)
  9462. a.hideturtle()
  9463. b = Turtle()
  9464. b.speed(0)
  9465. b.hideturtle()
  9466. colorA = textinput('pencolor a',"what is your name?:")
  9467. colorB = textinput('pencolor b',"what is your name?:")
  9468. size = 0
  9469. while True:
  9470. b.pencolor(colorB)
  9471. b.forward(size*3)
  9472. b.left(91)
  9473. a.pencolor(colorA)
  9474. a.forward(size*10)
  9475. a.circle(size, 360)
  9476. a.left(500)
  9477. size += 1
  9478. ```
  9479. More circles
  9480. ![game-150-a.png](./screenshots/game-150-a.png "game 150-a screenshot")
  9481. ```
  9482. import turtle as t
  9483. t.bgcolor('black')
  9484. t.hideturtle()
  9485. size = -300
  9486. t.speed(0)
  9487. while True:
  9488. if size % 2 == 0:
  9489. t.pencolor('cyan')
  9490. else:
  9491. t.pencolor('magenta')
  9492. t.circle(size*3)
  9493. size += 1
  9494. ```
  9495. ## [DAY-151] Classes; While
  9496. ![game-151.png](./screenshots/game-151.png "game 151 screenshot")
  9497. First make a painting program where you can chose colors and draw rectangles
  9498. ```
  9499. import pgzrun
  9500. WIDTH = 800
  9501. HEIGHT = 800
  9502. elf = Actor('c1')
  9503. x = 0
  9504. y = 0
  9505. color = None
  9506. drop = []
  9507. size = 40
  9508. def update():
  9509. global color,size
  9510. if keyboard.W:
  9511. elf.y -= 5
  9512. if keyboard.S:
  9513. elf.y += 5
  9514. if keyboard.D:
  9515. elf.x += 5
  9516. if keyboard.A:
  9517. elf.x -= 5
  9518. if keyboard.C:
  9519. screen.clear()
  9520. if keyboard.SPACE and color != None:
  9521. drop.append([color, Rect(elf.x, elf.y, size, size)])
  9522. if keyboard.K_1:
  9523. color = (255,0,0)
  9524. if keyboard.K_2:
  9525. color = (25,41, 88)
  9526. if keyboard.K_8:
  9527. size += 1
  9528. if keyboard.K_9:
  9529. size -= 1
  9530. def draw():
  9531. screen.clear()
  9532. elf.draw()
  9533. for pixel in drop:
  9534. screen.draw.rect(pixel[1],pixel[0])
  9535. if color != None:
  9536. screen.draw.rect(Rect(elf.x,elf.y,size,size), color)
  9537. pgzrun.go()
  9538. ```
  9539. Same program but making a Pixel class instead of a list with color and rect.
  9540. ```
  9541. import pgzrun
  9542. WIDTH = 800
  9543. HEIGHT = 800
  9544. class Pixel:
  9545. def __init__(self, color, x, y, size):
  9546. self.color = color
  9547. self.rect = Rect(x,y,size,size)
  9548. def draw(self):
  9549. screen.draw.rect(self.rect, self.color)
  9550. elf = Actor('c1')
  9551. x = 0
  9552. y = 0
  9553. color = None
  9554. drop = []
  9555. size = 40
  9556. def update():
  9557. global color,size
  9558. if keyboard.W:
  9559. elf.y -= 5
  9560. if keyboard.S:
  9561. elf.y += 5
  9562. if keyboard.D:
  9563. elf.x += 5
  9564. if keyboard.A:
  9565. elf.x -= 5
  9566. if keyboard.C:
  9567. screen.clear()
  9568. if keyboard.SPACE and color != None:
  9569. pixel = Pixel(color, elf.x, elf.y, size)
  9570. drop.append(pixel)
  9571. if keyboard.K_1:
  9572. color = (255,0,0)
  9573. if keyboard.K_2:
  9574. color = (25, 41, 88)
  9575. if keyboard.K_8:
  9576. size += 1
  9577. if keyboard.K_9:
  9578. size -= 1
  9579. def draw():
  9580. screen.clear()
  9581. elf.draw()
  9582. for pixel in drop:
  9583. pixel.draw()
  9584. if color != None:
  9585. screen.draw.rect(Rect(elf.x,elf.y,size,size), color)
  9586. pgzrun.go()
  9587. ```
  9588. Go back in the book and re-read the class chapter.
  9589. Try out some ideas with a class, just to understand better what `self` is, for example play around with this Point class, try to add `move_right` or `move_up` methods.
  9590. ```
  9591. class Point:
  9592. def __init__(self, x, y):
  9593. self.x = x
  9594. self.y = y
  9595. def move(self,x,y):
  9596. self.x = x
  9597. self.y = y
  9598. def move_left(self):
  9599. self.x -= 1
  9600. def show(self):
  9601. print(self.x, self.y)
  9602. def equal(self, other_point):
  9603. if self.x == other_point.x and self.y == other_point.y:
  9604. return True
  9605. return False
  9606. p1 = Point(10,20)
  9607. p2 = Point(30,40)
  9608. p3 = Point(10,20)
  9609. p3.move(50,60)
  9610. p1.show()
  9611. p2.show()
  9612. p3.move_left()
  9613. p3.show()
  9614. print(p3.equal(p1))
  9615. ```
  9616. ---
  9617. Completely unrelated and just for fun, make a triangle like pattern:
  9618. ```
  9619. while True:
  9620. for i in range(0,10):
  9621. print(':3'* i)
  9622. for i in range(10,0,-1):
  9623. print(':D' * i)
  9624. ```
  9625. Prints infinite sequence of smilies
  9626. ```
  9627. :3
  9628. :3:3
  9629. :3:3:3
  9630. :3:3:3:3
  9631. :3:3:3:3:3
  9632. :3:3:3:3:3:3
  9633. :3:3:3:3:3:3:3
  9634. :3:3:3:3:3:3:3:3
  9635. :3:3:3:3:3:3:3:3:3
  9636. :D:D:D:D:D:D:D:D:D:D
  9637. :D:D:D:D:D:D:D:D:D
  9638. :D:D:D:D:D:D:D:D
  9639. :D:D:D:D:D:D:D
  9640. :D:D:D:D:D:D
  9641. :D:D:D:D:D
  9642. :D:D:D:D
  9643. :D:D:D
  9644. :D:D
  9645. :D
  9646. :3
  9647. :3:3
  9648. :3:3:3
  9649. :3:3:3:3
  9650. :3:3:3:3:3
  9651. :3:3:3:3:3:3
  9652. ...
  9653. ```
  9654. ## [DAY-152] Lists
  9655. ![game-152.png](./screenshots/game-152.png "game 152 screenshot")
  9656. Make 3 actors you can pick up and drop them wherever you hit SPACE.
  9657. ```
  9658. import pgzrun
  9659. WIDTH = 500
  9660. HEIGHT = 500
  9661. king = Actor('c2')
  9662. elf = Actor('c1')
  9663. flower = Actor('flower')
  9664. rock = Actor('rock')
  9665. king.x = 480
  9666. king.y = 125
  9667. flower.y = 380
  9668. flower.x = 480
  9669. rock.x = 480
  9670. rock.y = 250
  9671. drop = []
  9672. speed = 5
  9673. def update():
  9674. global speed
  9675. if keyboard.W:
  9676. elf.y -= speed
  9677. if keyboard.S:
  9678. elf.y += speed
  9679. if keyboard.D:
  9680. elf.x += speed
  9681. if keyboard.A:
  9682. elf.x -= speed
  9683. if keyboard.C:
  9684. screen.clear()
  9685. if elf.colliderect(king):
  9686. elf.image=king.image
  9687. speed = 2
  9688. if elf.colliderect(rock):
  9689. elf.image=rock.image
  9690. speed = 1
  9691. if elf.colliderect(flower):
  9692. elf.image=flower.image
  9693. speed = 10
  9694. if keyboard.SPACE and elf.image != 'c1':
  9695. a = Actor(elf.image)
  9696. a.x = elf.x
  9697. a.y = elf.y
  9698. drop.append(a)
  9699. elf.image='c1'
  9700. speed = 5
  9701. def draw():
  9702. screen.clear()
  9703. elf.draw()
  9704. king.draw()
  9705. flower.draw()
  9706. rock.draw()
  9707. for d in drop:
  9708. d.draw()
  9709. pgzrun.go()
  9710. ```
  9711. ## [DAY-153] Lists; Dictionaries
  9712. ![game-153.png](./screenshots/game-153.png "game 153 screenshot")
  9713. Find Waldo, here are two different implementations of the game, one uses dictionaries and one doesnt.
  9714. In this game, one of the actors has his back turned, and the purpose of the game is to find them.
  9715. We are using this example to practice lists, using `for element in list` and `for i in range(len(list))`, and overusing iterating over the list to find a matching element.
  9716. ```
  9717. import pgzrun
  9718. import random
  9719. WIDTH = 800
  9720. HEIGHT = 800
  9721. elf = Actor('c1')
  9722. elf.x = 400
  9723. elf.y = 400
  9724. drop = []
  9725. def on_key_down(key):
  9726. if key == keys.SPACE:
  9727. found = False
  9728. for i in drop:
  9729. if i.image == 'c2-back':
  9730. found = True
  9731. if not found:
  9732. a = Actor('c2-back')
  9733. a.x = random.randint(0,1500)
  9734. a.y = random.randint(0,1500)
  9735. drop.append(a)
  9736. for i in range(100):
  9737. a = Actor('c2')
  9738. a.x = random.randint(0,2000)
  9739. a.y = random.randint(0,2000)
  9740. drop.append(a)
  9741. if key == keys.P:
  9742. for i in drop:
  9743. if i.image == 'c2-back':
  9744. i.x = random.randint(elf.x - 200,elf.x + 200)
  9745. i.y = random.randint(elf.y - 200,elf.y + 200)
  9746. waldo_found = False
  9747. def update():
  9748. global waldo_found
  9749. if keyboard.W:
  9750. for x in range(len(drop)):
  9751. i = drop[x]
  9752. i.y += 5
  9753. if keyboard.S:
  9754. for a in range(len(drop)):
  9755. drop[a].y -= 5
  9756. if keyboard.A:
  9757. for i in drop:
  9758. i.x += 5
  9759. if keyboard.D:
  9760. for i in drop:
  9761. i.x -= 5
  9762. for i in drop:
  9763. if i.image == 'c2-back' and elf.colliderect(i):
  9764. waldo_found = True
  9765. def draw():
  9766. screen.fill('black')
  9767. elf.draw()
  9768. for i in drop:
  9769. i.draw()
  9770. if waldo_found == True:
  9771. screen.draw.text(" YOU HAVE FOUND WALDO ", (10,10))
  9772. pgzrun.go()
  9773. ```
  9774. A second implementation where we use a `waldo` variable so we dont have to scan the list of actors so many times, and also we move the elf instead of moving all the actors. And we use a dictionary with positions to try to avoid adding an actor close to already existing one.
  9775. ```
  9776. import pgzrun
  9777. import random
  9778. WIDTH = 800
  9779. HEIGHT = 800
  9780. elf = Actor('c1')
  9781. elf.x = 400
  9782. elf.y = 400
  9783. drop = []
  9784. waldo = Actor('c2-back')
  9785. seen = {}
  9786. def on_key_down(key):
  9787. if key == keys.SPACE:
  9788. waldo.x = random.randint(0,WIDTH)
  9789. waldo.y = random.randint(0,HEIGHT)
  9790. place = str(int(waldo.x/50)) + "_" + str(int(waldo.y/100))
  9791. seen[place] = True
  9792. for i in range(100):
  9793. x = random.randint(0,WIDTH)
  9794. y = random.randint(0,HEIGHT)
  9795. place = str(int(x/50)) + "_" + str(int(y/100))
  9796. if place not in seen:
  9797. a = Actor('c2')
  9798. a.x = x
  9799. a.y = y
  9800. drop.append(a)
  9801. seen[place] = True
  9802. waldo_found = False
  9803. def update():
  9804. global waldo_found
  9805. if keyboard.W:
  9806. elf.y -= 5
  9807. if keyboard.S:
  9808. elf.y += 5
  9809. if keyboard.A:
  9810. elf.x -= 5
  9811. if keyboard.D:
  9812. elf.x += 5
  9813. if waldo.colliderect(elf):
  9814. waldo_found = True
  9815. def draw():
  9816. screen.fill('black')
  9817. elf.draw()
  9818. for i in drop:
  9819. i.draw()
  9820. waldo.draw()
  9821. if waldo_found == True:
  9822. screen.draw.text(" YOU HAVE FOUND WALDO ", (10,10))
  9823. pgzrun.go()
  9824. ```
  9825. ## [DAY-154] Classes
  9826. Pacman, make things move around, stop when they hit something
  9827. ![game-154.png](./screenshots/game-154.png "game 154 screenshot")
  9828. ```
  9829. import random
  9830. import pgzrun
  9831. WIDTH = 600
  9832. HEIGHT = 600
  9833. game_over = False
  9834. lives = 3
  9835. obsticles = [
  9836. Rect(100,100,20,20),
  9837. Rect(200,200,100,200),
  9838. ]
  9839. class Mover:
  9840. def __init__(self, image, x, y, direction):
  9841. self.actor = Actor(image)
  9842. self.direction = direction
  9843. self.actor.x = x
  9844. self.actor.y = y
  9845. self.counter = 0
  9846. def draw(self):
  9847. self.actor.draw()
  9848. def update(self):
  9849. orig_x = self.actor.x
  9850. orig_y = self.actor.y
  9851. self.counter += 1
  9852. if self.counter > 120 and self.actor.image == "c2":
  9853. self.direction = random.choice(['up','down','left','right'])
  9854. self.counter = 0
  9855. if self.direction == 'up':
  9856. self.actor.y -= 1
  9857. if self.direction == 'down':
  9858. self.actor.y += 1
  9859. if self.direction == 'left':
  9860. self.actor.x -= 1
  9861. if self.direction == 'right':
  9862. self.actor.x += 1
  9863. if self.actor.x > WIDTH:
  9864. self.actor.x = 0
  9865. if self.actor.x < 0:
  9866. self.actor.x = WIDTH
  9867. if self.actor.y > HEIGHT:
  9868. self.actor.y = 0
  9869. if self.actor.y < 0:
  9870. self.actor.y = HEIGHT
  9871. hit_wall = False
  9872. for o in obsticles:
  9873. if self.actor.colliderect(o):
  9874. self.actor.x = orig_x
  9875. self.actor.y = orig_y
  9876. hit_wall = True
  9877. break
  9878. if hit_wall and self.actor.image == "c2":
  9879. self.direction = random.choice(['up','down','left','right'])
  9880. pacman = Mover("c1", 10, 10, 'up')
  9881. movers = [pacman,
  9882. Mover("c2", 100, 40, 'up'),
  9883. Mover("c2", 100, 50, 'up'),
  9884. Mover("c2", 100, 60, 'up'),
  9885. Mover("c2", 100, 70, 'up')
  9886. ]
  9887. def update():
  9888. global lives,game_over
  9889. if keyboard.W:
  9890. pacman.direction = 'up'
  9891. if keyboard.S:
  9892. pacman.direction = 'down'
  9893. if keyboard.A:
  9894. pacman.direction = 'left'
  9895. if keyboard.D:
  9896. pacman.direction = 'right'
  9897. for m in movers:
  9898. m.update()
  9899. for o in movers:
  9900. if pacman.actor.colliderect(o.actor) and o != pacman:
  9901. lives -= 1
  9902. pacman.actor.x = 0
  9903. pacman.actor.y = 0
  9904. if lives < 0:
  9905. game_over = True
  9906. def draw():
  9907. screen.fill('black')
  9908. for o in obsticles:
  9909. screen.draw.filled_rect(o,(255,0,0))
  9910. screen.draw.text('lives: ' + str(lives), (10,10))
  9911. if game_over == True:
  9912. screen.fill('royalblue')
  9913. screen.draw.text('GAME OVER YOU LOST',(10,10))
  9914. for m in movers:
  9915. m.draw()
  9916. pgzrun.go()
  9917. ```
  9918. ## [DAY-155] c++
  9919. First lets discuss a bit about the difference between `c++` and `python`. For example, lets examine what happens with the following program:
  9920. ```
  9921. while True:
  9922. print("hello world")
  9923. ```
  9924. If you save it in the file `hello.py`, and you have to start it with `python hello.py`. Python is a program on its own, which will load the `hello.py` file and execute it line by line. The `python` program is called `interpreter` because it interprets the code, kind of like when you read a program, trying to find out what it does, you interpret the code in your head and evaluate it.
  9925. `c` and `c++` on the other hand are compiled languages, you need a program `gcc` for c and `g++` for c++ to transform your source code to machine code, that your computer will directly run, instruction by instruction, `gcc` and `g++` are compilers.
  9926. Lets start where everything starts, print "Hello World". Save the following program in a file `hello.cpp` (cpp for c plus plus).
  9927. ```
  9928. #include <iostream>
  9929. using namespace std;
  9930. int main(void) {
  9931. cout << "Hello World " << endl;
  9932. }
  9933. ```
  9934. Now lets compile it, `g++ -o hello hello.cpp` will make a program `hello` that you will be able to execute by running `./hello` you see it is very different, you run directly `hello` which will make your computer execute its instructions one by one, which is very different than running python to load your `hello.py`, in the python case your computer is running the python executable which loads your `hello.py` and interprets it line by line.
  9935. `int main()` declares the `main` function, each c/c++ program must have a main() function, thats where your program starts, unlike python, where it starts from the top of the file. You can think of your processor jumping to the address of the main function in memory, as we spoke in the previous lessons, in the computer's memoruy code is data, and data is code.
  9936. `cout` means `character output` and `<<` means `pour into the cout` whatever follows, e.g. `cout << 5` will just print 5, `cout "hello"` will print hello, `cout << 5 << "hello"` will print 5hello, and `endl` inserts the newline character `\n`.
  9937. `using namespace std;` is similar to from `turtle import *`, we will get into it later
  9938. And very importantly you `c++` does not care about your spaces, the following program compiles just fine
  9939. ```
  9940. #include <iostream>
  9941. using namespace std;int main(void) {cout << "Hello World " << endl;}
  9942. ```
  9943. Each code block is surrounded by `{}` and each statement ends with `;` and thats it
  9944. Try out the following programs, and just experiment with them using your python knowledge. (hint: `int` means integer)
  9945. ```
  9946. #include <iostream>
  9947. using namespace std;
  9948. int main(void) {
  9949. int i = 1000;
  9950. while(i) {
  9951. if (i < 500) {
  9952. cout << "HIII" << endl;
  9953. } else {
  9954. cout << "Hello World " << i << endl;
  9955. }
  9956. i--;
  9957. }
  9958. }
  9959. ```
  9960. ```
  9961. #include <iostream>
  9962. using namespace std;
  9963. int main(void) {
  9964. for (int i = 1000; i >= 0 ; i--) {
  9965. if (i < 500) {
  9966. cout << "HIII " << i << endl;
  9967. } else {
  9968. cout << "Hello World " << i << endl;
  9969. }
  9970. }
  9971. return 0;
  9972. }
  9973. ```
  9974. ## [DAY-156] for; while
  9975. Write the same code with for and while loops.
  9976. ```
  9977. #include <iostream>
  9978. using namespace std;
  9979. int main(void) {
  9980. int x = 3;
  9981. while(x < 3000000){
  9982. cout << x << endl;
  9983. x = x+3;
  9984. }
  9985. return 0;
  9986. }
  9987. ```
  9988. ```
  9989. #include <iostream>
  9990. using namespace std;
  9991. int main(void) {
  9992. for (int x = 0; x < 3000000; x = x + 3) {
  9993. cout << x << endl;
  9994. }
  9995. return 0;
  9996. }
  9997. ```
  9998. <hr>
  9999. ```
  10000. #include <iostream>
  10001. using namespace std;
  10002. int main(void) {
  10003. for (int x = 10; x > 0; x = x - 1) {
  10004. cout << x << endl;
  10005. }
  10006. return 0;
  10007. }
  10008. ```
  10009. ```
  10010. #include <iostream>
  10011. using namespace std;
  10012. int main(void) {
  10013. int x = 10;
  10014. while(x > 0){
  10015. cout << x << endl;
  10016. x -= 1;
  10017. }
  10018. return 0;
  10019. }
  10020. ```
  10021. <hr>
  10022. ```
  10023. #include <iostream>
  10024. using namespace std;
  10025. int main(void) {
  10026. int x = 0;
  10027. while (x < 10) {
  10028. cout << x << endl;
  10029. x+=1;
  10030. }
  10031. return 0;
  10032. }
  10033. ```
  10034. ```
  10035. #include <iostream>
  10036. using namespace std;
  10037. int main(void) {
  10038. for(int x = 0; x < 10; x += 1){
  10039. cout << x << endl;
  10040. }
  10041. return 0;
  10042. }
  10043. ```
  10044. ## [DAY-157] strings; cin
  10045. Make love tester in python:
  10046. ```
  10047. while True:
  10048. sum = 0
  10049. name1 = input('name 1: ')
  10050. name2 = input('name 2: ')
  10051. for i in range(len(name1)):
  10052. sum += ord(name1[i])
  10053. for i in range(len(name2)):
  10054. sum += ord(name2[i])
  10055. match = 1 + (sum % 100)
  10056. print("love test result:")
  10057. print(match)
  10058. ```
  10059. Write the same program in c++:
  10060. ```
  10061. #include <iostream>
  10062. using namespace std;
  10063. int main()
  10064. {
  10065. while(1) {
  10066. string name1;
  10067. string name2;
  10068. cout << "name1: ";
  10069. cin >> name1;
  10070. cout << "name2: ";
  10071. cin >> name2;
  10072. int sum = 0;
  10073. for (int i = 0; i < name1.size(); i++) {
  10074. sum += name1[i];
  10075. }
  10076. for (int i = 0; i < name2.size(); i++) {
  10077. sum += name2[i];
  10078. }
  10079. int match = 1 + (sum % 100);
  10080. cout << "love test result:" << endl;
  10081. cout << match << endl;
  10082. }
  10083. }
  10084. ```
  10085. `cin` is `character input`, you can perform a read operation by geting data out of cin with `>>`. Both `cin` and `cout` are streams. We will talk more about it later. For now just remember `cin >> variable` will read from the input and put the value in `variable`, and `cout << variable` will print the value of the variable.
  10086. ## [DAY-158] if; while
  10087. rock paper scissors again
  10088. ```
  10089. import random
  10090. options = ['rock','paper','scissors']
  10091. while True:
  10092. player = input(' '.join(options) + ': ')
  10093. if player not in options:
  10094. print("i dont know what to do with " + player)
  10095. continue
  10096. computer = random.choice(options)
  10097. print(computer)
  10098. if player == computer:
  10099. print("its a tie!")
  10100. if player == 'rock':
  10101. if computer == 'paper':
  10102. print('U lose the round')
  10103. elif computer == 'scissors':
  10104. print('U win this round')
  10105. if player == 'paper':
  10106. if computer == 'rock':
  10107. print('U win this round')
  10108. elif computer == 'scissors':
  10109. print('U lose the round')
  10110. if player == 'scissors':
  10111. if computer == 'rock':
  10112. print('U lose the round')
  10113. elif computer == 'paper':
  10114. print('U win this round')
  10115. ```
  10116. sum things
  10117. ```
  10118. data = ['hello','world','earth']
  10119. r = ''
  10120. for d in data:
  10121. r += d
  10122. print(r)
  10123. data = [1,2,3]
  10124. r = 0
  10125. for d in data:
  10126. r += d
  10127. print(r)
  10128. data = [[1,2],[3,4],[5,6]]
  10129. r = []
  10130. for d in data:
  10131. r += d
  10132. print(r)
  10133. ```
  10134. The pattern, start with an empty result, iterate over the list and append append to the result is very very common. Examine the above code and notice how the part where it adds to the result is the same regardless if the list is list of strings, integers or list of lists
  10135. ## [DAY-159] strings; sizeof
  10136. Back to basics, how are strings layed out in memory, and how many bytes the primitive types occupy in memory:
  10137. ```
  10138. #include <iostream>
  10139. using namespace std;
  10140. int main(void) {
  10141. char c = 'a';
  10142. int x = 'a';
  10143. bool b = true;
  10144. int sum = 0;
  10145. long l = 1;
  10146. short s = 1;
  10147. float f = 0.555;
  10148. double d = 0.4123123;
  10149. long double ld = 0.123123;
  10150. cout << "char" << sizeof(c) << endl;
  10151. cout << "bool" << sizeof(b) << endl;
  10152. cout << "int" << sizeof(sum) << endl;
  10153. cout << "short" << sizeof(s) << endl;
  10154. cout << "long" << sizeof(l) << endl;
  10155. cout << "float" << sizeof(f) << endl;
  10156. cout << "double" << sizeof(d) << endl;
  10157. cout << "long double" << sizeof(ld) << endl;
  10158. int ages[10]= {10,12,10,9,10,12,12,2,3,2};
  10159. cout << sizeof(ages) << endl;;
  10160. long double z[5] = {0,0,0,0,0};
  10161. cout << sizeof(z) << endl;;
  10162. char s1[10] = {'h','e','l','l','o','w','o','r','d','\0'};
  10163. char s2[] = "helloword";
  10164. cout << s1 << endl;
  10165. cout << s2 << endl;
  10166. }
  10167. ```
  10168. <hr>
  10169. argc and argv
  10170. ```
  10171. #include <iostream>
  10172. using namespace std;
  10173. int main(int argc, char* argv[]) {
  10174. cout << "Have " << argc << " arguments:" << endl;
  10175. cout << "my name is: " << argv[0] << endl;
  10176. for (int i = 0; i < argc; ++i) {
  10177. cout << i << ": " << argv[i] << endl;
  10178. }
  10179. return 0;
  10180. }
  10181. ```
  10182. Compile the the program above as `g++ -o xyz file.cpp`, and run it with `./xyz hello world "aaa bbbb cccc" ddd`. You see `g++` has a `main` function as well, and it has `argc` and `argv` as well.
  10183. <hr>
  10184. Formatting example:
  10185. ```
  10186. #include <iostream>
  10187. #include <iomanip>
  10188. using namespace std;
  10189. int main(void) {
  10190. for (int fahr=0; fahr<=100; fahr+=10){
  10191. cout<< endl
  10192. << setw(6)
  10193. << setprecision(0)
  10194. << fahr
  10195. << setw(10)
  10196. << setprecision(3)
  10197. << 5.0/9.0 * (fahr-32.0);
  10198. }
  10199. cout << endl;
  10200. return(0);
  10201. }
  10202. ```
  10203. ## [DAY-160] pointers
  10204. c/c++ pointes and arrays are sometimes confusing, we will come back to them multiple times, especially because strings are pointers to arrays of characters, it is important for the concept to "click". Do not worry if you dont get it at first (or at second, or at third) attempt.
  10205. There are two important operators '*' and '&', `int *pa = &a` means we have a pointer (`*`) to a variable of type `int` equal to the address (`&`) of variable `a`. The value of `pa` is just a number, it is literally the address of the memory where the value of `a` will be.
  10206. The most important concept is that `pa` is actually just a number, this is the actual value of `pa`, and with `*pa = 5` means, go to this place in memory and put 5 there, we can literally go anywhere in memory and put some value there.
  10207. Arrays are a continuous chunks of memory, `char b[10]` means `b` is a pointer to somewhere in memory where you hold `10` slots of type `char` which is 10 bytes. so `b` actually just holds the location of those 10 bytes. Thats right, `b` is a pointer, we can do `b[2] = 'a'` or `*(b + 2) = 'a'` they are the same thing, as `b[2]` means go to wherever `b` points to, and add 2 slots of `b`'s type, same as `*(b + 2)`.
  10208. Examine the following program:
  10209. ```
  10210. #include <iostream>
  10211. using namespace std;
  10212. int main(int argc, char* argv[]) {
  10213. int a = 7;
  10214. int *pa = &a;
  10215. *pa = 8;
  10216. cout << a << endl;
  10217. int b[8] = {10,11,12,13,14,15,16,17};
  10218. cout << b << endl;
  10219. cout << (b + 3) << endl;
  10220. cout << *(b + 3) << endl;
  10221. cout << b[3] << endl;
  10222. return 0;
  10223. }
  10224. ```
  10225. ## [DAY-161] if; while; functions
  10226. Tic tac toe with 9 variables, one for each position of the grid.
  10227. This is how the gameplay should look:
  10228. ```
  10229. a b c
  10230. 0 - - -
  10231. 1 - - -
  10232. 2 - - -
  10233. [x] enter position (row col): 0 a
  10234. a b c
  10235. 0 x - -
  10236. 1 - - -
  10237. 2 - - -
  10238. [0] enter position (row col): 0 b
  10239. a b c
  10240. 0 x 0 -
  10241. 1 - - -
  10242. 2 - - -
  10243. [x] enter position (row col): 1 a
  10244. a b c
  10245. 0 x 0 -
  10246. 1 x - -
  10247. 2 - - -
  10248. [0] enter position (row col): 1 b
  10249. a b c
  10250. 0 x 0 -
  10251. 1 x 0 -
  10252. 2 - - -
  10253. [x] enter position (row col): 2 a
  10254. a b c
  10255. 0 x 0 -
  10256. 1 x 0 -
  10257. 2 x - -
  10258. x wins!
  10259. ```
  10260. And this is the code:
  10261. ```
  10262. #include <iostream>
  10263. using namespace std;
  10264. void render(char g0, char g1, char g2, char g3, char g4, char g5, char g6, char g7, char g8) {
  10265. cout << " a b c" << endl;
  10266. cout << "0 " << g0 << " " << g1 << " " << g2 << endl;
  10267. cout << "1 " << g3 << " " << g4 << " " << g5 << endl;
  10268. cout << "2 " << g6 << " " << g7 << " " << g8 << endl;
  10269. }
  10270. bool wins(char symbol, char g0, char g1, char g2, char g3, char g4, char g5, char g6, char g7, char g8) {
  10271. if (g0 == symbol && g1 == symbol && g2 == symbol) {
  10272. return true;
  10273. }
  10274. if (g0 == symbol && g3 == symbol && g6 == symbol) {
  10275. return true;
  10276. }
  10277. if (g0 == symbol && g4 == symbol && g8 == symbol) {
  10278. return true;
  10279. }
  10280. if (g1 == symbol && g4 == symbol && g7 == symbol) {
  10281. return true;
  10282. }
  10283. if (g2 == symbol && g5 == symbol && g8 == symbol) {
  10284. return true;
  10285. }
  10286. if (g3 == symbol && g4 == symbol && g5 == symbol) {
  10287. return true;
  10288. }
  10289. if (g6 == symbol && g7 == symbol && g8 == symbol) {
  10290. return true;
  10291. }
  10292. if (g6 == symbol && g4 == symbol && g2 == symbol) {
  10293. return true;
  10294. }
  10295. return false;
  10296. }
  10297. int main(void) {
  10298. char g0,g1,g2,g3,g4,g5,g6,g7,g8;
  10299. g0 = g1 = g2 = g3 = g4 = g5 = g6 = g7 = g8 = '-';
  10300. char symbol = 'x';
  10301. while(1) {
  10302. render(g0,g1,g2,g3,g4,g5,g6,g7,g8);
  10303. char row,col;
  10304. cout << "[" << symbol << "] enter position (row col): ";
  10305. cin >> row >> col;
  10306. cout << endl;
  10307. if (row == '0') {
  10308. if (col == 'a') {
  10309. g0 = symbol;
  10310. }
  10311. if (col == 'b') {
  10312. g1 = symbol;
  10313. }
  10314. if (col == 'c') {
  10315. g2 = symbol;
  10316. }
  10317. }
  10318. if (row == '1') {
  10319. if (col == 'a') {
  10320. g3 = symbol;
  10321. }
  10322. if (col == 'b') {
  10323. g4 = symbol;
  10324. }
  10325. if (col == 'c') {
  10326. g5 = symbol;
  10327. }
  10328. }
  10329. if (row == '2') {
  10330. if (col == 'a') {
  10331. g6 = symbol;
  10332. }
  10333. if (col == 'b') {
  10334. g7 = symbol;
  10335. }
  10336. if (col == 'c') {
  10337. g8 = symbol;
  10338. }
  10339. }
  10340. if (wins(symbol,g0,g1,g2,g3,g4,g5,g6,g7,g8)) {
  10341. render(g0,g1,g2,g3,g4,g5,g6,g7,g8);
  10342. cout << symbol << " wins!" << endl;
  10343. break;
  10344. }
  10345. if (symbol == 'x') {
  10346. symbol = '0';
  10347. } else {
  10348. symbol = 'x';
  10349. }
  10350. }
  10351. return 0;
  10352. }
  10353. ```
  10354. ## [DAY-162] if; while; variables
  10355. Make Tic Tac Toe in python using 9 variables; Completely on your own.
  10356. > (this is the code that she wrote)
  10357. ```
  10358. def board(a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10359. print(' ',1,2,3)
  10360. print('a ',a1,a2,a3)
  10361. print('b ',b1,b2,b3)
  10362. print('c ',c1,c2,c3)
  10363. def game():
  10364. a1 = '-'
  10365. a2 = '-'
  10366. a3 = '-'
  10367. b1 = '-'
  10368. b2 = '-'
  10369. b3 = '-'
  10370. c1 = '-'
  10371. c2 = '-'
  10372. c3 = '-'
  10373. xz = 'x'
  10374. while True:
  10375. board(a1,a2,a3,b1,b2,b3,c1,c2,c3)
  10376. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10377. if ask == 'a1':
  10378. a1 = xz
  10379. if ask == 'a2':
  10380. a2 = xz
  10381. if ask == 'a3':
  10382. a3 = xz
  10383. if ask == 'b1':
  10384. b1 = xz
  10385. if ask == 'b2':
  10386. b2 = xz
  10387. if ask == 'b3':
  10388. b3 = xz
  10389. if ask == 'c1':
  10390. c1 = xz
  10391. if ask == 'c2':
  10392. c2 = xz
  10393. if ask == 'c3':
  10394. c3 = xz
  10395. if a1 == xz and a2 == xz and a3 == xz:
  10396. print(xz+ ' Wins 🥳🥳🥳')
  10397. break
  10398. if a3 == xz and b3 == xz and c3 == xz:
  10399. print(xz+ ' Wins 🥳🥳🥳')
  10400. break
  10401. if a2 == xz and b2 == xz and c2 == xz:
  10402. print(xz+ ' Wins 🥳🥳🥳')
  10403. break
  10404. if a1 == xz and b1 == xz and c1 == xz:
  10405. print(xz+ ' Wins 🥳🥳🥳')
  10406. break
  10407. if c1 == xz and c2 == xz and c3 == xz:
  10408. print(xz+ ' Wins 🥳🥳🥳')
  10409. break
  10410. if b1 == xz and b2 == xz and b3 == xz:
  10411. print(xz+ ' Wins 🥳🥳🥳')
  10412. break
  10413. if c1 == xz and b2 == xz and a3 == xz:
  10414. print(xz+ ' Wins 🥳🥳🥳')
  10415. break
  10416. if a1 == xz and b2 == xz and c3 == xz:
  10417. print(xz+ ' Wins 🥳🥳🥳')
  10418. break
  10419. if xz == 'x':
  10420. xz = '0'
  10421. else:
  10422. xz = 'x'
  10423. game()
  10424. ```
  10425. Another way to write the same program, using few function.
  10426. ```
  10427. def print_board(a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10428. print(' ',1,2,3)
  10429. print('a ',a1,a2,a3)
  10430. print('b ',b1,b2,b3)
  10431. print('c ',c1,c2,c3)
  10432. def win(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10433. if a1 == xz and a2 == xz and a3 == xz:
  10434. return True
  10435. if a3 == xz and b3 == xz and c3 == xz:
  10436. return True
  10437. if a2 == xz and b2 == xz and c2 == xz:
  10438. return True
  10439. if a1 == xz and b1 == xz and c1 == xz:
  10440. return True
  10441. if c1 == xz and c2 == xz and c3 == xz:
  10442. return True
  10443. if b1 == xz and b2 == xz and b3 == xz:
  10444. return True
  10445. if c1 == xz and b2 == xz and a3 == xz:
  10446. return True
  10447. if a1 == xz and b2 == xz and c3 == xz:
  10448. return True
  10449. return False
  10450. def get_input(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10451. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10452. if ask == 'a1':
  10453. a1 = xz
  10454. if ask == 'a2':
  10455. a2 = xz
  10456. if ask == 'a3':
  10457. a3 = xz
  10458. if ask == 'b1':
  10459. b1 = xz
  10460. if ask == 'b2':
  10461. b2 = xz
  10462. if ask == 'b3':
  10463. b3 = xz
  10464. if ask == 'c1':
  10465. c1 = xz
  10466. if ask == 'c2':
  10467. c2 = xz
  10468. if ask == 'c3':
  10469. c3 = xz
  10470. return a1,a2,a3,b1,b2,b3,c1,c2,c3
  10471. def game():
  10472. a1 = a2 = a3 = b1 = b2 = b3 = c1 = c2 = c3 = '-'
  10473. xz = 'x'
  10474. while True:
  10475. print_board(a1,a2,a3,b1,b2,b3,c1,c2,c3)
  10476. a1,a2,a3,b1,b2,b3,c1,c2,c3 = get_input(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3)
  10477. if win(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10478. print(xz + " WINS 🥳🥳🥳!!!")
  10479. break
  10480. if xz == 'x':
  10481. xz = '0'
  10482. else:
  10483. xz = 'x'
  10484. game()
  10485. ```
  10486. Now the game loop is very obvious:
  10487. * print the board
  10488. * get the input and modify the variables
  10489. * check if there is a winnner
  10490. * swap the symbol (from x to 0 and from 0 to x)
  10491. But in the same time, when you read the functions it is a bit confusing what is a1 a2 a3.. etc. This is ok for such a small program, either way works fine, but when programs grow you have to think about 'wait if someone is reading this function, will it make sense', 'will my variable names make sense to someone else'.
  10492. ## [DAY-163] if; while; lists
  10493. Do the same tic tac toe but with a list instead of 9 variables
  10494. ![game-163.png](./screenshots/game-163.png "game 163 screenshot")
  10495. > (this is the code that she wrote)
  10496. ```
  10497. def board(g):
  10498. print(' ',1,2,3)
  10499. print('a ',g[0],g[1],g[2])
  10500. print('b ',g[3],g[4],g[5])
  10501. print('c ',g[6],g[7],g[8])
  10502. def game():
  10503. g = ['-','-','-','-','-','-','-','-','-']
  10504. xz = 'x'
  10505. while True:
  10506. board(g)
  10507. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10508. if ask == 'a1':
  10509. g[0] = xz
  10510. if ask == 'a2':
  10511. g[1] = xz
  10512. if ask == 'a3':
  10513. g[2] = xz
  10514. if ask == 'b1':
  10515. g[3] = xz
  10516. if ask == 'b2':
  10517. g[4] = xz
  10518. if ask == 'b3':
  10519. g[5] = xz
  10520. if ask == 'c1':
  10521. g[6] = xz
  10522. if ask == 'c2':
  10523. g[7] = xz
  10524. if ask == 'c3':
  10525. g[8] = xz
  10526. if g[0] == xz and g[1] == xz and g[2] == xz:
  10527. print(xz+ ' Wins 🥳🥳🥳')
  10528. break
  10529. if g[3] == xz and g[4] == xz and g[5] == xz:
  10530. print(xz+ ' Wins 🥳🥳🥳')
  10531. break
  10532. if g[6] == xz and g[7] == xz and g[8] == xz:
  10533. print(xz+ ' Wins 🥳🥳🥳')
  10534. break
  10535. if g[1] == xz and g[4] == xz and g[7] == xz:
  10536. print(xz+ ' Wins 🥳🥳🥳')
  10537. break
  10538. if g[0] == xz and g[3] == xz and g[6] == xz:
  10539. print(xz+ ' Wins 🥳🥳🥳')
  10540. break
  10541. if g[2] == xz and g[5] == xz and g[8] == xz:
  10542. print(xz+ ' Wins 🥳🥳🥳')
  10543. break
  10544. if g[0] == xz and g[4] == xz and g[8] == xz:
  10545. print(xz+ ' Wins 🥳🥳🥳')
  10546. break
  10547. if g[2] == xz and g[4] == xz and g[6] == xz:
  10548. print(xz+ ' Wins 🥳🥳🥳')
  10549. break
  10550. if xz == 'x':
  10551. xz = '0'
  10552. else:
  10553. xz = 'x'
  10554. game()
  10555. ```
  10556. alternative way of writing this:
  10557. ```
  10558. def board(g):
  10559. print(' ',1,2,3)
  10560. print('a ',g[0],g[1],g[2])
  10561. print('b ',g[3],g[4],g[5])
  10562. print('c ',g[6],g[7],g[8])
  10563. def check(g, xz, i1,i2,i3):
  10564. if g[i1] == xz and g[i2] == xz and g[i3] == xz:
  10565. return True
  10566. return False
  10567. def game():
  10568. g = ['-','-','-','-','-','-','-','-','-']
  10569. xz = 'x'
  10570. while True:
  10571. # print the board
  10572. board(g)
  10573. # get the input and update the game board
  10574. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10575. index = 0
  10576. if ask[0] == 'a':
  10577. index = 0 + int(ask[1]) - 1 # convert a1 to index 0, a3 to index 3
  10578. if ask[0] == 'b':
  10579. index = 3 + int(ask[1]) - 1 # convert b1 to index 3 and b3 to index 5
  10580. if ask[0] == 'c':
  10581. index = 6 + int(ask[1]) - 1 # convert c1 to index 6 and c3 to index 8
  10582. g[index] = xz
  10583. # check if we have a winner
  10584. # horizontal
  10585. if check(g,xz,0,1,2) or check(g,xz,3,4,5) or check(g,xz,6,7,8):
  10586. print(xz+ ' Wins 🥳🥳🥳')
  10587. break
  10588. # vertical
  10589. if check(g,xz,1,4,7) or check(g,xz,0,3,6) or check(g,xz,2,5,8):
  10590. print(xz+ ' Wins 🥳🥳🥳')
  10591. break
  10592. # diagonal
  10593. if check(g,xz,0,4,8) or check(g,xz,2,4,6):
  10594. print(xz+ ' Wins 🥳🥳🥳')
  10595. break
  10596. # swap the synmbol for the next turn
  10597. if xz == 'x':
  10598. xz = '0'
  10599. else:
  10600. xz = 'x'
  10601. game()
  10602. ```
  10603. ## [DAY-164] pointers
  10604. Write a program to prepare for the test tomorrow. Its a test of abbreviations, from abbreviation to meaning. Make a program to help you study, it should ask you for a abbreviation and then you should write its meaning.
  10605. ```
  10606. t.z.t -> ten zijner tijd
  10607. v.l.n.r -> van links naar rechts
  10608. e.d -> en dergelijk
  10609. nr. -> nummer
  10610. zg. -> zogenaamd
  10611. Gebr. -> gebroeders
  10612. dr. -> doctor
  10613. s.v.p -> s'il vous plait
  10614. t.o.v -> ten opzichte van
  10615. nl. -> namelijk
  10616. N.B. -> Nota Bene
  10617. sr. -> senior
  10618. jr. -> junior
  10619. C -> Celsius
  10620. etc -> etcetra
  10621. t.a.v -> ter attentie van
  10622. P.S. -> postscriptum
  10623. B. en W. -> Burgemeesteren Wethouders
  10624. NL -> Nederland
  10625. v.a -> vanaf
  10626. drs -> doctorandes
  10627. ```
  10628. The program will have 2 lists with the same amount of elements, you should pick a random index, ask the user to type the meaning for `abbreviations[i]` and compare it with `meaning[i]`
  10629. ```
  10630. import random
  10631. def test(taal,toets):
  10632. i = random.randint(0,len(taal)-1)
  10633. f = input(taal[i]+ ': ')
  10634. if f == toets[i]:
  10635. print('corect')
  10636. else:
  10637. print("WRONG, one more try!")
  10638. f = input(taal[i]+ ': ')
  10639. if f == toets[i]:
  10640. print('corect')
  10641. else:
  10642. print('better luck next time the correct answer was: '+toets[i])
  10643. short = ['t.z.t','v.l.n.r','e.d','nr.','zg.','Gebr.','dr.',
  10644. 's.v.p','t.o.v','nl.','N.B.','sr.','jr.','C',
  10645. 'etc','t.a.v','P.S.','B. en W.','NL','v.a','drs']
  10646. long = ['ten zijner tijd','van links naar rechts','en dergelijk',
  10647. 'nummer','zogenaamd','gebroeders','doctor',
  10648. "s'il vous plait",'ten opzichte van','namelijk',
  10649. 'Nota Bene','senior','junior','Celsius',
  10650. 'etcetra','ter attentie van','postscriptum',
  10651. 'Burgemeesteren Wethouders','Nederland','vanaf','doctorandes']
  10652. for i in range(len(short)):
  10653. print(short[i] + ' -> ' + long[i])
  10654. while True:
  10655. test(short,long)
  10656. test(long, short)
  10657. ```
  10658. ## [DAY-165] if; while
  10659. Another tic tac toe on your own
  10660. > (this is the code she wrote)
  10661. ```
  10662. def board(g):
  10663. print(' ',1,2,3)
  10664. print('a',g[0],g[1],g[2])
  10665. print('b',g[3],g[4],g[5])
  10666. print('c',g[6],g[7],g[8])
  10667. g = ['-']*9
  10668. idk = 'x'
  10669. while True:
  10670. board(g)
  10671. l = input(idk + 'choose a number 1,2,3 and a letter a,b,c: ')
  10672. if l == 'a1':
  10673. g[0] = idk
  10674. if l == 'a2':
  10675. g[1] = idk
  10676. if l == 'a3':
  10677. g[2] = idk
  10678. if l == 'b1':
  10679. g[3] = idk
  10680. if l == 'b2':
  10681. g[4] = idk
  10682. if l == 'b3':
  10683. g[5] = idk
  10684. if l == 'c1':
  10685. g[6] = idk
  10686. if l == 'c2':
  10687. g[7] = idk
  10688. if l == 'c3':
  10689. g[8] = idk
  10690. if g[0] == idk and g[1] == idk and g[2] == idk:
  10691. print(idk+' Won congratulations 🥳🥳🥳')
  10692. break
  10693. if g[3] == idk and g[4] == idk and g[5] == idk:
  10694. print(idk+' Won congratulations 🥳🥳🥳')
  10695. break
  10696. if g[6] == idk and g[7] == idk and g[8] == idk:
  10697. print(idk+' Won congratulations 🥳🥳🥳')
  10698. break
  10699. if g[0] == idk and g[3] == idk and g[6] == idk:
  10700. print(idk+' Won congratulations 🥳🥳🥳')
  10701. break
  10702. if g[1] == idk and g[4] == idk and g[7] == idk:
  10703. print(idk+' Won congratulations 🥳🥳🥳')
  10704. break
  10705. if g[2] == idk and g[5] == idk and g[8] == idk:
  10706. print(idk+ ' Won congratulations 🥳🥳🥳')
  10707. break
  10708. if g[2] == idk and g[4] == idk and g[6] == idk:
  10709. print(idk+ 'Won congratulations 🥳🥳🥳')
  10710. break
  10711. if g[0] == idk and g[4] == idk and g[8] == idk:
  10712. print(idk+' Won congratulations 🥳🥳🥳')
  10713. break
  10714. done = True
  10715. for e in g:
  10716. if e == '-':
  10717. done = False
  10718. if done:
  10719. print('Its a tie')
  10720. break
  10721. if idk == 'x':
  10722. idk = '0'
  10723. else:
  10724. idk = 'x'
  10725. board(g)
  10726. ```
  10727. ## [DAY-166] if; while
  10728. Write tic tac toe on your own but 4x4 instead of 3x3.
  10729. > (this is the code she wrote)
  10730. ```
  10731. def board(g):
  10732. print(' ',1,2,3,4)
  10733. print('a',g[0],g[1],g[2],g[3])
  10734. print('b',g[4],g[5],g[6],g[7])
  10735. print('c',g[8],g[9],g[10],g[11])
  10736. print('d',g[12],g[13],g[14],g[15])
  10737. g = ['-']*16
  10738. idk = 'x'
  10739. while True:
  10740. board(g)
  10741. l = input(idk + 'choose a number 1,2,3 and a letter a,b,c: ')
  10742. if l == 'a1':
  10743. g[0] = idk
  10744. if l == 'a2':
  10745. g[1] = idk
  10746. if l == 'a3':
  10747. g[2] = idk
  10748. if l == 'a4':
  10749. g[3] = idk
  10750. if g[0] == idk and g[1] == idk and g[2] == idk and g[3] == idk:
  10751. print(idk+' Won congratulations 🥳🥳🥳')
  10752. break
  10753. # ...
  10754. if idk == 'x':
  10755. idk = '0'
  10756. else:
  10757. idk = 'x'
  10758. board(g)
  10759. ```
  10760. ## [DAY-167] C; printf; scanf
  10761. We will use `printf` to display text and `scanf` to read text input from the user. First compile the following program, save it to a file `hello.c` and run `gcc -o hello hello.c` the C compiler we will use is called `gcc`, just as the C++ compiler we used was called `g++`, and the options are again `-o` for 'output file name' and then the source code file `hello.c`.
  10762. ```
  10763. #include <stdio.h>
  10764. int main(void) {
  10765. int age = 0;
  10766. printf("How old are you: ");
  10767. scanf("%d",&age);
  10768. if (age > 10) {
  10769. printf("you are a grownup\n");
  10770. } else {
  10771. printf("are you a little kid, %d %d %c\n", age, 102, 103);
  10772. }
  10773. return 0;
  10774. }
  10775. ```
  10776. Now lets read it line by line, first we make a variable `age` of type `integer` with initial value of `0`, then we print "How old are you" using `printf`, and immidiately after tat we do `scanf("%d",&age)`, first we say to scanf that we are looking for a integer `%d` and then once it reads an integer to put it on memory where the variable `age` is located at. With the `&` symbol we take the memory address of the variable.
  10777. Then we compare if the age that the user entered is > 10, we print one thing, and if not we print `printf("are you a little kid, %d %d %c\n", age, 102, 103);` this will print the age itself (the first %d) will use the second parameter which is `age`, then the second %d will print 102, and then %c will print the ascii value of 103 (g).
  10778. Both printf and scanf's first argument is the formatting string, while it is printing or scanning the input, whenever it sees %d %c %f (digit, character, floating point number), it will read from the arguments you passed to it and do what you want, read or write depending if printf or scanf.
  10779. This is just the first steps towards C, dont worry if you dont get the `&` thing and the memory address, with some practice things will click and it will all make sense.
  10780. Lets say your coputer has only 30 bytes of memory:
  10781. ```
  10782. 00-09|..........|
  10783. 10-19|0000......| int age at memory address 10, occupying 4 bytes
  10784. 20-29|..........|
  10785. 30-39|PPPPPPPPPP| the program itself
  10786. ```
  10787. `&age` is the address of age, which is 10, its as simple as that, `scanf` gets the value 10 as the location in memory in which it should write down the number that it processed from the user input.
  10788. ## [DAY-168] c; while; if
  10789. Rock paper scissors in C.
  10790. ```
  10791. #include <stdio.h>
  10792. #include <stdlib.h>
  10793. #define ROCK 0
  10794. #define PAPER 1
  10795. #define SCISSORS 2
  10796. int main(void) {
  10797. while (1) {
  10798. int player;
  10799. printf("rock(0) paper(1) scissors(2): ");
  10800. scanf("%d", &player);
  10801. int computer = rand() % 3;
  10802. printf("player: %d, computer: %d\n", player, computer);
  10803. if (computer == player) {
  10804. printf("its a tie\n");
  10805. } else {
  10806. if (computer == ROCK && player == PAPER) {
  10807. printf("player wins\n");
  10808. }
  10809. if (computer == ROCK && player == SCISSORS) {
  10810. printf("computer wins\n");
  10811. }
  10812. if (computer == PAPER && player == ROCK) {
  10813. printf("computer wins\n");
  10814. }
  10815. if (computer == PAPER && player == SCISSORS) {
  10816. printf("player wins\n");
  10817. }
  10818. if (computer == SCISSORS && player == ROCK) {
  10819. printf("player wins\n");
  10820. }
  10821. if (computer == SCISSORS && player == PAPER) {
  10822. printf("computer wins\n");
  10823. }
  10824. }
  10825. }
  10826. return 0;
  10827. }
  10828. ```
  10829. `#define ROCK 0` just makes the c compiler to replace ROCK with 0 wherever it sees it in the source code.
  10830. `#include <stdlib.h>` is needed for the `rand` function, it returns an integer, but since we need a number from 0, 1, 2 we just do `rand() % 3`, which will take the reminder from the random number and 3.
  10831. Try this in python:
  10832. ```
  10833. for i in range(100000):
  10834. print(i, i % 3)
  10835. ```
  10836. You will see:
  10837. ```
  10838. 0 0
  10839. 1 1
  10840. 2 2
  10841. 3 0
  10842. 4 1
  10843. 5 2
  10844. 6 0
  10845. 7 1
  10846. 8 2
  10847. 9 0
  10848. 10 1
  10849. 11 2
  10850. 12 0
  10851. 13 1
  10852. 14 2
  10853. 15 0
  10854. 16 1
  10855. 17 2
  10856. 18 0
  10857. 19 1
  10858. 20 2
  10859. 21 0
  10860. 22 1
  10861. 23 2
  10862. 24 0
  10863. 25 1
  10864. 26 2
  10865. 27 0
  10866. 28 1
  10867. 29 2
  10868. 30 0
  10869. 31 1
  10870. 32 2
  10871. 33 0
  10872. 34 1
  10873. 35 2
  10874. 36 0
  10875. 37 1
  10876. 38 2
  10877. 39 0
  10878. 40 1
  10879. 41 2
  10880. 42 0
  10881. 43 1
  10882. 44 2
  10883. 45 0
  10884. 46 1
  10885. 47 2
  10886. 48 0
  10887. 49 1
  10888. 50 2
  10889. 51 0
  10890. 52 1
  10891. 53 2
  10892. 54 0
  10893. ...
  10894. ```
  10895. ## [DAY-169] c; while; if
  10896. Battle ship in C.
  10897. Arrays are continous block of memory, for example `int x[10]` creates 10 integers (4 bytes each, so 40 bytes block), you can access each element by its index from `x[0]` to `x[9]`, e.g. `x[2] = 5` will set the 3rd element to be equal to 5.
  10898. In C it is very easy to have multi dimensional arrays, simply say `int x[10][10]` and that creates 10x10 integers you can access by their row and column, we will use two dimensional array to store our boards for the battleship game. As usual, we use one hidden board with the ships and one display board with the guesses.
  10899. ```
  10900. #include <stdio.h>
  10901. #include <stdlib.h>
  10902. #define SIZE 10
  10903. int main(void) {
  10904. int hidden[SIZE][SIZE];
  10905. int display[SIZE][SIZE];
  10906. for (int i = 0; i < SIZE; i++) {
  10907. for (int j = 0; j < SIZE; j++) {
  10908. hidden[i][j] = 0;
  10909. display[i][j] = 0;
  10910. }
  10911. }
  10912. // make 20 random ships
  10913. for (int i = 0; i < 20; i++) {
  10914. hidden[rand() % SIZE][rand() % SIZE] = 1;
  10915. }
  10916. while (1) {
  10917. // print the display board
  10918. for (int i = 0; i < SIZE; i++) {
  10919. for (int j = 0; j < SIZE; j++) {
  10920. printf("%d ", display[i][j]);
  10921. }
  10922. printf("\n");
  10923. }
  10924. // get the row and column from the user
  10925. int row, column;
  10926. printf("row column> ");
  10927. scanf("%d %d", &row, &column);
  10928. // modify the display board depending if ship is
  10929. // found in the hidden board or not.
  10930. if (hidden[row][column] == 1) {
  10931. display[row][column] = 1;
  10932. } else {
  10933. display[row][column] = 2;
  10934. }
  10935. }
  10936. return 0;
  10937. }
  10938. ```
  10939. ## [DAY-170] pointers
  10940. Watch "What Are Pointers? (C++)", by javidx9 on youtube. https://www.youtube.com/watch?v=iChalAKXffs
  10941. ## [DAY-171] while; for; if; list
  10942. Build a chess game in 3 days.
  10943. * day 1, build the board, black and white squares, think carefully about the algorithm how to alternate between the colors
  10944. * day 2, build the basic movement, how to pick and drop a piece (use the pieces from https://joszs.itch.io/, they are licensed as CC 4.0 and are very very beautiful)
  10945. * day 3, polish the pieces, make it possible to take a piece
  10946. * todo: add queening the pawn code later
  10947. * todo: add restrictions to illegal moves
  10948. ![game-171.png](./screenshots/game-171.png "game 171 screenshot")
  10949. > This is the code that we wrote together, it actually took 3 days, 30 minutes per day, with a some help from the parent, but in the end its a (almost) working chess game.
  10950. ```
  10951. import pgzrun
  10952. HEIGHT = 800
  10953. WIDTH = 800
  10954. board = []
  10955. black = [
  10956. Actor('chess/rook-black',anchor=(0,0), pos=(0,0)),
  10957. Actor('chess/knight-black',anchor=(0,0), pos=(100,0)),
  10958. Actor('chess/bishop-black',anchor=(0,0), pos=(200,0)),
  10959. Actor('chess/queen-black',anchor=(0,0), pos=(300,0)),
  10960. Actor('chess/king-black',anchor=(0,0), pos=(400,0)),
  10961. Actor('chess/bishop-black',anchor=(0,0), pos=(500,0)),
  10962. Actor('chess/knight-black',anchor=(0,0), pos=(600,0)),
  10963. Actor('chess/rook-black',anchor=(0,0), pos=(700,0)),
  10964. Actor('chess/pawn-black',anchor=(0,0), pos=(0,100)),
  10965. Actor('chess/pawn-black',anchor=(0,0), pos=(100,100)),
  10966. Actor('chess/pawn-black',anchor=(0,0), pos=(200,100)),
  10967. Actor('chess/pawn-black',anchor=(0,0), pos=(300,100)),
  10968. Actor('chess/pawn-black',anchor=(0,0), pos=(400,100)),
  10969. Actor('chess/pawn-black',anchor=(0,0), pos=(500,100)),
  10970. Actor('chess/pawn-black',anchor=(0,0), pos=(600,100)),
  10971. Actor('chess/pawn-black',anchor=(0,0), pos=(700,100)),
  10972. ]
  10973. white = [
  10974. Actor('chess/pawn-white',anchor=(0,0), pos=(0,600)),
  10975. Actor('chess/pawn-white',anchor=(0,0), pos=(100,600)),
  10976. Actor('chess/pawn-white',anchor=(0,0), pos=(200,600)),
  10977. Actor('chess/pawn-white',anchor=(0,0), pos=(300,600)),
  10978. Actor('chess/pawn-white',anchor=(0,0), pos=(400,600)),
  10979. Actor('chess/pawn-white',anchor=(0,0), pos=(500,600)),
  10980. Actor('chess/pawn-white',anchor=(0,0), pos=(600,600)),
  10981. Actor('chess/pawn-white',anchor=(0,0), pos=(700,600)),
  10982. Actor('chess/rook-white',anchor=(0,0), pos=(0,700)),
  10983. Actor('chess/knight-white',anchor=(0,0), pos=(100,700)),
  10984. Actor('chess/bishop-white',anchor=(0,0), pos=(200,700)),
  10985. Actor('chess/queen-white',anchor=(0,0), pos=(300,700)),
  10986. Actor('chess/king-white',anchor=(0,0), pos=(400,700)),
  10987. Actor('chess/bishop-white',anchor=(0,0), pos=(500,700)),
  10988. Actor('chess/knight-white',anchor=(0,0), pos=(600,700)),
  10989. Actor('chess/rook-white',anchor=(0,0), pos=(700,700)),
  10990. ]
  10991. x = 0
  10992. y = 0
  10993. block = 0
  10994. for i in range(1,65):
  10995. if block % 2 == 0:
  10996. board.append(Actor('chess/white',anchor=(0,0), pos=(x,y)))
  10997. else:
  10998. board.append(Actor('chess/black',anchor=(0,0), pos=(x,y)))
  10999. block += 1
  11000. x += 100
  11001. if i != 0 and i%8 == 0:
  11002. y += 100
  11003. x = 0
  11004. block+=3
  11005. pick_white = None
  11006. pick_black = None
  11007. elf = Actor("c1",ancor=(0,0))
  11008. king = Actor("c2")
  11009. def on_key_down(key):
  11010. global pick_white,pick_black
  11011. if key == keys.R and pick_white == None:
  11012. # pick up the piece below
  11013. for w in white:
  11014. if elf.colliderect(w):
  11015. pick_white = w
  11016. elif key == keys.R and pick_white != None:
  11017. for b in board:
  11018. # shouldnt be able to drop if there is already white piece there
  11019. if elf.colliderect(b):
  11020. for w in white:
  11021. if w != pick_white and b.colliderect(w):
  11022. return
  11023. # snap the white piece to the board
  11024. pick_white.x = b.x
  11025. pick_white.y = b.y
  11026. # take the black piece if there
  11027. for bl in list(black):
  11028. if bl.colliderect(pick_white):
  11029. black.remove(bl)
  11030. # drop it
  11031. pick_white = None
  11032. break
  11033. if key == keys.P and pick_black == None:
  11034. # pick up the piece below
  11035. for b in black:
  11036. if king.colliderect(b):
  11037. pick_black = b
  11038. elif key == keys.P and pick_black != None:
  11039. for b in board:
  11040. if king.colliderect(b):
  11041. # dont allow a drop if there is already a black piece there
  11042. for l in black:
  11043. if l != pick_black and b.colliderect(l):
  11044. return
  11045. # snap the black piece to the board
  11046. pick_black.x = b.x
  11047. pick_black.y = b.y
  11048. # take the white piece if there
  11049. for w in list(white):
  11050. if w.colliderect(pick_black):
  11051. white.remove(w)
  11052. # drop it
  11053. pick_black = None
  11054. break
  11055. def update():
  11056. global pick_white,pick_black
  11057. speed = 2
  11058. if keyboard.W:
  11059. elf.y -= 5
  11060. if keyboard.S:
  11061. elf.y += 5
  11062. if keyboard.A:
  11063. elf.x -= 5
  11064. if keyboard.D:
  11065. elf.x += 5
  11066. if keyboard.UP:
  11067. king.y -= 5
  11068. if keyboard.DOWN:
  11069. king.y += 5
  11070. if keyboard.LEFT:
  11071. king.x -= 5
  11072. if keyboard.RIGHT:
  11073. king.x += 5
  11074. # move the white piece with the elf
  11075. if pick_white != None:
  11076. pick_white.x = elf.x - 30
  11077. pick_white.y = elf.y - 30
  11078. # move the black piece with the king
  11079. if pick_black != None:
  11080. pick_black.x = king.x - 30
  11081. pick_black.y = king.y - 30
  11082. def draw():
  11083. screen.fill('deepskyblue')
  11084. for b in board:
  11085. b.draw()
  11086. for b in black:
  11087. b.draw()
  11088. for w in white:
  11089. w.draw()
  11090. elf.draw()
  11091. king.draw()
  11092. pgzrun.go()
  11093. ```
  11094. ## [DAY-172] if
  11095. Add Queening the Pawn functionality, which means when a white/black pawn reaches the of the board it turns into a queen. Think a bit what that means, for a white pawn it reaches the end of the board when its .y property is 0, and for a black pawn when its 700. The only thing left to do is to actually check if we are holding a pawn.
  11096. ```
  11097. # ...
  11098. # shouldnt be able to drop if there is already white piece there
  11099. if elf.colliderect(b):
  11100. for w in white:
  11101. if w != pick_white and b.colliderect(w):
  11102. return
  11103. # snap the white piece to the board
  11104. pick_white.x = b.x
  11105. pick_white.y = b.y
  11106. # take the black piece if there
  11107. for bl in list(black):
  11108. if bl.colliderect(pick_white):
  11109. black.remove(bl)
  11110. # Queening the Pawn:
  11111. # pick_white.image is chess/pawn-white for the white pawn
  11112. # set the pick_white.image to chess/queen-white if it reaches the black end of the board
  11113. if pick_white.image == 'chess/pawn-white' and pick_white.y == 0:
  11114. pick_white.image = 'chess/queen-white'
  11115. # drop it
  11116. pick_white = None
  11117. break
  11118. # ...
  11119. ```
  11120. and respective for the black pawn:
  11121. ```
  11122. # ...
  11123. if pick_black.image == 'chess/pawn-black' and pick_black.y == 700:
  11124. pick_black.image = 'chess/queen-black'
  11125. # drop it
  11126. pick_black = None
  11127. # ...
  11128. ```
  11129. ## [DAY-173] if; variables
  11130. Today we will make another rule, the pawns can not go backwards. Also we will cleanup the code a bit, and rename few variable so it is more readable, previously we had `for b in board` and then we were using `b.x` and etc, which was kind of confusing. We will rename it for `for square in board` and you will see how much more readable the code is.
  11131. First if we want to check if something is going backwards we have to compare its current position with the previous position. In our case this is quite simple, we will make two variables `x` and `y` and once we select which piece we will be moving we will store the piece's .x and .y properties into our `x` and `y` variables.
  11132. After we have the original position it is just a matter of checking at the time of placing the piece if it is a pawn and if the original y position is bigger or smaller than the new position, depending which way is forward, for the black pawns up is downwards (y is growing), for white its upwards (y is decreasing).
  11133. This is the whole program again, because of the rename of some variables, it is easier to re-read it.
  11134. ```
  11135. import pgzrun
  11136. HEIGHT = 800
  11137. WIDTH = 800
  11138. board = []
  11139. black = [
  11140. Actor('chess/rook-black',anchor=(0,0), pos=(0,0)),
  11141. Actor('chess/knight-black',anchor=(0,0), pos=(100,0)),
  11142. Actor('chess/bishop-black',anchor=(0,0), pos=(200,0)),
  11143. Actor('chess/queen-black',anchor=(0,0), pos=(300,0)),
  11144. Actor('chess/king-black',anchor=(0,0), pos=(400,0)),
  11145. Actor('chess/bishop-black',anchor=(0,0), pos=(500,0)),
  11146. Actor('chess/knight-black',anchor=(0,0), pos=(600,0)),
  11147. Actor('chess/rook-black',anchor=(0,0), pos=(700,0)),
  11148. Actor('chess/pawn-black',anchor=(0,0), pos=(0,100)),
  11149. Actor('chess/pawn-black',anchor=(0,0), pos=(100,100)),
  11150. Actor('chess/pawn-black',anchor=(0,0), pos=(200,100)),
  11151. Actor('chess/pawn-black',anchor=(0,0), pos=(300,100)),
  11152. Actor('chess/pawn-black',anchor=(0,0), pos=(400,100)),
  11153. Actor('chess/pawn-black',anchor=(0,0), pos=(500,100)),
  11154. Actor('chess/pawn-black',anchor=(0,0), pos=(600,100)),
  11155. Actor('chess/pawn-black',anchor=(0,0), pos=(700,100)),
  11156. ]
  11157. white = [
  11158. Actor('chess/pawn-white',anchor=(0,0), pos=(0,600)),
  11159. Actor('chess/pawn-white',anchor=(0,0), pos=(100,600)),
  11160. Actor('chess/pawn-white',anchor=(0,0), pos=(200,600)),
  11161. Actor('chess/pawn-white',anchor=(0,0), pos=(300,600)),
  11162. Actor('chess/pawn-white',anchor=(0,0), pos=(400,600)),
  11163. Actor('chess/pawn-white',anchor=(0,0), pos=(500,600)),
  11164. Actor('chess/pawn-white',anchor=(0,0), pos=(600,600)),
  11165. Actor('chess/pawn-white',anchor=(0,0), pos=(700,600)),
  11166. Actor('chess/rook-white',anchor=(0,0), pos=(0,700)),
  11167. Actor('chess/knight-white',anchor=(0,0), pos=(100,700)),
  11168. Actor('chess/bishop-white',anchor=(0,0), pos=(200,700)),
  11169. Actor('chess/queen-white',anchor=(0,0), pos=(300,700)),
  11170. Actor('chess/king-white',anchor=(0,0), pos=(400,700)),
  11171. Actor('chess/bishop-white',anchor=(0,0), pos=(500,700)),
  11172. Actor('chess/knight-white',anchor=(0,0), pos=(600,700)),
  11173. Actor('chess/rook-white',anchor=(0,0), pos=(700,700)),
  11174. ]
  11175. x = 0
  11176. y = 0
  11177. block = 0
  11178. for i in range(1,65):
  11179. if block % 2 == 0:
  11180. board.append(Actor('chess/white',anchor=(0,0), pos=(x,y)))
  11181. else:
  11182. board.append(Actor('chess/black',anchor=(0,0), pos=(x,y)))
  11183. block += 1
  11184. x += 100
  11185. if i != 0 and i%8 == 0:
  11186. y += 100
  11187. x = 0
  11188. block+=3
  11189. pick_white = None
  11190. pick_black = None
  11191. elf = Actor("c1",ancor=(0,0))
  11192. king = Actor("c2")
  11193. x = 0
  11194. y = 0
  11195. def on_key_down(key):
  11196. global pick_white,pick_black,x,y
  11197. if key == keys.SPACE and pick_white == None:
  11198. # pick up the piece below
  11199. for w in white:
  11200. if elf.colliderect(w):
  11201. pick_white = w
  11202. # store the original position
  11203. x = w.x
  11204. y = w.y
  11205. elif key == keys.SPACE and pick_white != None:
  11206. for square in board:
  11207. # shouldnt be able to drop if there is already white piece there
  11208. if elf.colliderect(square):
  11209. for w in white:
  11210. if w != pick_white and square.colliderect(w):
  11211. return
  11212. # pawns cant move backwards
  11213. if pick_white.image == 'chess/pawn-white' and square.y > y:
  11214. return
  11215. # snap the white piece to the board
  11216. pick_white.x = square.x
  11217. pick_white.y = square.y
  11218. # take the black piece if there
  11219. for b in list(black):
  11220. if b.colliderect(pick_white):
  11221. black.remove(b)
  11222. # Queening the Pawn:
  11223. # pick_white.image is chess/pawn-white for the white pawn
  11224. # set the pick_white.image to chess/queen-white if it reaches the black end of the board
  11225. if pick_white.image == 'chess/pawn-white' and pick_white.y == 0:
  11226. pick_white.image = 'chess/queen-white'
  11227. # drop it
  11228. pick_white = None
  11229. break
  11230. if key == keys.P and pick_black == None:
  11231. # pick up the piece below
  11232. for b in black:
  11233. if king.colliderect(b):
  11234. pick_black = b
  11235. # store the original position
  11236. y = b.y
  11237. x = b.x
  11238. elif key == keys.P and pick_black != None:
  11239. for square in board:
  11240. if king.colliderect(square):
  11241. # dont allow a drop if there is already a black piece there
  11242. for b in black:
  11243. if b != pick_black and square.colliderect(b):
  11244. return
  11245. # pawns cant move backwards
  11246. if pick_black.image == 'chess/pawn-black' and square.y < y:
  11247. return
  11248. # snap the black piece to the board
  11249. pick_black.x = square.x
  11250. pick_black.y = square.y
  11251. # take the white piece if there
  11252. for w in list(white):
  11253. if w.colliderect(pick_black):
  11254. white.remove(w)
  11255. # Queen the Pawn
  11256. if pick_black.image == 'chess/pawn-black' and pick_black.y == 700:
  11257. pick_black.image = 'chess/queen-black'
  11258. # drop it
  11259. pick_black = None
  11260. break
  11261. def update():
  11262. global pick_white,pick_black
  11263. if keyboard.W:
  11264. elf.y -= 5
  11265. if keyboard.S:
  11266. elf.y += 5
  11267. if keyboard.A:
  11268. elf.x -= 5
  11269. if keyboard.D:
  11270. elf.x += 5
  11271. if keyboard.UP:
  11272. king.y -= 5
  11273. if keyboard.DOWN:
  11274. king.y += 5
  11275. if keyboard.LEFT:
  11276. king.x -= 5
  11277. if keyboard.RIGHT:
  11278. king.x += 5
  11279. # move the white piece with the elf
  11280. if pick_white != None:
  11281. pick_white.x = elf.x - 30
  11282. pick_white.y = elf.y - 30
  11283. # move the black piece with the king
  11284. if pick_black != None:
  11285. pick_black.x = king.x - 30
  11286. pick_black.y = king.y - 30
  11287. def draw():
  11288. screen.fill('deepskyblue')
  11289. for square in board:
  11290. square.draw()
  11291. for b in black:
  11292. b.draw()
  11293. for w in white:
  11294. w.draw()
  11295. elf.draw()
  11296. king.draw()
  11297. pgzrun.go()
  11298. ```
  11299. ## [DAY-174] if; list
  11300. The knight moves in shape L, so we have to make all other moves illegal.
  11301. First draw on a sheet of paper all possible moves, and
  11302. ![game-174.png](./screenshots/game-174.png "game 174 screenshot")
  11303. There are many ways you can implement this but we will focus on two, one with just if conditions, and one with a list of possible moves.
  11304. With if conditions, what we do is we set the move as bad (`good = False`), and then we check if it is actually one of the good moves we do `good = True`, in the end if its not a good move we return from the `on_key_press` function and the piece is not dropped on the square.
  11305. ```
  11306. elif key == keys.P and pick_black != None:
  11307. for square in board:
  11308. if king.colliderect(square):
  11309. ...
  11310. # knight can only move L shape
  11311. if pick_black.image == 'chess/knight-black':
  11312. good = False
  11313. if square.x == x + 100 and square.y == y - 200:
  11314. good = True
  11315. elif square.x == x + 100 and square.y == y + 200:
  11316. good = True
  11317. elif square.x == x - 200 and square.y == y - 100:
  11318. good = True
  11319. elif square.x == x - 200 and square.y == y + 100:
  11320. good = True
  11321. elif square.x == x - 100 and square.y == y + 200:
  11322. good = True
  11323. elif square.x == x + 200 and square.y == y + 100:
  11324. good = True
  11325. elif square.x == x + 200 and square.y == y - 100:
  11326. good = True
  11327. elif square.x == x - 100 and square.y == y - 200:
  11328. good = True
  11329. elif square.x == x and square.y == y:
  11330. good = True
  11331. if not good:
  11332. return
  11333. ...
  11334. ```
  11335. For the white pieces we will try the other approach, which checks if a the move is in a list of allowed moves. You can check if a list is in a list, e.g. `a = [[1,2],[3,4]]` you can just try `if [1,2] in a`, so we can simply build a list of possible moves, and check if the square we are dropping the piece on is one of those moves.
  11336. ```
  11337. ...
  11338. elif key == keys.SPACE and pick_white != None:
  11339. for square in board:
  11340. # shouldnt be able to drop if there is already white piece there
  11341. if elf.colliderect(square):
  11342. ...
  11343. # knight can only move L shape
  11344. knight_possible = [
  11345. [x,y],
  11346. [x+100,y-200],
  11347. [x+100,y+200],
  11348. [x-200,y-100],
  11349. [x-200,y+100],
  11350. [x-100,y+200],
  11351. [x+200,y+100],
  11352. [x+200,y-100],
  11353. [x-100,y-200]
  11354. ]
  11355. if pick_white.image == 'chess/knight-white' and [square.x,square.y] not in knight_possible:
  11356. return
  11357. ...
  11358. ```
  11359. ## [DAY-175] if
  11360. The pawn can only move 2 squares from starting position and 1 square otherwise, try to implement this rule by yourself.
  11361. > this is the code she wrote (including the comment)
  11362. ```
  11363. ...
  11364. #if pawn.y == 600:
  11365. #pawn can only move 200:
  11366. #else
  11367. #pwan can move only 100
  11368. if pick_white.image == 'chess/pawn-white':
  11369. if y == 600:
  11370. if y - square.y > 200:
  11371. return
  11372. if y != 600:
  11373. if y - square.y >100:
  11374. return
  11375. ...
  11376. if pick_black.image == 'chess/pawn-black':
  11377. if y == 100:
  11378. if square.y - y > 200:
  11379. return
  11380. if y != 100:
  11381. if square.y - y >100:
  11382. return
  11383. ```
  11384. ## [DAY-176] if
  11385. First rename x and y to pick_x and pick_y so things are clearer when you compare square.x with pick_x. Then come up with a way to limit the king's movements to only one square.
  11386. > this is the code she wrote
  11387. ```
  11388. ...
  11389. if pick_black.image == 'chess/king-black':
  11390. if square.y - pick_y > 100 or square.y - pick_y < -100:
  11391. return
  11392. if square.x - pick_x > 100 or square.x - pick_x < -100:
  11393. return
  11394. ...
  11395. ```
  11396. ## [DAY-177] if
  11397. The rook can move only vertically or horizontaly, meaning that either its x or y does not change. Try to code the rule by yourself. If you get stuck, try to do only vertical (x does not change) or horizontal (y does not change), and then think how to add the other direction.
  11398. Remember, always try the simple thing first.
  11399. > this is the code she wrote
  11400. ```
  11401. ...
  11402. if pick_black.image == 'chess/rook-black':
  11403. if square.x != pick_x and square.y != pick_y:
  11404. return
  11405. ...
  11406. ```
  11407. ## [DAY-178] if; absolute
  11408. Today we will do the rule for the bishop, since the bishop moves in diagonal. You see in the image that the diagonal means that both x and y change with the same absolute amount, lets say we want to move only one square, the possible values are: -1 -1, -1 1, 1 1, 1 -1, meaning move up and left (decrease y and decrease x), up and right (decrease y, increase x), down and right (increase y, indcrease x), down and left (increase y, decrease x).
  11409. ![game-178.png](./screenshots/game-178.png "game 178 screenshot")
  11410. Note that if you actually only care if the amount of steps away from the origin, the dirction does not matter. In math when we care about the absolute value of a number we just care about the amount of steps it would take to get from that number to zero, for example from -5 to zero it will take 5 steps, from 5 to zero it will also take 5 steps.
  11411. ```
  11412. <--------------------|-------------------->
  11413. -5 -4 -3 -2 -1 0 1 2 3 4 5
  11414. ```
  11415. Imagine you walking from -5 to zero, or from 5 to zero both will take you 5 steps. So lets write a function that takes a number and if the number is negative we will just turn it into its positive value, as we only care about the amount of steps.
  11416. ```
  11417. def abs(x):
  11418. if x < 0:
  11419. return x * -1
  11420. return x
  11421. ```
  11422. Now lets make the bishop rule. If the steps change in x is the same as the change in y then we must be moving in a diagonal, if not we refuse the move.
  11423. ```
  11424. ...
  11425. if pick_white.image == 'chess/bishop-white':
  11426. # how much did the y change
  11427. d_y = pick_y - square.y
  11428. # how much did the x change
  11429. d_x = pick_x - square.x
  11430. # if they didnt change the same amount, then its illegal move
  11431. if abs(d_y) != abs(d_x):
  11432. return
  11433. ...
  11434. ```
  11435. ## [DAY-179] if; for
  11436. Today we will do two more rules, one is the queen and one for the pawn. The queen can move like the rook and the bishop combined, so horizontally, vertically and diagonally. The pawn can move one step diagonally if she can take an enemy piece.
  11437. Lets start with the queen, as we already have the rook and bishop rules, it is quite easy, we just have to say 'if the move is not like the rook and not like the bishop then its illegal'.
  11438. ```
  11439. if pick_white.image == 'chess/rook-white':
  11440. if square.x != pick_x and square.y != pick_y:
  11441. return
  11442. if pick_white.image == 'chess/bishop-white':
  11443. d_y = pick_y - square.y
  11444. d_x = pick_x - square.x
  11445. if abs(d_y) != abs(d_x):
  11446. return
  11447. if pick_white.image == 'chess/queen-white':
  11448. d_y = pick_y - square.y
  11449. d_x = pick_x - square.x
  11450. if abs(d_y) != abs(d_x) and square.x != pick_x and square.y != pick_y:
  11451. return
  11452. ...
  11453. ```
  11454. The pawn is a bit more complicated, we need to check if the move is actually one step diagonally, and we also need to have a way to check if a piece is on specific position. We will make `is_on_square` function, that takes a position and a list and checks if any of the items of that list is on that position.
  11455. ```
  11456. def is_on_square(x, y, pieces):
  11457. for p in pieces:
  11458. if p.x == x and p.y == y:
  11459. return True
  11460. return False
  11461. ```
  11462. Now that we have the `is_on_square` function, we can simply check if the `y` of the square is exactly on top of the original position, and the `x` of the square is either one to the left or one to the right, which would mean either 1 square left diagonal or right diagonal, and then check if there is a black piece there, if it is allow the move.
  11463. ![game-179.png](./screenshots/game-179.png "game 179 screenshot")
  11464. ```
  11465. ...
  11466. if pick_white.image == 'chess/pawn-white':
  11467. # 1 or 2 squares
  11468. if pick_y == 600:
  11469. if pick_y - square.y > 200:
  11470. return
  11471. if pick_y != 600:
  11472. if pick_y - square.y > 100:
  11473. return
  11474. # pawn can only go left or right if theres someone
  11475. if pick_x != square.x:
  11476. ok = False
  11477. if pick_y - square.y == 100 and pick_x - square.x == 100 and is_on_square(square.x, square.y, black):
  11478. ok = True
  11479. if pick_y - square.y == 100 and pick_x - square.x == -100 and is_on_square(square.x, square.y, black):
  11480. ok = True
  11481. if not ok:
  11482. return
  11483. ...
  11484. ```
  11485. ## [DAY-180] if
  11486. There is an important rule in chess, that many people dont know, En Passant (In Passing).
  11487. From Wikipedia (https://en.wikipedia.org/wiki/En_passant):
  11488. > En passant (French: [ɑ̃ paˈsɑ̃], lit. in passing) is a move in chess. It is a special pawn capture that can only occur immediately after a pawn makes a move of two squares from its starting square and provided that it could have been captured by an enemy pawn had it advanced only one square. The opponent captures the just-moved pawn "in passing" through the first square. The result is the same as if the pawn had advanced only one square and the enemy pawn had captured it normally.
  11489. > The en passant capture must be made on the very next turn or the right to do so is lost. En passant capture is a common theme in chess compositions.
  11490. > The en passant capture rule was added in the 15th century when the rule that gave pawns an initial double-step move was introduced. It prevents a pawn from using the two-square advance to pass an adjacent enemy pawn without the risk of being captured.
  11491. ![game-180-a.png](./screenshots/game-180-a.png "game 180-a screenshot")
  11492. ![game-180-b.png](./screenshots/game-180-b.png "game 180-b screenshot")
  11493. ![game-180-c.png](./screenshots/game-180-c.png "game 180-b screenshot")
  11494. So its pretty nice rule, what we have to do is to remember each pawn that moves two squares and consider it possible en_passant, and then if the oponnent's pawn wants to move diagonally we will check if there is en_passant above(black)/below(white) and if there is we will capture it. If any move is made we will clear the en-passant
  11495. the code looks like this:
  11496. ```
  11497. enpassant = None
  11498. def on_key_down(key):
  11499. global pick_white, pick_black, pick_x, pick_y, enpassant
  11500. ...
  11501. elif key == keys.SPACE and pick_white != None:
  11502. for square in board:
  11503. # shouldnt be able to drop if there is already white piece there
  11504. if elf.colliderect(square):
  11505. ...
  11506. if pick_white.image == 'chess/pawn-white':
  11507. # 1 or 2 squares
  11508. if pick_y == 600:
  11509. if pick_y - square.y == 200:
  11510. enpassant = pick_white
  11511. if pick_y - square.y > 200:
  11512. return
  11513. if pick_y != 600:
  11514. if pick_y - square.y > 100:
  11515. return
  11516. # if y > 200 first move:
  11517. # pawn can only go left or right if theres someone
  11518. if pick_x != square.x:
  11519. ok = False
  11520. if pick_y - square.y == 100 and pick_x - square.x == 100 and is_on_square(square.x, square.y, black):
  11521. ok = True
  11522. if pick_y - square.y == 100 and pick_x - square.x == -100 and is_on_square(square.x, square.y, black):
  11523. ok = True
  11524. if (pick_y - square.y == 100 and pick_x - square.x == 100) or (pick_y - square.y == 100 and pick_x - square.x == -100):
  11525. if enpassant != None and enpassant.image == 'chess/pawn-black':
  11526. if enpassant.x == square.x and enpassant.y == square.y + 100:
  11527. black.remove(enpassant)
  11528. ok = True
  11529. if not ok:
  11530. return
  11531. # pawns cant move backwards
  11532. if square.y > pick_y:
  11533. return
  11534. # Queening the Pawn:
  11535. # pick_white.image is chess/pawn-white for the white pawn
  11536. # set the pick_white.image to chess/queen-white if it reaches the black end of the board
  11537. if square.y == 0:
  11538. pick_white.image = 'chess/queen-white'
  11539. ...
  11540. # snap the white piece to the board
  11541. pick_white.x = square.x
  11542. pick_white.y = square.y
  11543. if enpassant != pick_white:
  11544. enpassant = None
  11545. ...
  11546. ```
  11547. Notice how we set enpassant = pick_white if the pawn moves 2 squares (this will be used if the black pawn tries to capture), and later when we see that the pawn is moving diagonally we do:
  11548. ```
  11549. if (pick_y - square.y == 100 and pick_x - square.x == 100) or (pick_y - square.y == 100 and pick_x - square.x == -100):
  11550. if enpassant != None and enpassant.image == 'chess/pawn-black':
  11551. if enpassant.x == square.x and enpassant.y == square.y + 100:
  11552. black.remove(enpassant)
  11553. ok = True
  11554. ```
  11555. This basically checks if it is one square diagonal to the left or one square diagonal to the right, and if it is it checks if there is active enpassant and it is a black pawn, then it checks if it sits directly above the square we want to go to, and if it is we capture it and mark the move valid.
  11556. ## [DAY-181] if
  11557. Add undo support. We need to store the piece's position when its picked up, the piece itself and its image (in case of Queening The Pawn) and we need to store those for every move, then if the key 'b' is pressed we need to take the last move and revert it, and so on.
  11558. A good strategy for that is to simply use a list, and each time we pick a piece we will append the position_x, position_y, image, actor and then when 'b' is pressed we will pop them out and set them to the actor in question.
  11559. ```
  11560. ...
  11561. back = []
  11562. def on_key_down(key):
  11563. global pick_white, pick_black, pick_x, pick_y, pick_image, enpassant,back
  11564. if key == keys.SPACE and pick_white == None:
  11565. # pick up the piece below
  11566. for w in white:
  11567. if elf.colliderect(w):
  11568. pick_white = w
  11569. # store the original position
  11570. pick_x = w.x
  11571. pick_y = w.y
  11572. pick_image = w.image
  11573. elif key == keys.SPACE and pick_white != None:
  11574. for square in board:
  11575. # shouldnt be able to drop if there is already white piece there
  11576. if elf.colliderect(square):
  11577. # make sure the move is valid
  11578. ...
  11579. back.append(pick_image)
  11580. back.append(pick_y)
  11581. back.append(pick_x)
  11582. back.append(pick_white)
  11583. pick_white.x = square.x
  11584. pick_white.y = square.y
  11585. ...
  11586. if key == keys.B:
  11587. if len(back) != 0:
  11588. actor = back.pop()
  11589. x = back.pop()
  11590. y = back.pop()
  11591. image = back.pop()
  11592. actor.x = x
  11593. actor.y = y
  11594. actor.image = image
  11595. ...
  11596. ```
  11597. We are using the list like a stack, we add stuff to it and when we need we pop the top most items. You can see that we append image, y, x, actor but when we pop we get them in reverse order, because pop() removes the top most item from the ist, so we get back actor, x, y, image.
  11598. There is a fundamental limitation to this aproach, which is that we lose pieces that were taken, so if you undo they will just be gone.
  11599. ## [DAY-182] look back
  11600. Today we will look back on some of the first programs you wrote.
  11601. Open our old files and read as many of them as you can.
  11602. ## [DAY-183] Generalization
  11603. From today we will start to think before we code. You can see the game of chess we made, it kind of works but it is quite hard to add things to it, and to add new rules and etc. It is already around 500 lines of hard to read if statements.
  11604. We will do one week of exercises without writing code, just with pen and paper, where we will generalize, or try to extract the common attributes of things. We will think about how to think about things.
  11605. Lets start with an example. You know that `1 + 2` is the same as `2 + 1`, or `1 + 2 = 2 + 1`, same with `3 + 5 = 5 + 3`, this is quite intuitive, if you have two apples in one hand and one in the other, you have 3 apples irrelevant of which hand has 2 apples and which has 1. We can generalize that rule to `a + b = b + a`, meaning that any number `a` plus any number `b` is the same as wiriting `b+a`. It might seem like we did nothing here, just stated the obvious, but I will show you how powerful this generalization is.
  11606. At first we were thinkging of numbers, but with this generalization we can actually use expressions, for example `a = ((4838 + 8272) * 3)` and `b = ((7467 / 2) + 27838)` and still `a + b = b + a`, we can substitute `a` and `b`, so `((4838 + 8272) * 3) + ((7467 / 2) + 27838) = ((7467 / 2) + 27838) + ((4838 + 8272) * 3)`. We have higher level of reason, we are not confined to numbers anymore, but to whole expressions and expressions of expressions.
  11607. Lets talk now about what is needed to represent a chess piece. First we need its color, is it black or white, we need its kind (rook, bishop etc..), and its position x and y. Those are the properties of a piece. Each piece however can move in a different way, this is its behavior. Those are the two main things we have to think about, we can generalize thenm into 'what does the thing do' and 'how does the thing look'.
  11608. This week we will spend more time on examples about generalization and abstraction, and after that we will rewrite the chess game. It is very common to write something quick, and then rewrite it when you know how to actually think about it. The first time you code something is almost never good, purely because you still dont know how to represent the things in your program yet, even if you think a lot about it. In the real world you need to combine the both aproaches, of code and explore, and think carefully about how the pieces in your program talk to each other.
  11609. ## [DAY-184] Generalization
  11610. > We (me and my daughter) have spent 30 minutes per day for the last week just talking about how to think about behavior and state. With all kinds of discussions, from tic tac toe, to stratego, to classess and lists and many more concepts. The talks were very open and unstructured, so it is hard to put them directly 1:1 in the book. I recommend you do the same. Spend time talking about how to think about your program, how the parts in it communicate, how you group the state, and how do you abstract behaviour. It is also important to think about how to think about problems in general, move one layer above practicality. Discuss patterns.
  11611. ## [DAY-185] Generalization
  11612. Today we will build three different versions of snakes and ladders to illustrate different approaches.
  11613. We will use super small Snakes and Ladders game with the following rules:
  11614. * there are 9 squares, from 0 to 8
  11615. * 0 -> 0
  11616. * 1 -> 2
  11617. * 2 -> 2
  11618. * 3 -> 3
  11619. * 4 -> 2
  11620. * 5 -> 7
  11621. * 6 -> 0
  11622. * 7 -> 7
  11623. * 8 -> 8
  11624. 1. While and If, most basic implementation. In this implementation if we do 99 squares or we want to render a board, or we want to make the game more interesting to roll the dice twice or something like that, everything will just explode in complexity.
  11625. ```
  11626. player1 = 0
  11627. while True:
  11628. print("player board position: ", player1)
  11629. dice = int(input("dice roll> "))
  11630. player1 += dice
  11631. if player1 == 1:
  11632. player1 = 3
  11633. elif player1 == 4:
  11634. player1 = 2
  11635. elif player1 == 5:
  11636. player1 = 7
  11637. elif player1 == 6:
  11638. player1 = 0
  11639. ```
  11640. 2. Think about the rules of the game and what is a bit more abstract way to think about the them. The only rule actually is: if you land on the square you move wherever the square says, could be 0 (stay there), +steps or -steps. This is an example implementation where we just keep the state of each square in a list, square index 1 moves you to index 3 and so on.
  11641. ```
  11642. board = [
  11643. 0,
  11644. 2, # 1 -> 3
  11645. 0,
  11646. 0,
  11647. -2, # 4 -> 2
  11648. 2, # 5 -> 7
  11649. -6, # 6 -> 0
  11650. 0,
  11651. 0
  11652. ]
  11653. player1 = 8
  11654. while True:
  11655. print("player board index: ", player1)
  11656. dice = int(input("dice roll> "))
  11657. player1 += dice
  11658. if player1 >= len(board) - 1:
  11659. print("finished")
  11660. break
  11661. snake_or_ladder = board[player1]
  11662. player1 += snake_or_ladder
  11663. ```
  11664. The whole game is actually encoded in those two lines:
  11665. ```
  11666. snake_or_ladder = board[player1]
  11667. player1 += snake_or_ladder
  11668. ```
  11669. See how different this is? The size of the code is very similar in lines, but this version is so much easier to change and to extend. For example if we want to display the board, now we can just pass the board list to some `render` function and be done. This is actually not possible in the first version with the if conditions unless we almost duplicate the whole program.
  11670. 3. There is one more thing we could do to simplify it a bit, and that is to split the board from the input. So that we could move it maybe in a separate file (board.py) if we want. Separating the user input from the board action is quite nice because now it will be super easy to add mouse click functionality, and board rendering.
  11671. ```
  11672. class Board:
  11673. def __init__(self):
  11674. self.player = 0
  11675. self.squares = [
  11676. 0,
  11677. 2, # 1 -> 3
  11678. 0,
  11679. 0,
  11680. -2, # 4 -> 2
  11681. 2, # 5 -> 7
  11682. -6, # 6 -> 0
  11683. 0,
  11684. 0
  11685. ]
  11686. def move(self, dice):
  11687. position = self.player + dice
  11688. if position >= len(self.squares) - 1:
  11689. return True
  11690. self.player += self.squares[position]
  11691. return False
  11692. #################################################
  11693. b = Board()
  11694. while True:
  11695. print("player board position: ", b.player)
  11696. roll = int(input("dice roll> "))
  11697. if b.move(roll):
  11698. print('finished')
  11699. break
  11700. ```
  11701. ## [DAY-186] If
  11702. Make snakes and ladders on your own with pygame zero.
  11703. ![game-186-b.png](./screenshots/game-186-b.png "game 186-b screenshot")
  11704. > This is what she wrote. She just went and found 500x500 board so that its easy to compute the position of each square, and hardcoded the jumps.
  11705. ```
  11706. import pgzrun
  11707. import random
  11708. HEIGHT = 500
  11709. WIDTH = 500
  11710. elf = Actor("c1")
  11711. elf.x = -25
  11712. elf.y = 475
  11713. game_over = False
  11714. board = Actor("snake-500")
  11715. def on_key_down(key):
  11716. if key == keys.SPACE:
  11717. elf.x += random.choice([50,100,150,200,250,300])
  11718. if elf.x > 475 and elf.y == 25:
  11719. elf.x = 25
  11720. elf.y = 25
  11721. if elf.x > 475:
  11722. elf.x -= 500
  11723. elf.y -= 50
  11724. if elf.y == 375 and elf.x == 225:
  11725. elf.y = 475
  11726. elf.x = 225
  11727. if elf.y == 25 and elf.x == 25:
  11728. elf.y = 175
  11729. if elf.y == 475 and elf.x == 125:
  11730. elf.y = 225
  11731. elf.x = 25
  11732. if elf.y == 325 and elf.x == 175:
  11733. elf.y = 475
  11734. elf.x = 25
  11735. if elf.y == 475 and elf.x == 275:
  11736. elf.y = 375
  11737. elf.x = 325
  11738. if elf.y == 175 and elf.x == 125:
  11739. elf.y = 25
  11740. elf.x = 225
  11741. if elf.y == 75 and elf.x == 325:
  11742. elf.y = 225
  11743. elf.x = 325
  11744. if elf.y == 25 and elf.x == 425:
  11745. elf.y = 175
  11746. elf.x = 425
  11747. if elf.y == 475 and elf.x == 425:
  11748. elf.y = 175
  11749. elf.x = 425
  11750. def update():
  11751. global game_over
  11752. speed = 10
  11753. if keyboard.UP:
  11754. elf.y -= speed
  11755. if keyboard.DOWN:
  11756. elf.y += speed
  11757. if keyboard.LEFT:
  11758. elf.x -= speed
  11759. if keyboard.RIGHT:
  11760. elf.x += speed
  11761. if elf.x == 475 and elf.y == 25:
  11762. game_over = True
  11763. def draw():
  11764. board.draw()
  11765. elf.draw()
  11766. if game_over == True:
  11767. screen.draw.text('YOU WIN CONGRATULATION',(100,100),color = (0,0,0))
  11768. pgzrun.go()
  11769. ```
  11770. > she also made a grid to compute the positions of each square
  11771. ![game-186-a.png](./screenshots/game-186-a.png "game 186-a screenshot")
  11772. ## [DAY-187] If; While; Functions
  11773. Watch Programming for Advanced Beginners: Battleships - EP 1, from Robert Heaton (https://www.youtube.com/watch?v=Gi0Fdyhk1_0), and then watch it again and code with the author
  11774. ## [DAY-188] OOP
  11775. Watch https://www.youtube.com/watch?v=JeznW_7DlB0 (Python Object Oriented Programming (OOP) - For Beginners
  11776. from Tech With Tim)
  11777. ## [DAY-189] Keyword Arguments; String Methods
  11778. Today you have to watch three videos:
  11779. * Python keyword arguments 🔑 by Bro Code - https://www.youtube.com/watch?v=Tu0lFBXQgPw
  11780. * Python string methods by Bro Code - https://www.youtube.com/watch?v=crw3rVFNwIM
  11781. * Python Object Oriented Programming (OOP) - For Beginners from Tech With Tim - https://www.youtube.com/watch?v=JeznW_7DlB0 (watch it again)
  11782. ## [DAY-190] While
  11783. Make a web whatsapp bot that sends the same message in an infinite loop
  11784. * click on the chrome tab with whatsapp
  11785. * click on the search box
  11786. * searche for contact name (dad)
  11787. * clicks on the top result
  11788. * click on the message input field
  11789. * type 'hello world'
  11790. * click the send button
  11791. Using https://pyautogui.readthedocs.io/en/latest/ as a guide. There are many ways to read documentation, try to spend some time just brawsing through it. Another way is to go to the example section and see if you can find examples that can help you solve your problem.
  11792. This is a snippet with examples taken from pyautogui's page:
  11793. ```
  11794. >>> import pyautogui
  11795. >>> screenWidth, screenHeight = pyautogui.size() # Get the size of the primary monitor.
  11796. >>> screenWidth, screenHeight
  11797. (2560, 1440)
  11798. >>> currentMouseX, currentMouseY = pyautogui.position() # Get the XY position of the mouse.
  11799. >>> currentMouseX, currentMouseY
  11800. (1314, 345)
  11801. >>> pyautogui.moveTo(100, 150) # Move the mouse to XY coordinates.
  11802. >>> pyautogui.click() # Click the mouse.
  11803. >>> pyautogui.click(100, 200) # Move the mouse to XY coordinates and click it.
  11804. >>> pyautogui.click('button.png') # Find where button.png appears on the screen and click it.
  11805. >>> pyautogui.move(400, 0) # Move the mouse 400 pixels to the right of its current position.
  11806. >>> pyautogui.doubleClick() # Double click the mouse.
  11807. >>> pyautogui.moveTo(500, 500, duration=2, tween=pyautogui.easeInOutQuad) # Use tweening/easing function to move mouse over 2 seconds.
  11808. >>> pyautogui.write('Hello world!', interval=0.25) # type with quarter-second pause in between each key
  11809. >>> pyautogui.press('esc') # Press the Esc key. All key names are in pyautogui.KEY_NAMES
  11810. >>> with pyautogui.hold('shift'): # Press the Shift key down and hold it.
  11811. pyautogui.press(['left', 'left', 'left', 'left']) # Press the left arrow key 4 times.
  11812. >>> # Shift key is released automatically.
  11813. >>> pyautogui.hotkey('ctrl', 'c') # Press the Ctrl-C hotkey combination.
  11814. >>> pyautogui.alert('This is the message to display.') # Make an alert box appear and pause the program until OK is clicked.
  11815. ```
  11816. > use `pyautogui.position()` to find the accurate positions for your screen.
  11817. ```
  11818. import pyautogui
  11819. import time
  11820. while True:
  11821. pyautogui.click(305,10)
  11822. pyautogui.click(117,252)
  11823. pyautogui.write('dad', interval=0.25)
  11824. pyautogui.click(185, 395)
  11825. pyautogui.write('hello world!', interval=0.20)
  11826. pyautogui.click(935, 1132)
  11827. time.sleep(1)
  11828. ```
  11829. Have some fun with it pranking your parents :) _but not too much_.
  11830. ## [DAY-191] While
  11831. Make another whatsapp bot, but this time send a very very long message.
  11832. ```
  11833. import pyautogui
  11834. import time
  11835. import random
  11836. while True:
  11837. pyautogui.click(305,10)
  11838. pyautogui.click(117,252)
  11839. pyautogui.write('dad', interval=0.25)
  11840. time.sleep(1)
  11841. pyautogui.click(185, 395)
  11842. time.sleep(1)
  11843. for i in range(3000):
  11844. s = 'yo' * random.randint(1, 4)
  11845. pyautogui.write(s + ' ')
  11846. time.sleep(5)
  11847. pyautogui.click(935, 1132)
  11848. ```
  11849. this will send the message:
  11850. "yoyoyo yoyoyo yoyoyo yoyoyoyo yo yo yoyoyo yoyoyo yoyoyoyo yo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyo yo yo yoyo yoyo yo yoyo yoyo yo yoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyoyoyo yoyoyo yo yoyoyoyo yo yoyoyo yoyo yoyoyo yoyo yo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yo yoyoyo yoyoyo yoyoyoyo yoyo yoyo yo yoyo yoyoyo yoyoyoyo yoyo yo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yo yo yo yoyo yo yoyoyo yoyo yoyoyo yoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyo yo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yo yoyoyo yoyoyoyo yoyo yo yoyoyo yoyo yoyo yoyo yo yo yoyo yoyoyoyo yo yoyo yo yoyoyo yo yoyoyo yoyoyoyo yoyoyo yoyo yoyo yo yoyoyoyo yo yoyo yo yoyoyoyo yoyoyo yo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yoyo yo yo yoyoyoyo yoyo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyo yo yoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyo yo yoyoyoyo yo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyoyo yoyo yoyo yoyo yoyo yo yo yoyo yoyo yo yoyo yoyo yoyoyo yoyo yo yo yoyoyoyo yo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyo yoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yo yoyoyo yo yoyoyo yoyoyoyo yo yo yoyoyo yoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyoyoyo yoyo yo yoyoyoyo yoyo yoyo yo yo yoyoyo yo yo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyo yoyo yo yo yoyoyoyo yoyo yoyo yoyoyo yoyo yo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyo yoyo yo yoyoyoyo yoyo yoyoyoyo yoyo yo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yoyoyo yo yo yoyoyo yoyoyo yoyoyoyo yo yo yo yoyoyo yoyo yoyo yoyoyo yoyo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyoyo yo yoyoyoyo yo yo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyo yo yo yoyo yoyoyoyo yo yo yoyoyo yo yoyoyo yoyoyoyo yo yoyo yoyoyo yoyo yoyoyo yo yo yoyoyo yoyoyoyo yo yo yoyoyo yoyo yoyoyoyo yo yoyo yoyo yoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yo yo yoyoyoyo yoyoyoyo yoyo yo yoyo yoyo yo yoyoyo yoyoyo yoyoyoyo yo yoyoyo yoyo yoyoyoyo yo yoyo yo yoyo yoyoyoyo yo yoyoyo yoyo yoyo yoyoyo yoyoyoyo yo yo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyo yoyo yo yo yo yoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyoyo yo yoyoyo yo yo yoyo yo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yo yo yoyoyo yo yoyo yoyoyo yoyo yoyoyo yoyo yo yoyo yo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yo yoyo yoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyo yo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyo yo yoyo yo yoyo yo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yo yoyo yo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyo yo yoyoyo yoyoyo yoyo yoyo yoyo yoyo yo yoyo yoyo yoyoyo yoyoyo yoyoyoyo yoyo yo yo yoyo yo yoyoyoyo yo yoyoyoyo yoyoyo yoyo yoyoyo yoyo yoyoyo yoyoyo yoyoyo yo yo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyo yoyo yo yoyo yo yoyoyo yo yoyoyo yo yoyoyoyo yoyo yo yoyo yoyo yoyoyo yoyoyo yo yo yoyoyoyo yoyo yo yo yoyoyo yo yo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyo yo yoyoyo yoyoyoyo yoyoyoyo yo yo yo yoyoyo yo yoyo yoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yo yoyoyoyo yo yoyoyo yo yoyoyo yoyoyoyo yoyo yo yoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyo yoyo yoyoyo yoyo yoyoyo yoyoyo yo yo yoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyo yoyo yo yoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yo yoyoyoyo yoyo yoyoyoyo yo yo yoyoyoyo yoyoyoyo yoyoyo yo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyo yoyo yoyo yo yoyoyo yoyoyo yo yoyoyoyo yo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyo yoyoyo yo yoyo yoyo yoyo yoyo yoyoyoyo yoyo yo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yoyo yo yoyoyo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyoyo yo yoyo yoyoyoyo yo yoyoyo yoyoyo yoyoyoyo yoyo yoyoyo yoyo yo yoyo yoyoyo yo yoyo yo yo yoyoyo yo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyo yoyo yoyoyo yoyo yoyoyo yoyo yo yoyoyoyo yoyoyo yo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yoyoyoyo yoyoyo yoyo yo yoyo yo yoyoyo yo yoyoyo yo yoyoyoyo yoyoyo yo yo yoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyo yo yoyoyo yoyoyo yoyo yoyo yoyoyoyo yo yoyo yoyo yoyo yoyo yoyoyoyo yoyo yoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyoyoyo yo yoyoyoyo yoyo yoyo yoyoyoyo yoyo yo yo yoyo yo yoyo yo yoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yo yo yoyoyoyo yoyo yoyoyo yoyo yoyo yoyoyoyo yo yoyo yoyo yoyo yoyoyoyo yo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyo yoyoyo yoyoyoyo yoyoyo yo yoyo yo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyoyoyo yoyo yo yoyo yoyoyo yoyoyoyo yoyo yoyoyo yo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyoyo yoyo yo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yo yoyoyo yoyoyo yoyo yoyoyo yoyo yoyo yoyoyo yo yoyo yoyoyo yoyo yoyoyo yoyo yoyoyo yoyoyo yo yoyoyo yoyo yoyo yoyoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yo yo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyo yo yoyoyo yo yoyo yoyoyo yoyo yoyo yo yoyoyoyo yoyoyoyo yo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yo yoyo yoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yo yoyo yoyoyoyo yoyo yo yoyo yoyoyoyo yoyoyo yo yoyoyoyo yoyoyo yoyo yo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yoyoyo yoyo yo yoyoyo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyoyo yo yoyoyo yoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yo yo yo yoyo yoyoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yo yoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yo yo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyo yo yoyoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyo yo yo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yo yoyo yoyo yo yoyoyoyo yoyo yoyo yoyo yoyo yo yoyo yo yoyoyo yoyoyo yoyo yo yo yoyoyoyo yo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yo yoyo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yoyoyo yoyoyoyo yoyoyoyo yo yoyo yo yo yo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyo yoyo yo yoyo yo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yo yoyo yoyoyoyo yoyo yoyoyo yo yoyoyo yo yoyo yoyoyoyo yoyoyo yo yoyoyo yo yoyoyoyo yo yoyo yoyoyo yoyo yoyoyo yo yo yo yo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yo yo yoyo yoyoyoyo yoyoyo yo yoyo yoyo yo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yo yo yoyo yoyoyo yoyo yoyoyoyo yo yoyoyo yoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyoyo yo yo yoyoyo yoyoyoyo yoyo yoyoyoyo yo yoyo yo yoyoyoyo yoyoyo yoyoyo yo yo yoyo yoyoyo yoyoyo yoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyo yo yo yoyo yoyo yoyo yoyoyoyo yo yoyoyoyo yoyo yoyoyoyo yo yoyoyo yoyo yoyoyo yoyoyoyo yo yo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yo yo yoyoyoyo yoyo yo yoyo yoyo yoyo yoyoyoyo yo yoyo yo yo yoyoyoyo yoyo yoyo yoyoyoyo yoyo yoyoyo yo yo yo yoyo yo yoyoyoyo yoyo yoyo yoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyoyo yoyo yoyo yoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyo yo yoyo yoyo yoyoyo yo yo yoyo yoyo yo yoyo yoyoyo yo yoyoyoyo yoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yo yo yoyoyo yo yoyoyoyo yoyo yoyoyoyo yoyoyo yo yoyoyoyo yo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyo yoyo yo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyoyo yo yoyoyoyo yo yoyoyo yoyo yoyo yoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yoyoyo yo yoyoyoyo yoyoyo yoyo yoyoyo yo yo yoyoyo yoyoyo yoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yo yoyo yoyo yoyoyoyo yo yoyoyo yoyoyo yo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yo yoyo yoyoyoyo yo yo yoyoyoyo yoyo yoyo yoyoyo yoyo yoyo yoyo yo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyo yo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yo yo yoyoyo yoyo yo yoyo yo yoyoyo yo yoyoyo yoyoyo yoyo yoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyo yoyo yoyo yoyoyoyo yoyo yoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyo yo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yoyoyo yoyoyoyo yo yo yo yo yoyoyoyo yoyoyo yoyo yoyo yo yoyoyo yoyoyoyo yoyo yoyo yoyo yoyo yoyoyo yoyoyo yoyoyo yo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yo yo yoyoyoyo yo yoyoyo yoyo yoyoyo yoyo yoyo yoyo yo yoyo yoyoyo yo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyoyo yo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyo yo yo yoyoyo yo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yo yo yoyoyo yoyoyoyo yoyoyo yoyo yo yoyoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyo yo yoyoyoyo yo yoyoyo yoyo yoyoyo yo yoyoyoyo yo yo yo yoyoyo yo yo yoyo yoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyo yo yo yoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yo yo yo yo yo yoyo yo yo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yo yo yoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyoyoyo yoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yo yo yoyoyoyo yoyoyoyo yo yo yoyo yo yoyo yoyoyo yoyoyo yoyo yoyoyo yo yoyoyo yoyoyo yoyoyoyo yo yo yoyo yoyoyoyo yo yoyoyoyo yoyo yoyo yo yoyoyoyo yo yo yoyoyoyo yoyo yo yoyoyoyo yo yoyoyo yo yo yoyoyo yoyoyoyo yoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyo yoyo yoyo yo yo yoyoyoyo yoyoyo yoyo yoyo yo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyo yoyo yo yoyoyo yoyoyo yo yoyoyo yo yoyoyo yo yo yoyoyoyo yo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyoyo yoyoyo yo yo yoyo yoyo yoyoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyoyo yoyoyo yo yoyo yoyo yoyoyoyo yo yoyoyo yoyoyo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyoyo yo yoyo yoyoyoyo yoyoyo yo yoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyo yo yo yoyo yoyoyoyo yo yoyoyoyo yo yoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyo yo yoyoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyo yoyoyo yo yoyo yoyoyoyo yo yoyo yoyo yoyoyoyo yoyo yoyoyoyo yo yoyoyoyo yoyo yo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyo yoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyoyo yo yoyoyoyo yo yoyo yoyoyo yo yoyo yoyoyo yo yo yoyoyoyo yo yoyo yoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyoyo yoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yoyoyo yo yoyoyo yo yoyoyoyo yo yoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyo yoyo yo yo yoyoyo yoyoyo yoyoyoyo yoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyo yo yoyoyo yoyo yoyo yoyo yoyo yoyoyoyo yo yoyoyoyo yo yoyoyoyo yoyo yo yoyo yoyoyoyo yoyo yo yoyoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yo yo yoyoyo yoyoyo yo yoyo yoyo yoyoyoyo yo yoyo yoyo yoyoyo yoyoyoyo yo yo yoyoyo yo yoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyo yoyo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyo yoyo yoyoyo yoyoyo yoyo yo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yo yo yoyoyo yoyoyo yo yoyoyoyo yoyoyoyo yoyo yo yoyo yo yoyoyoyo yo yoyoyoyo yo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyo yo yoyoyo yoyoyoyo yoyo yoyoyo yo yo yoyoyo yo yoyoyoyo yoyoyoyo yo yo yoyoyoyo yoyoyoyo yo yoyo yoyo yo yoyo yo yoyoyoyo yoyo yo yoyoyo yoyoyoyo ypoyoyo yoyoyo yo yoyo yo yoyoyo yoyoyoyo yo yoyo yoyoyo yoyoyo yoyo yoyo yo yoyoyo yoyoyoyo yo yoyo yo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyo yo yoyoyoyo yoyo yoyoyo yoyo yoyo yo yoyoyoyo yoyo yoyoyo yoyo yo yoyoyo yoyoyoyo yo yoyo yoyoyoyo yo yo yoyoyo yoyo yoyo yo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yo yoyo yo yoyo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyo yoyo yo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yo yoyo yoyoyo yo yoyoyo yoyoyo yoyo yoyoyoyo yoyo yo yoyo yoyoyoyo yoyo yo yoyoyoyo yoyo yoyo yo yoyoyo yo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyo yo yoyoyo yo yoyoyo yoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yo yoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyoyo yo yoyo yo yoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyo yoyo yo yo yo yoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yo yoyo yoyoyo yo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyo yo yoyo yoyoyoyo yo yo yoyoyo yoyoyo yoyoyo yo yo yo yoyoyo yoyoyoyo yoyo yoyo yoyoyo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yo yoyoyoyo yo yo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyoyo yo yoyo yoyoyo yo yoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyo yo yoyoyo yoyoyoyo yoyo yoyoyo yo yoyoyoyo yoyo yo yoyoyoyo yo yoyoyoyo yo yoyoyoyo yo yo yoyoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyo yo yoyoyoyo yoyoyo yoyoyo yo yoyoyo yoyoyo yoyo yoyo yo yo yoyoyo yoyo yoyoyo yoyo yo yoyoyoyo yo yoyoyo yo yo yoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyo yoyoyo yo yoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyo yoyo yoyoyo yoyoyo yo yoyoyo yoyo yo yoyoyoyo yoyo yoyoyo yoyo yo yoyoyoyo yoyo yoyo yo yoyoyoyo yo yoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyo yo yoyoyoyo yoyoyo yoyo yoyoyoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yo yoyo yoyoyoyo yoyoyoyo yo yoyoyo yoyoyo yo yoyo yoyo yoyoyo yo yoyo yoyoyo yoyoyo yoyo yoyo yoyoyoyo yo yoyoyoyo yo yoyo yoyoyo yo yoyoyo yo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyo yo yoyoyoyo yoyo yo yoyo yoyo yoyoyoyo yoyoyo yoyo yo yoyo yoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yo yoyoyoyo yoyoyo yo yoyoyoyo yoyoyo yoyoyoyo yo yo yoyoyoyo yo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyoyo yo yoyoyo yoyoyo yoyoyoyo yoyo yoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyo yo yoyoyo yo yoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyoyo yo yoyoyo yoyoyoyo yoyo yo yoyoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yo yoyoyoyo yoyoyo yo yoyoyoyo yo yoyo yoyoyoyo yo yoyo yoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyo yo yoyoyo yoyoyo yo yoyoyo yoyoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyo yoyoyo yo yoyoyoyo yoyoyo yo yoyoyoyo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yo yo yoyoyo yoyoyoyo yoyoyoyo yo yoyo yoyoyoyo yoyo yoyoyo yoyoyo yo yo yoyoyoyo yo yoyoyoyo yo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyo yoyo yoyo yoyoyo yoyoyo yoyo yoyo yoyoyoyo yo yoyo yo yoyo yo yo yo yoyo yo yoyoyoyo yo yoyoyo yoyoyoyo yo yoyoyo yoyo yoyoyoyo yoyoyo yoyoyo yo yoyoyoyo yo yoyoyoyo yoyoyoyo yo yo yoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyo yo yoyoyoyo yoyo yo yo yoyo yoyoyoyo yoyoyoyo yo yo yoyoyo yoyoyoyo yo yoyoyoyo yo yoyo yoyoyo yoyoyoyo yoyoyo yoyo yoyo yo yo yo yoyoyoyo yoyoyo yoyo yoyo yoyoyo yoyoyo yoyoyo yoyo yo yo yoyoyo yoyo yo yoyoyoyo yoyoyoyo yoyoyo yo yo yoyoyoyo yo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyo yoyoyoyo yo yoyoyoyo yoyoyo yo yoyo yoyo yo yoyo yoyoyoyo yo yoyo yo yoyo yoyoyoyo yoyoyoyo yo yo yoyoyo yo yoyoyo yoyo yoyoyoyo yoyo yoyo yo yoyo yo yoyo yoyoyoyo yo yoyoyo yo yoyoyoyo yo yoyoyoyo yo yo yoyo yoyoyoyo yo yo yo yoyoyo yo yo yoyo yoyo yoyoyo yoyo yo yoyoyo yo yoyo yoyoyoyo yoyo yo yoyoyo yoyoyo yoyo yoyo yoyoyo yo yoyo yo yoyo yoyoyo yoyoyo yoyoyoyo yoyo yo yoyoyoyo yo yoyoyo yo yoyoyo yo yoyoyoyo yoyo yoyo yoyoyo yoyo yoyoyo yoyoyoyo yo yoyo yo yo yoyoyoyo yoyoyo yoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yo yoyoyo yo yoyoyo yo yoyoyoyo yoyo yo yo yoyoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yo yoyoyoyo yo yo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyo yoyoyo yoyoyo yoyo yoyoyo yoyoyo yoyo yo yo yoyo yoyoyoyo yoyoyoyo yoyo yoyo yoyo yo yoyoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyo yo yo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyoyo yoyo yo yoyoyoyo yo yoyoyoyo yoyoyo yoyo yoyo yoyoyoyo yoyoyoyo yoyoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyoyo yoyoyo yoyoyoyo yo yoyoyo yoyoyoyo yo yoyo yoyo yoyo yoyoyo yoyoyoyo yoyoyoyo yoyoyo yo yoyoyoyo yoyo yoyoyo yoyo yoyoyo yoyo yo yoyo yoyo yo yo yoyoyoyo yoyo yoyoyoyo yoyoyo yoyoyo yoyo yo yoyoyo yoyoyoyo yo yoyoyo yoyo yoyoyo yoyo yoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyoyo yoyoyoyo yoyoyoyo yoyo yoyoyo yoyo yo yo yo yoyoyoyo yoyo yo yo yoyoyoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yoyo yo yoyoyoyo yoyoyoyo yoyoyo yoyoyo yo yoyoyoyo yoyo yoyo yoyoyo yoyo yoyoyo yoyoyoyo yoyo yoyo yoyoyoyo yo yo yoyoyo yoyo yoyo yoyo yoyoyoyo yoyo yoyo yoyoyoyo yoyo yoyoyo yoyoyoyo yoyoyo yoyoyo yoyoyoyo yoyo yoyoyoyo yo yo yoyoyoyo yoyo yoyo yoyo yo yoyoyoyo yo yoyo yoyoyoyo yo yoyo yoyoyo yoyoyo yoyoyo"