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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Programming for kids (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://github.com/jackdoe/programming-for-kids">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>Programming for kids</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://github.com/jackdoe/programming-for-kids" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p>```
  71. ┌─┐┬─┐┌─┐┌─┐┬─┐┌─┐┌┬┐┌┬┐┬┌┐┌┌─┐
  72. ├─┘├┬┘│ ││ ┬├┬┘├─┤│││││││││││ ┬
  73. ┴ ┴└─└─┘└─┘┴└─┴ ┴┴ ┴┴ ┴┴┘└┘└─┘
  74. ┌─┐┌─┐┬─┐ <br />
  75. ├┤ │ │├┬┘ <br />
  76. └ └─┘┴└─ <br />
  77. ┬┌─┬┌┬┐┌─┐ <br />
  78. ├┴┐│ ││└─┐ <br />
  79. ┴ ┴┴─┴┘└─┘ </p>
  80. <blockquote>
  81. <p>by: Borislav Nikolov
  82. year: 2021</p>
  83. </blockquote>
  84. <p>The parent has to know how to program.
  85. Spend 30 minutes per day. Every day.</p>
  86. <p>"Anything worth doing is worth doing badly." — G. K. Chesterton</p>
  87. <p>```</p>
  88. <p><br>
  89. <br>
  90. <br>
  91. <br></p>
  92. <div style="page-break-before:always"></div>
  93. <h1>Hello World</h1>
  94. <p>::: warning
  95. <em>This chapter is for parents, kids skip to the next one.</em> <a href="https://github.com/jackdoe/programming-for-kids#day-0-the-computer">day 0 - the computer</a>
  96. :::</p>
  97. <h2>Why</h2>
  98. <p>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.</p>
  99. <p>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?</p>
  100. <p>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.</p>
  101. <p>Maybe she will grow hating it, or even hating me. Parenting is difficult.</p>
  102. <p>We are 7 months in, and so far she doesn't hate me.</p>
  103. <h2>About the book</h2>
  104. <p>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, <em>every day</em>. 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.</p>
  105. <p>Again, if your children are older, or younger, this book might not work, you could of course still find pieces that work for you.</p>
  106. <p>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.</p>
  107. <p>Also its nice to print a copy so they don't just copy paste.</p>
  108. <p>What you need:</p>
  109. <ul>
  110. <li>Computer</li>
  111. <li>Patience</li>
  112. <li>Internet</li>
  113. <li>Patience</li>
  114. </ul>
  115. <p>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.</p>
  116. <p>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.</p>
  117. <p>The emphasis on HTML helps with understanding hierarchy, <code>tr</code> is child of <code>table</code>, <code>table</code> is child of <code>body</code> body is child of <code>html</code>, <code>td</code> is a sister to <code>td</code> and both are children of <code>tr</code> etc, it helped a lot with my daughter understanding how the <code>else</code> is sibling to the <code>if</code> and how both are children to <code>while</code>.</p>
  118. <p>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.</p>
  119. <h2>Other materials</h2>
  120. <p>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.</p>
  121. <p>The Robot Turtles game is amazing as well, you can find it here: https://www.thinkfun.com/products/robot-turtles/</p>
  122. <p>Scratch works for some kids, mine didn't enjoy it much.</p>
  123. <p>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 <code>black/brown wire to gnd, red wire to 5v and orange wire to D9</code>, and run:</p>
  124. <p>```</p>
  125. <h1>include <Servo.h></h1>
  126. <h1>define SERVO_PIN 9</h1>
  127. <p>Servo s;
  128. void setup() {
  129. s.attach(SERVO_PIN, 1000, 2000);
  130. }</p>
  131. <p>void loop() {
  132. s.write(0);
  133. delay(500);</p>
  134. <p>s.write(60);
  135. delay(500);</p>
  136. <p>s.write(120);
  137. delay(500);
  138. }
  139. ```</p>
  140. <h2>Motivation</h2>
  141. <p>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.</p>
  142. <p>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.</p>
  143. <p>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.</p>
  144. <p>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.</p>
  145. <div style="page-break-before:always"></div>
  146. <h2>week - 0</h2>
  147. <h2>week - 000</h2>
  148. <p><a href="#day-0-the-computer">day-0 the computer</a></p>
  149. <p><a href="#day-0-files">day-0 files</a></p>
  150. <p><a href="#day-0-ascii">day-0 ascii</a></p>
  151. <p><a href="#day-0-magic">day-0 magic</a></p>
  152. <p><a href="#day-0-how-to-google">day-0 how to google</a></p>
  153. <p><a href="#day-1-touch-typing">day-1 touch typing</a></p>
  154. <p><a href="#day-2-install-python">day-2 install python</a></p>
  155. <p><a href="#day-2-make-a-useful-program">day-2 make a useful program</a></p>
  156. <p><a href="#day-3-touch-typing-using-your-program">day-3 touch typing using your program</a></p>
  157. <p><a href="#day-4-html---basics">day-4 html - basics</a></p>
  158. <p><a href="#day-5-html---basics">day-5 html - basics</a></p>
  159. <p><a href="#day-6-touch-typing">day-6 touch typing</a></p>
  160. <h2>week - 001</h2>
  161. <p><a href="#day-7-new-touch-typing-program">day-7 new touch typing program</a></p>
  162. <p><a href="#day-8-touch-typing">day-8 touch typing</a></p>
  163. <p><a href="#day-9-touch-typing-using-your-program">day-9 touch typing using your program</a></p>
  164. <p><a href="#day-10-html---basics">day-10 html - basics</a></p>
  165. <p><a href="#day-11-html---basics">day-11 html - basics</a></p>
  166. <p><a href="#day-12-touch-typing">day-12 touch typing</a></p>
  167. <p><a href="#day-13-html">day-13 html</a></p>
  168. <h2>week - 002</h2>
  169. <p><a href="#day-14-html---tables">day-14 html - tables</a></p>
  170. <p><a href="#day-15-html---more-tables">day-15 html - more tables</a></p>
  171. <p><a href="#day-16-html---multiplication-table">day-16 html - multiplication table</a></p>
  172. <p><a href="#day-17-html---multiplication-table">day-17 html - multiplication table</a></p>
  173. <p><a href="#day-18-touch-typing">day-18 touch typing</a></p>
  174. <p><a href="#day-19-html---links">day-19 html - links</a></p>
  175. <p><a href="#day-20-html---tree">day-20 html - tree</a></p>
  176. <h2>week - 003</h2>
  177. <p><a href="#day-21-html---view-source">day-21 html - view source</a></p>
  178. <p><a href="#day-22-html---inspect">day-22 html - inspect</a></p>
  179. <p><a href="#day-23-html---images">day-23 html - images</a></p>
  180. <p><a href="#day-24-licenses">day-24 licenses</a></p>
  181. <p><a href="#day-25-touch-typing">day-25 touch typing</a></p>
  182. <p><a href="#day-26-html---title">day-26 html - title</a></p>
  183. <p><a href="#day-27-html---fun-(js)">day-27 html - fun (js)</a></p>
  184. <h2>week - 004</h2>
  185. <p><a href="#day-28-print-functions-while-variables-conditions">day-28 print; functions; while; variables; conditions</a></p>
  186. <p><a href="#day-29-print-if">day-29 print; if</a></p>
  187. <p><a href="#day-30-functions-lists">day-30 functions; lists</a></p>
  188. <p><a href="#day-31-functions-if-random-lists">day-31 functions; if; random; lists</a></p>
  189. <p><a href="#day-32-lists-while">day-32 lists; while</a></p>
  190. <p><a href="#day-33-for">day-33 for</a></p>
  191. <p><a href="#day-34-love-tester">day-34 love tester</a></p>
  192. <p><a href="#day-34-touch-typing">day-34 touch typing</a></p>
  193. <h2>week - 005</h2>
  194. <p><a href="#day-35-lists-while-continue">day-35 lists; while; continue</a></p>
  195. <p><a href="#day-36-while-range-functions">day-36 while; range; functions</a></p>
  196. <p><a href="#day-37-while-functions">day-37 while; functions</a></p>
  197. <p><a href="#day-38-strings">day-38 strings</a></p>
  198. <p><a href="#day-39-touch-typing">day-39 touch typing</a></p>
  199. <p><a href="#day-40-functions-strings-range">day-40 functions; strings; range</a></p>
  200. <p><a href="#day-41-basics-of-basics">day-41 basics of basics</a></p>
  201. <h2>week - 006</h2>
  202. <p><a href="#day-41-lists-if-while">day-41 lists; if; while</a></p>
  203. <p><a href="#day-42-lists-functions-grid-while">day-42 lists; functions; grid; while</a></p>
  204. <p><a href="#day-43-if-range">day-43 if; range</a></p>
  205. <p><a href="#day-44-lists">day-44 lists</a></p>
  206. <p><a href="#day-45-lists-functions">day-45 lists; functions</a></p>
  207. <p><a href="#day-46-basic-turtle">day-46 basic turtle</a></p>
  208. <p><a href="#day-47-range-while">day-47 range; while</a></p>
  209. <h2>week - 007</h2>
  210. <p><a href="#day-48-strings-functions">day-48 strings; functions</a></p>
  211. <p><a href="#day-49-list-dictionaries">day-49 list; dictionaries</a></p>
  212. <p><a href="#day-50-lists-if">day-50 lists; if</a></p>
  213. <p><a href="#day-51-internet-awareness---scamsviruses">day-51 internet awareness - scams/viruses</a></p>
  214. <p><a href="#day-52-internet-awareness---how-login-works">day-52 internet awareness - how login works</a></p>
  215. <p><a href="#day-53-basics-of-the-internet---ipdns">day-53 basics of the internet - ip/dns</a></p>
  216. <p><a href="#day-54-touch-typing">day-54 touch typing</a></p>
  217. <h2>week - 008</h2>
  218. <p><a href="#day-55-lists-functions">day-55 lists; functions</a></p>
  219. <p><a href="#day-56-functions-if-random">day-56 functions; if; random</a></p>
  220. <p><a href="#day-57-lists-functions-grid">day-57 lists; functions; grid</a></p>
  221. <p><a href="#day-58-continue-previous-day">day-58 continue previous day</a></p>
  222. <p><a href="#day-59-tuples-lists">day-59 tuples; lists</a></p>
  223. <p><a href="#day-60-go-back-in-time">day-60 go back in time</a></p>
  224. <h2>week - 009</h2>
  225. <p><a href="#day-61-pygame-pygamezero-coordinates">day-61 pygame; pygamezero; coordinates</a></p>
  226. <p><a href="#day-62-collisions-callbacks">day-62 collisions; callbacks</a></p>
  227. <p><a href="#day-63-functions">day-63 functions</a></p>
  228. <p><a href="#day-64-lists-functions">day-64 lists; functions</a></p>
  229. <p><a href="#day-65-functions-collisions">day-65 functions; collisions</a></p>
  230. <p><a href="#day-66-schedule-callbacks-functions">day-66 schedule; callbacks; functions</a></p>
  231. <p><a href="#day-67-lists-functions">day-67 lists; functions</a></p>
  232. <h2>week - 010</h2>
  233. <p><a href="#day-68-lists-functions">day-68 lists; functions</a></p>
  234. <p><a href="#day-69-sockets-functions-callbacks">day-69 sockets; functions; callbacks</a></p>
  235. <p><a href="#day-70-lists-functions">day-70 lists; functions</a></p>
  236. <p><a href="#day-71-strings-integers-while-functions">day-71 strings; integers; while; functions</a></p>
  237. <p><a href="#day-72-reading-code">day-72 reading code</a></p>
  238. <p><a href="#day-73-reading-code">day-73 reading code</a></p>
  239. <p><a href="#day-74-strings-while-lists">day-74 strings; while; lists</a></p>
  240. <h2>week - 011</h2>
  241. <p><a href="#day-75-functions-callbacks-lists-encoding">day-75 functions; callbacks; lists; encoding</a></p>
  242. <p><a href="#day-76-functions-callbacks-lists">day-76 functions; callbacks; lists</a></p>
  243. <p><a href="#day-77-lists-encodedecode">day-77 lists; encode/decode</a></p>
  244. <p><a href="#day-78-coordinates-functions-callbacks">day-78 coordinates; functions; callbacks</a></p>
  245. <p><a href="#day-79-lists-encoding">day-79 lists; encoding</a></p>
  246. <p><a href="#day-80-lists-functions">day-80 lists; functions</a></p>
  247. <p><a href="#day-81-lists-encoding">day-81 lists; encoding</a></p>
  248. <h2>week - 012</h2>
  249. <p><a href="#day-82-lists-strings">day-82 lists; strings</a></p>
  250. <p><a href="#day-83-lists-functions">day-83 lists; functions</a></p>
  251. <p><a href="#day-84-lists">day-84 lists</a></p>
  252. <p><a href="#day-85-list-functions">day-85 list; functions</a></p>
  253. <p><a href="#day-86-lists">day-86 lists</a></p>
  254. <p><a href="#day-87-readwrite-files">day-87 read/write files</a></p>
  255. <p><a href="#day-88-flask">day-88 flask</a></p>
  256. <h2>week - 013</h2>
  257. <p><a href="#day-89-files-strings-lists">day-89 files; strings; lists</a></p>
  258. <p><a href="#day-90-strings">day-90 strings</a></p>
  259. <p><a href="#day-91-lists">day-91 lists</a></p>
  260. <p><a href="#day-92-command-line-command-line-arguments-files">day-92 command line; command line arguments; files</a></p>
  261. <p><a href="#day-93-pydoc">day-93 pydoc</a></p>
  262. <p><a href="#day-94-editors---ednanoviemacs..">day-94 editors - ed/nano/vi/emacs..</a></p>
  263. <p><a href="#day-95-memory-virtual-computer-instructions-strings-lists">day-95 memory; virtual computer; instructions; strings; lists</a></p>
  264. <h2>week - 014</h2>
  265. <p><a href="#day-95-memory-machine-code-virtual-computer">day-95 memory; machine code; virtual computer</a></p>
  266. <p><a href="#day-96-binary-ascii-memory">day-96 binary; ascii; memory</a></p>
  267. <p><a href="#day-97-lists-">day-97 lists; </a></p>
  268. <p><a href="#day-98-lists-readwrite-file">day-98 lists; read/write file</a></p>
  269. <p><a href="#day-99-classes-lists-functions-cartesian-coordinates">day-99 classes; lists; functions; cartesian coordinates</a></p>
  270. <p><a href="#day-100-touch-typing-lists">day-100 touch typing; lists</a></p>
  271. <p><a href="#day-101-functions-strings">day-101 functions; strings</a></p>
  272. <h2>week - 015</h2>
  273. <p><a href="#day-102-touch-typing-day">day-102 touch typing day</a></p>
  274. <p><a href="#day-103-read-file-command-line-arguments">day-103 read file; command line arguments</a></p>
  275. <p><a href="#day-104-read-file-command-line-arguments-dictionary">day-104 read file; command line arguments; dictionary</a></p>
  276. <p><a href="#day-105-basics-of-basics">day-105 basics of basics</a></p>
  277. <p><a href="#day-106-readwrite-file-lists">day-106 read/write file; lists</a></p>
  278. <p><a href="#day-107-lists-dictionaries">day-107 lists; dictionaries</a></p>
  279. <p><a href="#day-108-dictionaries">day-108 dictionaries</a></p>
  280. <h2>week - 016</h2>
  281. <p><a href="#day-109-touch-typing-day">day-109 touch typing day</a></p>
  282. <p><a href="#day-110-find-code-on-tiktok">day-110 find code on tiktok</a></p>
  283. <p><a href="#day-111-lists-random">day-111 lists; random</a></p>
  284. <p><a href="#day-112-use-simple-dictionary">day-112 use simple dictionary</a></p>
  285. <p><a href="#day-113-discover-pythontutor">day-113 discover pythontutor</a></p>
  286. <p><a href="#day-114-simple-turtle">day-114 simple turtle</a></p>
  287. <p><a href="#day-115-practical-coding-control-roblox-with-python">day-115 practical coding, control roblox with python</a></p>
  288. <h2>week - 017</h2>
  289. <p><a href="#day-116-many-turtles">day-116 many turtles</a></p>
  290. <p><a href="#day-117-another-text-editor">day-117 another text editor</a></p>
  291. <p><a href="#day-118-search-lyrics">day-118 search lyrics</a></p>
  292. <p><a href="#day-119-facial-recognition-move-78">day-119 facial recognition; move 78</a></p>
  293. <p><a href="#day-120-program-on-your-own-form-a-book">day-120 program on your own form a book</a></p>
  294. <p><a href="#day-121-scam-check-list">day-121 scam check list</a></p>
  295. <p><a href="#day-122-lists-random-mutate">day-122 lists; random; mutate</a></p>
  296. <h2>week - 018</h2>
  297. <p><a href="#day-123-lists-callbacks">day-123 lists; callbacks</a></p>
  298. <p><a href="#day-124-bmp-format-images-encodingdecoding">day-124 bmp format, images; encoding/decoding</a></p>
  299. <p><a href="#day-125-lists-dictionaries">day-125 lists; dictionaries</a></p>
  300. <p><a href="#day-126-readwrite-file">day-126 read/write file</a></p>
  301. <p><a href="#day-127-callbacks-schedule-interval">day-127 callbacks; schedule interval</a></p>
  302. <p><a href="#day-128-lists-cpu-usage-resources">day-128 lists; cpu usage; resources</a></p>
  303. <p><a href="#day-129-eat-your-computer-memory-cpu">day-129 eat your computer; memory; cpu</a></p>
  304. <h2>week - 019</h2>
  305. <p><a href="#day-130-turtle-lists-classes">day-130 turtle; lists; classes</a></p>
  306. <p><a href="#day-131-lists-files-dictionaries">day-131 lists; files; dictionaries</a></p>
  307. <p><a href="#day-132-lists-classes">day-132 lists; classes</a></p>
  308. <p><a href="#day-133-touch-typing-lists">day-133 touch typing; lists</a></p>
  309. <p><a href="#day-134-lists-methods">day-134 lists; methods</a></p>
  310. <p><a href="#day-134-if">day-134 if</a></p>
  311. <p><a href="#day-135-dictionary-for">day-135 dictionary; for</a></p>
  312. <h2>week - 020</h2>
  313. <p><a href="#day-136-for-arrays-memory">day-136 for; arrays; memory</a></p>
  314. <p><a href="#day-137-for-file-if">day-137 for; file; if</a></p>
  315. <p><a href="#day-138-for-file-if">day-138 for; file; if</a></p>
  316. <p><a href="#day-139-while-list-counter">day-139 while; list; counter</a></p>
  317. <p><a href="#day-140-while-turtle-strings">day-140 while; turtle; strings</a></p>
  318. <p><a href="#day-141-wiki-api">day-141 wiki; api</a></p>
  319. <p><a href="#day-142-while">day-142 while</a></p>
  320. <h2>week - 021</h2>
  321. <p><a href="#day-143-strings">day-143 strings</a></p>
  322. <p><a href="#day-144-strings-lists">day-144 strings; lists</a></p>
  323. <p><a href="#day-145-while">day-145 while</a></p>
  324. <p><a href="#day-146-while-classes">day-146 while; classes</a></p>
  325. <p><a href="#day-147-while">day-147 while</a></p>
  326. <p><a href="#day-148-money">day-148 money</a></p>
  327. <p><a href="#day-149-creators-consumers-and-ideas">day-149 creators, consumers and ideas</a></p>
  328. <h2>week - 022</h2>
  329. <p><a href="#day-150-while-classes">day-150 while; classes</a></p>
  330. <p><a href="#day-151-classes-while">day-151 classes; while</a></p>
  331. <p><a href="#day-152-lists">day-152 lists</a></p>
  332. <p><a href="#day-153-lists-dictionaries">day-153 lists; dictionaries</a></p>
  333. <p><a href="#day-154-classes">day-154 classes</a></p>
  334. <p><a href="#day-155-c++">day-155 c++</a></p>
  335. <p><a href="#day-156-for-while">day-156 for; while</a></p>
  336. <h2>week - 023</h2>
  337. <p><a href="#day-157-strings-cin">day-157 strings; cin</a></p>
  338. <p><a href="#day-158-if-while">day-158 if; while</a></p>
  339. <p><a href="#day-159-strings-sizeof">day-159 strings; sizeof</a></p>
  340. <p><a href="#day-160-pointers">day-160 pointers</a></p>
  341. <p><a href="#day-161-if-while-functions">day-161 if; while; functions</a></p>
  342. <p><a href="#day-162-if-while-variables">day-162 if; while; variables</a></p>
  343. <p><a href="#day-163-if-while-lists">day-163 if; while; lists</a></p>
  344. <h2>week - 024</h2>
  345. <p><a href="#day-164-pointers">day-164 pointers</a></p>
  346. <p><a href="#day-165-if-while">day-165 if; while</a></p>
  347. <p><a href="#day-166-if-while">day-166 if; while</a></p>
  348. <p><a href="#day-167-c-printf-scanf">day-167 c; printf; scanf</a></p>
  349. <p><a href="#day-168-c-while-if">day-168 c; while; if</a></p>
  350. <p><a href="#day-169-c-while-if">day-169 c; while; if</a></p>
  351. <p><a href="#day-170-pointers">day-170 pointers</a></p>
  352. <h2>week - 025</h2>
  353. <p><a href="#day-171-while-for-if-list">day-171 while; for; if; list</a></p>
  354. <p><a href="#day-172-if">day-172 if</a></p>
  355. <p><a href="#day-173-if-variables">day-173 if; variables</a></p>
  356. <p><a href="#day-174-if-list">day-174 if; list</a></p>
  357. <p><a href="#day-175-if">day-175 if</a></p>
  358. <p><a href="#day-176-if">day-176 if</a></p>
  359. <p><a href="#day-177-if">day-177 if</a></p>
  360. <h2>week - 026</h2>
  361. <p><a href="#day-178-if-absolute">day-178 if; absolute</a></p>
  362. <p><a href="#day-179-if-for">day-179 if; for</a></p>
  363. <p><a href="#day-180-if">day-180 if</a></p>
  364. <p><a href="#day-181-if">day-181 if</a></p>
  365. <p><a href="#day-182-look-back">day-182 look back</a></p>
  366. <p><a href="#day-183-generalization">day-183 generalization</a></p>
  367. <p><a href="#day-184-generalization">day-184 generalization</a></p>
  368. <h2>week - 027</h2>
  369. <p><a href="#day-185-generalization">day-185 generalization</a></p>
  370. <p><a href="#day-186-if">day-186 if</a></p>
  371. <p><a href="#day-187-if-while-functions">day-187 if; while; functions</a></p>
  372. <p><a href="#day-188-oop">day-188 oop</a></p>
  373. <p><a href="#day-189-keyword-arguments-string-methods">day-189 keyword arguments; string methods</a></p>
  374. <p><a href="#day-190-while">day-190 while</a></p>
  375. <p><a href="#day-191-while">day-191 while</a></p>
  376. <h2>[DAY-0] The Computer</h2>
  377. <p>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.</p>
  378. <p>```
  379. +------------------+
  380. | |
  381. | [ ] |
  382. | [ Processor ] |
  383. | [ ] |
  384. | |
  385. | [ Memory ] |
  386. | [ Memory ] |
  387. | |
  388. | [ Video Card ]--+------&gt; monitor
  389. | |
  390. | [ Disk ] |
  391. | | +---&gt; iphone
  392. | | +---&gt; mouse
  393. | [ USB ]---------+--+---&gt; keyboard
  394. | |
  395. | [ WiFi ] |
  396. | [ ... ] |
  397. +------------------+</p>
  398. <p>```</p>
  399. <p>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. </p>
  400. <p>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 <em>disks</em> 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.</p>
  401. <h2>[DAY-0] Files</h2>
  402. <p>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.</p>
  403. <p>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.</p>
  404. <p>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:</p>
  405. <p>```</p>
  406. <p>/
  407. ├─ home/
  408. │ ├─ jack/
  409. │ | ├─ type.py
  410. │ | ├─ example.txt
  411. │ | ├─ image.jpg</p>
  412. <p>```</p>
  413. <p>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.</p>
  414. <p>```
  415. /
  416. /
  417. /<strong><em>_</em></strong><strong><em>_</em></strong><strong><em>_</em>_
  418. |</strong><strong><em>_</em>_ </strong><strong><em>_</em></strong><em>
  419. /<strong><em>_</em> /|| |
  420. |".</strong></em>."| || |
  421. |<strong><em>_</em></strong>|/ | |
  422. || .<strong><em>."|| /
  423. ||</em></strong><strong><em>_|| /
  424. |</em></strong>______|/ Felix Lee</p>
  425. <p>```</p>
  426. <blockquote>
  427. <p>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.</p>
  428. </blockquote>
  429. <p>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.</p>
  430. <h2>[DAY-0] ASCII</h2>
  431. <p>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.</p>
  432. <p><code>``
  433. 32 SPC 64 @ 96</code>
  434. 33 ! 65 A 97 a
  435. 34 " 66 B 98 b
  436. 35 # 67 C 99 c
  437. 36 $ 68 D 100 d
  438. 37 % 69 E 101 e
  439. 38 &amp; 70 F 102 f
  440. 39 ' 71 G 103 g
  441. 40 ( 72 H 104 h
  442. 41 ) 73 I 105 i
  443. 42 * 74 J 106 j
  444. 43 + 75 K 107 k
  445. 44 , 76 L 108 l
  446. 45 - 77 M 109 m
  447. 46 . 78 N 110 n
  448. 47 / 79 O 111 o
  449. 48 0 80 P 112 p
  450. 49 1 81 Q 113 q
  451. 50 2 82 R 114 r
  452. 51 3 83 S 115 s
  453. 52 4 84 T 116 t
  454. 53 5 85 U 117 u
  455. 54 6 86 V 118 v
  456. 55 7 87 W 119 w
  457. 56 8 88 X 120 x
  458. 57 9 89 Y 121 y
  459. 58 : 90 Z 122 z
  460. 59 ; 91 [ 123 {
  461. 60 &lt; 92 \ 124 |
  462. 61 = 93 ] 125 }
  463. 62 &gt; 94 ^ 126 ~
  464. 63 ? 95 _</p>
  465. <p>```</p>
  466. <p>Try to decode: 110 105 99 101 32 119 111 114 107 33</p>
  467. <h2>[DAY-0] Magic</h2>
  468. <p><code>______________ _ _,-----------._ ___
  469. | | (_,.- _,-'_,-----------._`-._ _)_)
  470. | THE _ _ _ | | ,'_,-' ___________ `-._`.
  471. | | / \|_)| \ | `' ,',' _,-'___________`-._ `.`.
  472. | |__\_/| \|_/ | ,',' ,'_,-' . `-._`. `.`.
  473. | | /,' ,',' &gt;|&lt; `.`. `.\
  474. | OF THE _ _ | // ,',' &gt;&lt; ,^. &gt;&lt; `.`. \\
  475. | |_)||\|/_(_ | // /,' &gt;&lt; / | \ &gt;&lt; `.\ \\
  476. | | \|| |\_|_) | // // &gt;&lt; \/\^/\/ &gt;&lt; \\ \\
  477. |______________| ;; ;; `---' :: ::
  478. || || (____ || ||
  479. DOORS OF DURIN _||__||_ ,'----. _||__||_
  480. (o.____.o)____ `---' ____(o.____.o)
  481. | | /,--.) (,--.\ | |
  482. | |(( -`___ ___` ))| |
  483. | | \\,'', `. .' .``.// | |
  484. | | // (___,'. .'.___) \\ | |
  485. /| | ;;)) ____) . . (____ ((\\ | |\
  486. \|.__ | ||/ .'.--.\/ `/,--.`. \;: | __,|;
  487. |`-,`;.| :/ /,' `)-' `-(' `.\ \: |.;',-'|
  488. | `.. ' / \__.' `.__/ \ ` ,.' |
  489. | |,\ /, ,\ /,| |
  490. | ||: : ) . ( : :|| |
  491. /| |:; |/ . ./|\, , \| :;| |\
  492. \|.__ |/ : ,/- &lt;--:--&gt; ,\. ; \| __,|;
  493. |`-.``: `'/-. '\|/` ,-\`; ;'',-'|
  494. | `.. ,' `' ' ` `. ,.' |
  495. | || : : || |
  496. | || | | || |
  497. | || | | || |
  498. | |' | _ | `| |
  499. | | | '|)) | | |
  500. ;____: `._ `' _,' ;____:
  501. {______} \___________________/ {______}
  502. SSt |______|_______________________________|______|</code></p>
  503. <p>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?</p>
  504. <p>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 <strong>you</strong>, as every person is different.</p>
  505. <h2>[DAY-0] How to Google</h2>
  506. <p>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.</p>
  507. <p>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.</p>
  508. <p>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.</p>
  509. <p>The rules about how to use the internet are:</p>
  510. <ul>
  511. <li>The internet is sus!</li>
  512. <li>Never put your real name or phone number or address anywhere</li>
  513. <li>Never download anything unless your parent approves</li>
  514. <li>Never run anything you downloaded (sometimes downloads just start automatically)</li>
  515. <li>Don't trust messages like 'click here to get free iPhone' or 'clean your computer for free'</li>
  516. <li>Always ask your parent for help if you are not sure.</li>
  517. </ul>
  518. <p>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.</p>
  519. <h2>[DAY-1] Touch Typing</h2>
  520. <p>Touch typing is just typing without looking, if you are super slow while typing you will get frustrated too soon.</p>
  521. <p>Use https://www.keybr.com/ or ask someone to recommend you something. After using the touch typing app for few days, write your own.</p>
  522. <h2>[DAY-2] Install python</h2>
  523. <p>In general the first thing you should do when you don't know how to do something is to google it.</p>
  524. <p>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.</p>
  525. <p>Try to download from https://www.python.org/downloads/ and do it yourself, ask your parent for help if you are stuck.</p>
  526. <h2>[DAY-2] Make a useful program</h2>
  527. <p>After you have installed python3 run IDLE (ask your parent for help) and go to File -&gt; New File and type:</p>
  528. <p>```
  529. import random
  530. letters = 'fjfjfjfjfjfjjfghghghgaa;a;a;abcdefghijklmnopqrstuvwxyz'
  531. difficulty = 2</p>
  532. <p>while True:
  533. q = ''
  534. for i in range(difficulty):
  535. q = q + random.choice(letters)</p>
  536. <pre><code>a = input(q + ': ')
  537. if a == q:
  538. difficulty += 1
  539. else:
  540. if difficulty &gt; 2:
  541. difficulty -= 1
  542. </code></pre>
  543. <p>```</p>
  544. <p>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.</p>
  545. <p>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:</p>
  546. <p><code>aj: aj
  547. akg: akg
  548. jjgh: jjgh</code></p>
  549. <p>If you type it correctly, it will ask for a bigger sequence of characters, and if you make mistake it will ask for smaller. </p>
  550. <p>Don't rush it.</p>
  551. <p>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.</p>
  552. <h2>[DAY-3] Touch Typing using your program</h2>
  553. <p>Open IDLE again, go to File -&gt; Open File, and find where you saved your program, then double click to open it. After opened hit F5 and it will start again.</p>
  554. <p>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.</p>
  555. <blockquote>
  556. <p>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.</p>
  557. </blockquote>
  558. <h2>[DAY-4] HTML - Basics</h2>
  559. <p>We will start with HTML.</p>
  560. <p>Making a page can be a bit overwhelming, so just start small. for example:</p>
  561. <p>Open notepad and make a file on your desktop named "first.html", then write in it:</p>
  562. <p>```
  563. <html>
  564. <br />
  565. <body>
  566. <h1>welcome!</h1>
  567. <p>this is my page</p>
  568. </body></p>
  569. <p></html>
  570. ```</p>
  571. <p>Open Windows Explorer and find the file on your desktop and double click on it. </p>
  572. <p>Congrats! You have made your first web page!</p>
  573. <p>Now try this:</p>
  574. <p>```
  575. <html>
  576. <br />
  577. <body>
  578. <marquee>
  579. <h1>check this out!</h1>
  580. </marquee>
  581. <mark>Why would somebody use this?</mark>
  582. </body></p>
  583. <p></html>
  584. ```</p>
  585. <p>The rest of the day you will just try some other examples:</p>
  586. <p>List:</p>
  587. <p>```
  588. <html>
  589. <br />
  590. <body>
  591. <ul>
  592. <li>first <b>item</b></li>
  593. <li>second <i>item</i></li>
  594. <li>third</li>
  595. </ul>
  596. </body></p>
  597. <p></html>
  598. ```</p>
  599. <p>Horizontal Line:</p>
  600. <p>```
  601. <html>
  602. <br />
  603. <body>
  604. first
  605. line<br>
  606. second line<br>
  607. <hr>
  608. third line<br>
  609. </body></p>
  610. <p></html>
  611. ```</p>
  612. <p>'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!</p>
  613. <h2>[DAY-5] HTML - Basics</h2>
  614. <p>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.</p>
  615. <p>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.</p>
  616. <p>It looks for word between '&lt;' and then '&gt;', when it sees '&lt;' it knows what ever is between '&lt;' and '&gt;' 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 <strong>bold</strong>. There are many words like that you should try for yourself 'b' 'i' 'u' 'h1', and many more.</p>
  617. <p>For example, try this on your page: <code>&lt;b&gt;this is bold&lt;/b&gt;</code></p>
  618. <h2>[DAY-6] Touch Typing</h2>
  619. <p>Spend half the time using your program and half the time on keybr.com.</p>
  620. <h2>[DAY-7] New Touch Typing Program</h2>
  621. <p>Make new file on your desktop, touchtyping.html and type in it:</p>
  622. <p>```
  623. <center>
  624. <br />
  625. <pre style="font-size: 30px; letter-spacing: 4px;" id="question"></pre></p>
  626. <p></center></p>
  627. <script>
  628. var makeNewQuestion = function() {
  629. var letters = 'fjfjfjfjfjfjjfghghghgaa;a;a;abcdefghijklmnopqrstuvwxyz'
  630. var difficulty = 10
  631. var q = []
  632. for (var i = 0; i < difficulty; i++) {
  633. q.push(letters.charAt(Math.floor(Math.random() * letters.length)));
  634. }
  635. return q
  636. }
  637. var currentQuestion = makeNewQuestion()
  638. var questionElement = document.getElementById("question")
  639. questionElement.innerHTML = currentQuestion.join("")
  640. var position = 0
  641. document.body.addEventListener('keydown', (e) => {
  642. if (e.key == currentQuestion[position]) {
  643. position++
  644. if (position == currentQuestion.length) {
  645. currentQuestion = makeNewQuestion()
  646. position = 0
  647. } else {
  648. currentQuestion[position-1] = '<b>' + currentQuestion[position-1] + '</b>'
  649. }
  650. questionElement.innerHTML = currentQuestion.join("")
  651. }
  652. })
  653. </script>
  654. <p>```</p>
  655. <p>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.</p>
  656. <h2>[DAY-8] Touch Typing</h2>
  657. <p>Today just spend the day chilling on keybr.com</p>
  658. <blockquote>
  659. <p>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.</p>
  660. </blockquote>
  661. <h2>[DAY-9] Touch Typing using your program</h2>
  662. <p>Open touchtyping.html and spend the day using your awesome program. Once you open it, right click and then click on <code>View Source</code> to remember that you actually wrote this! Good job!</p>
  663. <h2>[DAY-10] HTML - Basics</h2>
  664. <p>From now on the HTML examples will be more code and less text, so you just have to go through them with your parent.</p>
  665. <p><code>&lt;html&gt;
  666. &lt;body&gt;
  667. &lt;h2&gt;welcome!&lt;/h2&gt;
  668. &lt;p&gt;
  669. this is my &lt;b&gt;first web page&lt;/b&gt; it has also &lt;i&gt;weird twist&lt;/i&gt;!
  670. &lt;/p&gt;
  671. &lt;hr&gt;
  672. &lt;p&gt;
  673. and a line
  674. &lt;/p&gt;
  675. &lt;/body&gt;
  676. &lt;/html&gt;</code></p>
  677. <p>Try to touch type as you are writing this, no need to hurry.</p>
  678. <p>```
  679. <html></p>
  680. <body>
  681. <h2>welcome!</h2>
  682. <p>
  683. this is my <b>first web page</b>!
  684. </p>
  685. and it has a bug!<br>
  686. <button onclick="document.body.appendChild(this.cloneNode(true))">🐛</button>
  687. </body>
  688. <p></html>
  689. ```</p>
  690. <p>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.</p>
  691. <p>You see we add this <code>onclick=...</code> 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 <code>onclick=..</code> stuff, so the other button you can press and it will copy itself again!</p>
  692. <p>Try to add more buttons by yourself with other emojis, 🏍️, 🏂, 🐓 or 🐧 for example.</p>
  693. <h2>[DAY-11] HTML - Basics</h2>
  694. <p>Making a presentation with HTML</p>
  695. <p>```
  696. <html>
  697. <body style="font-size: 24px;">
  698. <h1>Presentation For School</h1>
  699. <small>by: John, from class 4</small>
  700. <br>
  701. <br>
  702. <br>
  703. <br>
  704. <br>
  705. <hr></p>
  706. <pre><code> &lt;h1&gt;First Slide&lt;/h1&gt;
  707. &lt;ul&gt;
  708. &lt;li&gt;Something&lt;/li&gt;
  709. &lt;li&gt;very &lt;b&gt;important&lt;/b&gt;&lt;/li&gt;
  710. &lt;li&gt;and very &lt;i&gt;strange&lt;/i&gt;&lt;/li&gt;
  711. &lt;/ul&gt;
  712. &lt;br&gt;
  713. &lt;br&gt;
  714. &lt;br&gt;
  715. &lt;hr&gt;
  716. &lt;h1&gt;Second Slide&lt;/h1&gt;
  717. &lt;ul&gt;
  718. &lt;li&gt;Something Else&lt;/li&gt;
  719. &lt;li&gt;very &lt;u&gt;underline&lt;/u&gt;&lt;/li&gt;
  720. &lt;li&gt;and very &lt;del&gt;weird&lt;/del&gt;&lt;/li&gt;
  721. &lt;/ul&gt;
  722. &lt;br&gt;
  723. &lt;br&gt;
  724. &lt;br&gt;
  725. &lt;hr&gt;
  726. &lt;h1&gt;Third Slide&lt;/h1&gt;
  727. &lt;ul&gt;
  728. &lt;li&gt;... surely we can come up with a line&lt;/li&gt;
  729. &lt;li&gt;... and another line&lt;/li&gt;
  730. &lt;/ul&gt;
  731. &lt;br&gt;
  732. &lt;br&gt;
  733. &lt;br&gt;
  734. &lt;hr&gt;
  735. &lt;/body&gt;
  736. </code></pre>
  737. <p></html>
  738. ```</p>
  739. <h2>[DAY-12] Touch Typing</h2>
  740. <p>Use your program to touch type or go to keybr.com. </p>
  741. <p>Don't rush.</p>
  742. <h2>[DAY-13] HTML</h2>
  743. <p>This day is completely free style, try to put all kinds of HTML words inside each other, for example:</p>
  744. <p>```
  745. <html>
  746. <br />
  747. <body>
  748. <marquee>
  749. <ul>
  750. <li>
  751. <h1>
  752. <i>
  753. hello
  754. </i>
  755. </h1>
  756. </li>
  757. </ul>
  758. </marquee>
  759. </body></p>
  760. <p></html>
  761. ```</p>
  762. <p>Try to add the self cloning 🐛 button to that page.</p>
  763. <h2>[DAY-14] HTML - Tables</h2>
  764. <p>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.</p>
  765. <p>We use tables everywhere.</p>
  766. <p>Here are few examples:</p>
  767. <p>| power | pokemons |
  768. |-|-|
  769. | electiricy | Pikachu |
  770. | fire | Charmander |
  771. | grass | Bulbasaur |
  772. | poison | Bulbasaur |</p>
  773. <p>Or something you have probably seen, a multiplication table:</p>
  774. <p>| a | x | b | = |
  775. |---|---|---|----|
  776. | 5 | * | 5 | 25 |
  777. | 5 | * | 6 | 30 |
  778. | 5 | * | 7 | 37 |</p>
  779. <p>Make new file (or open the some old html page) and type this:
  780. ```
  781. <html>
  782. <br />
  783. <body>
  784. <table border="10">
  785. <tr><th>Name</th><th>Year</th></tr>
  786. <tr>
  787. <td>
  788. Donald Duck
  789. </td>
  790. <td>
  791. 1937
  792. </td>
  793. </tr>
  794. <tr>
  795. <td>
  796. Daisy Duck
  797. </td>
  798. <td>
  799. 1940
  800. </td>
  801. </tr>
  802. <tr>
  803. <td>
  804. Scrooge McDuck
  805. </td>
  806. <td>
  807. 1947
  808. </td>
  809. </tr>
  810. <tr>
  811. <td>
  812. Ludwig Von Drake
  813. </td>
  814. <td>
  815. 1961
  816. </td>
  817. </tr>
  818. </table>
  819. </body></p>
  820. <p></html>
  821. ```</p>
  822. <p>Only 3 new tags we have to learn <code>table, tr, td, th</code> are the main things we will work with, <code>tr</code> means table row and <code>td</code> is table data cell, or a column, <code>th</code> is table header. All the html key words you have learned so far are called <code>tags</code> or <code>elements</code>.</p>
  823. <p>Make <code>&lt;table border="100"&gt;</code> and see what happens.</p>
  824. <h2>[DAY-15] HTML - More tables</h2>
  825. <p>```
  826. <html>
  827. <br />
  828. <body>
  829. <table border="10">
  830. <tr><th>Name</th><th>Year</th></tr>
  831. <tr>
  832. <td>
  833. <marquee>
  834. hello world
  835. </marquee>
  836. </td>
  837. <td>
  838. <marquee>
  839. hello universe
  840. </marquee>
  841. </td>
  842. </tr>
  843. <tr>
  844. <td>
  845. <b>this does not move</b>
  846. </td>
  847. <td>
  848. <marquee>
  849. <i>this is italic</i>
  850. </marquee>
  851. </td>
  852. </tr>
  853. </table>
  854. </body></p>
  855. <p></html>
  856. ```</p>
  857. <p>Now make list in a table</p>
  858. <p>```</p>
  859. <table border=100>
  860. <tr>
  861. <td>
  862. <ul>
  863. <li>a</li>
  864. <li>b</li>
  865. <li>c</li>
  866. </ul>
  867. </td>
  868. <td>
  869. <ol>
  870. <li>a</li>
  871. <li>b</li>
  872. <li>c</li>
  873. </ol>
  874. </td>
  875. </tr>
  876. </table>
  877. <p>```</p>
  878. <p>Super small difference between <code>ul</code> and <code>ol</code>, one means 'unordered list' and the other one 'ordered list', so if you use <code>ol</code> every <code>li</code> will have its own number</p>
  879. <h2>[DAY-16] HTML - Multiplication table</h2>
  880. <p>Start writing the whole multiplication table
  881. (will take more than 1 day)</p>
  882. <h2>[DAY-17] HTML - Multiplication table</h2>
  883. <p>Finish writing the whole multiplication table.</p>
  884. <h2>[DAY-18] Touch Typing</h2>
  885. <p>Spend the day touch typing.</p>
  886. <h2>[DAY-19] HTML - Links</h2>
  887. <p>The most powerful feature of HTML is to be able to link to another place in the internet, try this:</p>
  888. <p><code>&lt;html&gt;
  889. &lt;body&gt;
  890. hi, &lt;a href="https://wikipedia.com"&gt;click here&lt;/a&gt; to go to wikipedia
  891. &lt;/body&gt;
  892. &lt;/html&gt;</code></p>
  893. <p>The <code>a</code> tag with its <code>href</code> 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..</p>
  894. <p>Whatever is in the <code>href</code> attribute this is where the browser will go after you click on whatever is inside the <code>&lt;a&gt;&lt;/a&gt;</code>, in our case <code>click here</code>. So after you click on <code>click here</code> your browser will go to wikipedia.com, and from there when you click somewhere it will go to wherever that <code>a</code>'s <code>href</code> points to.</p>
  895. <h2>[DAY-20] HTML - Tree</h2>
  896. <p>Rainbow:</p>
  897. <p><code>&lt;html&gt;
  898. &lt;body&gt;
  899. &lt;h1&gt;🌈&lt;/h1&gt;
  900. &lt;h1 style="color: red;"&gt;red&lt;/h1&gt;
  901. &lt;h1 style="color: orange"&gt;orange&lt;/h1&gt;
  902. &lt;h1 style="color: yellow"&gt;yellow&lt;/h1&gt;
  903. &lt;h1 style="color: green"&gt;green&lt;/h1&gt;
  904. &lt;h1 style="color: blue"&gt;blue&lt;/h1&gt;
  905. &lt;h1 style="color: indigo"&gt;indigo&lt;/h1&gt;
  906. &lt;h1 style="color: violet"&gt;violet&lt;/h1&gt;
  907. &lt;/body&gt;
  908. &lt;/html&gt;</code></p>
  909. <p>You dont always need <code>html</code> and <code>body</code>, the most browsers will show a page anyway, but it is good practice to do it proper and use <code>html</code> and <code>body</code> tags. Anyway, the next example is not "up to code".</p>
  910. <p>IT will make a sheep that follows your mouse, its pretty cool.</p>
  911. <p>```</p>
  912. <div id='sheep' style='position:absolute'>🐑</div>
  913. <script>
  914. var sheep = document.getElementById('sheep')
  915. document.body.onmousemove = (e) => {
  916. sheep.style.left = (e.clientX - 5 + 'px');
  917. sheep.style.top = (e.clientY - 5 + 'px');
  918. }
  919. </script>
  920. <p>```</p>
  921. <p>And a ghost button! it will remove itself when you press it.</p>
  922. <p><code>&lt;button onclick="this.parentNode.removeChild(this)"&gt;👻&lt;/button&gt;</code></p>
  923. <p>The way it works is <code>onclick=...</code> will call the code when you click on the button, in this case it says, "whoever <em>my</em> parent is, tell it to remove myself form its children list".</p>
  924. <p>You see, HTML is like a tree, let me show you.</p>
  925. <p>lets say our page is:</p>
  926. <p>```
  927. <html>
  928. <br />
  929. <body>
  930. <table border="10">
  931. <tr><th>Name</th><th>Year</th></tr>
  932. <tr>
  933. <td>
  934. <mark>
  935. hello
  936. </mark>
  937. </td>
  938. <td>
  939. <h1>
  940. world
  941. </h1>
  942. </td>
  943. </tr>
  944. <tr>
  945. <td>
  946. <b>move</b>
  947. </td>
  948. <td>
  949. <marquee>
  950. <i>italic</i>
  951. </marquee>
  952. </td>
  953. </tr>
  954. </table>
  955. </body></p>
  956. <p></html>
  957. ```</p>
  958. <p>It actually is a tree, every tag has children, and siblings
  959. ```
  960. <html>
  961. |
  962. <body>
  963. |
  964. <table>
  965. / | \
  966. / | \
  967. / | \
  968. / | \
  969. / | \
  970. / | \
  971. <tr> <tr> <tr> &lt;--- siblings, same parent
  972. /\ / \ / \
  973. / \ / \ / \
  974. <th> <th> <td> <td> <td> <td> &lt;--- the two td with same parent
  975. | | | | | | are siblings
  976. Name Year <mark> <h1> <b> <marquee>
  977. | | | |
  978. hello world move <i>
  979. |
  980. italic</p>
  981. <p>```</p>
  982. <p>Well trees in the world are actually the other way around haha. Leave it to programmers to not know how to make a tree :)</p>
  983. <p>```</p>
  984. <pre><code> italic
  985. |
  986. hello world move &lt;i&gt;
  987. | | | |
  988. Name Year &lt;mark&gt; &lt;h1&gt; &lt;b&gt; &lt;marquee&gt;
  989. | | | | | |
  990. &lt;th&gt; &lt;th&gt; &lt;td&gt; &lt;td&gt; &lt;td&gt; &lt;td&gt;
  991. \ / \ / \ /
  992. \/ \ / \ /
  993. &lt;tr&gt; &lt;tr&gt; &lt;tr&gt;
  994. \ | /
  995. \ | /
  996. \ | /
  997. \ | /
  998. \ | /
  999. \ | /
  1000. &lt;table&gt;
  1001. |
  1002. &lt;body&gt;
  1003. |
  1004. &lt;html&gt;
  1005. </code></pre>
  1006. <p>```</p>
  1007. <p>But you can see how all things that have the same parent are related, like brothers and sisters.</p>
  1008. <p>This is very important, we will spend the next week thinking about it as well.</p>
  1009. <h2>[DAY-21] HTML - View Source</h2>
  1010. <p>Browsers on laptops or pcs will allow you to rightclick on any page and then click on <code>View page source</code>, this will show you the HTML of the page your are looking at.</p>
  1011. <p>Open https://archive.org then right click on the pager and then click on <code>View page source</code>.</p>
  1012. <p>We will spend the rest of the day looking at some page sources</p>
  1013. <ul>
  1014. <li>https://archive.org</li>
  1015. <li>https://www.spacejam.com</li>
  1016. <li>https://www.asciiart.eu/</li>
  1017. <li>https://www.wikipedia.org</li>
  1018. <li>https://www.gutenberg.org/</li>
  1019. <li>https://digitalcomicmuseum.com/</li>
  1020. <li>https://www.terrypratchettbooks.com/</li>
  1021. <li>https://www.goodreads.com/</li>
  1022. </ul>
  1023. <h2>[DAY-22] HTML - Inspect</h2>
  1024. <p>Make new html file and write the following example:</p>
  1025. <p>```
  1026. Right click on this page, click Inspect and then go to Console.</p>
  1027. <script>
  1028. console.log('🐺🐺🐺🐺 You can see that in the console. 🐺🐺🐺🐺')
  1029. console.log('🐺🐺🐺🐺 type 12312*18237978123 in the console and see what happens. 🐺🐺🐺🐺')
  1030. </script>
  1031. <p>```</p>
  1032. <p>Open the file and then click F12, or right click on the page and click Inspect. You will see the logs.</p>
  1033. <p>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 <code>12312*18237978123</code> in the console and see the result.</p>
  1034. <p>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.</p>
  1035. <p>Lets try it. Make a new file with this content:</p>
  1036. <p>```
  1037. <html>
  1038. <br />
  1039. <body>
  1040. Your Robux Balance is: <b>0$</b>
  1041. </body></p>
  1042. <p></html>
  1043. ```</p>
  1044. <p>Open the file and then right click on <code>0$</code> and click inspect. Then you will see <code>&lt;b&gt;0$&lt;/b&gt;</code> 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.</p>
  1045. <h2>[DAY-23] HTML - Images</h2>
  1046. <p>To show an image you need the <code>img</code> tag, and give it <code>src</code> 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:</p>
  1047. <p>```
  1048. <html>
  1049. <br />
  1050. <body>
  1051. <img src="https://picsum.photos/id/237/200/300">
  1052. <img src="https://picsum.photos/id/40/200/300">
  1053. </body></p>
  1054. <p></html>
  1055. ```</p>
  1056. <p>Lets put the images in a table:</p>
  1057. <p>```
  1058. <html>
  1059. <br />
  1060. <body>
  1061. <table>
  1062. <tr>
  1063. <td>
  1064. <img src="https://picsum.photos/id/237/200/300">
  1065. </td>
  1066. <td>
  1067. <img src="https://picsum.photos/id/40/200/300">
  1068. </td>
  1069. </tr>
  1070. </table>
  1071. </body></p>
  1072. <p></html>
  1073. ```</p>
  1074. <p>Now of course we can have <code>img</code> in <code>a</code>, try this:</p>
  1075. <p>```
  1076. <html>
  1077. <br />
  1078. <body>
  1079. <table>
  1080. <tr>
  1081. <td>
  1082. <a href="https://wikipedia.com">
  1083. <img src="https://picsum.photos/id/237/200/300">
  1084. </a>
  1085. </td>
  1086. <td>
  1087. <a href="https://gutenberg.org">
  1088. <img src="https://picsum.photos/id/40/200/300">
  1089. </a>
  1090. </td>
  1091. </tr>
  1092. </table>
  1093. </body></p>
  1094. <p></html>
  1095. ```</p>
  1096. <p>Now you can click on the dog or the nose and it will lead you to the pages you link to.</p>
  1097. <p>Is it possible to have <code>img</code> and text in <code>a</code>? Well I am glad you asked!</p>
  1098. <p>```
  1099. <html>
  1100. <br />
  1101. <body>
  1102. <table>
  1103. <tr>
  1104. <td>
  1105. <a href="https://wikipedia.com">
  1106. <img src="https://picsum.photos/id/237/200/300">
  1107. <br>
  1108. This dog leads to wikipedia
  1109. </a>
  1110. </td>
  1111. <td>
  1112. <a href="https://gutenberg.org">
  1113. <img src="https://picsum.photos/id/40/200/300">
  1114. <br>
  1115. This cat (I think) leads to guttenberg.org
  1116. </a>
  1117. </td>
  1118. </tr>
  1119. </table>
  1120. </body></p>
  1121. <p></html>
  1122. ```</p>
  1123. <p>I even have <code>&lt;br&gt;</code> in the <code>a</code>, now you can click either on the image or on the text.</p>
  1124. <p>There is one more very important attribute of the <code>img</code> tag, and this is the <code>alt</code> 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 <code>alt="puppy"</code> on the puppy picture.</p>
  1125. <p>```</p>
  1126. <p>
  1127. Hello, and welcome to my page.
  1128. I hope you will like this image.
  1129. </p>
  1130. <p><img src="https://picsum.photos/id/237/200/300" alt="puppy">
  1131. ```</p>
  1132. <p>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 <code>alt</code> attribute on images it will say <code>Image ...</code> and whatever the value of <code>alt</code> is, in our case "puppy". So the reader will say:</p>
  1133. <p>```
  1134. Hello, and welcome to my page. I hope you will like this image. </p>
  1135. <p>Image puppy.
  1136. ```</p>
  1137. <p>If you have an image that has no information, like it is just there to make the site pretty, use <code>alt=""</code> then the screen reader will skip it.</p>
  1138. <h2>[DAY-24] Licenses</h2>
  1139. <p>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.</p>
  1140. <p>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.</p>
  1141. <p>Some licenses you can check out with your parents:</p>
  1142. <ul>
  1143. <li>Creative Commons Licenses CC-BY https://creativecommons.org/licenses/</li>
  1144. <li>GPL https://www.gnu.org/licenses/gpl-3.0.en.html</li>
  1145. <li>MIT License https://opensource.org/licenses/MIT</li>
  1146. <li>Apache License https://www.apache.org/licenses/LICENSE-2.0</li>
  1147. <li>Public Domain https://en.wikipedia.org/wiki/Public-domain-equivalent_license</li>
  1148. <li>Copyright https://en.wikipedia.org/wiki/Copyright</li>
  1149. </ul>
  1150. <p>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.</p>
  1151. <p>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..</p>
  1152. <p>Check out https://tldrlegal.com/ for super short description of licenses</p>
  1153. <h2>[DAY-25] Touch Typing</h2>
  1154. <p>relax and spend the day touch typing</p>
  1155. <h2>[DAY-26] HTML - Title</h2>
  1156. <p>```
  1157. <html>
  1158. <head>
  1159. <title>THIS IS SPARTA</title>
  1160. </head>
  1161. <br />
  1162. <body>
  1163. <marquee>
  1164. <ul>
  1165. <li>
  1166. <a href="https://wikipedia.com">click me</a>
  1167. </li>
  1168. <li>
  1169. <mark>hello world</mark>
  1170. </li>
  1171. </ul>
  1172. </marquee>
  1173. </body></p>
  1174. <p></html>
  1175. ```</p>
  1176. <p>Usually bodies have a <code>&lt;head&gt;</code> hehe.</p>
  1177. <p>In html in the <code>head</code> tag you can put things that will help the browser. For example, what is the <code>title</code> of this page? or what language is this page? Who is the author of this page? etc..</p>
  1178. <p>You can also put there some style, changing the body's background color, or the color of the text in the <code>h1</code> or <code>p</code>:</p>
  1179. <p>```
  1180. <html>
  1181. <head>
  1182. <style>
  1183. body {
  1184. background: blue;
  1185. }
  1186. p {
  1187. color: pink;
  1188. }
  1189. h1 {
  1190. color: cyan;
  1191. }
  1192. </style>
  1193. <title>some title</title>
  1194. </head>
  1195. <br />
  1196. <body>
  1197. <center>
  1198. <p>
  1199. Hello Universe
  1200. </p>
  1201. <h1>hello world</h1>
  1202. </center>
  1203. </body></p>
  1204. <p></html>
  1205. ```</p>
  1206. <p>The <em>language</em> we use inside the <code>style</code> tag is called <code>CSS</code>, 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</p>
  1207. <p>You see how in certain tags we can use different language, not html, like in <code>&lt;style&gt;</code> we use CSS, in <code>&lt;script&gt;</code> 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</p>
  1208. <h2>[DAY-27] HTML - Fun (JS)</h2>
  1209. <p>Many buttons</p>
  1210. <p>```
  1211. <button onclick="makeManyButtons()">🤖</button></p>
  1212. <script>
  1213. function makeManyButtons() {
  1214. // try to make million buttons!
  1215. for(var i = 0; i < 100; i++) {
  1216. var button = document.createElement('button')
  1217. button.innerText = '🐹'
  1218. document.body.appendChild(button)
  1219. }
  1220. }
  1221. </script>
  1222. <p>```</p>
  1223. <p>Replicator</p>
  1224. <p>```
  1225. <button onclick="replicate(10,'🦊')">🤖</button></p>
  1226. <script>
  1227. function replicate(n,buttonText) {
  1228. // try to make million buttons!
  1229. for(var i = 0; i < n; i++) {
  1230. var button = document.createElement('button')
  1231. button.onclick = function () {
  1232. replicate(20,'🦓')
  1233. };
  1234. button.innerText = buttonText
  1235. document.body.appendChild(button)
  1236. }
  1237. }
  1238. </script>
  1239. <p>```</p>
  1240. <p>Canvas</p>
  1241. <p>```
  1242. <html></p>
  1243. <body style="padding: 0; margin: 0">
  1244. <canvas id="squares"></canvas>
  1245. <script>
  1246. var canvas=document.getElementById('squares');
  1247. var ctx=canvas.getContext("2d");
  1248. canvas.width=window.innerWidth;
  1249. canvas.height=window.innerHeight;
  1250. function draw() {
  1251. ctx.fillStyle= '#' + Math.floor(Math.random()*16777215).toString(16);
  1252. ctx.globalAlpha=0.5;
  1253. var size=Math.floor((Math.random()) * 60) + 1;
  1254. var x = Math.floor(Math.random()*canvas.width)
  1255. var y = Math.floor(Math.random()*canvas.height)
  1256. ctx.fillRect(x, y, size, size);
  1257. };
  1258. setInterval(draw,10);
  1259. // why dont you try to make them rectangles instead of squares?
  1260. // or maybe even circles? google for 'canvas fillRect' and 'canvas arc'
  1261. </script>
  1262. </body>
  1263. <p></html>
  1264. ```</p>
  1265. <p>The last one is quite crazy! But I am sure you will like the result when done.</p>
  1266. <h2>[DAY-28] Print; Functions; While; Variables; Conditions</h2>
  1267. <p>Make a new file form IDLE, and write in it:
  1268. <code>print("Hi!")</code></p>
  1269. <p>Hit F5 and enjoy!</p>
  1270. <p>Your first(or second) python program.. Quite useless, but nevertheless. A program is a program!</p>
  1271. <p><code>print()</code> is called a function, functions are kind of mini useful programs, this one will print whatever you tell it. In this case <code>print("Hi!")</code> will output <code>Hi!</code>. 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.</p>
  1272. <p><code>"Hi!"</code> is a string, strings are just series of characters, you can make them in python with <code>"something"</code> or <code>'something'</code>, either single quotes or double quotes.</p>
  1273. <p><code>while True:
  1274. print("Hi!")</code></p>
  1275. <p><code>while True</code> that means forever. so you will see:</p>
  1276. <p>```
  1277. Hi!
  1278. Hi!
  1279. Hi!
  1280. Hi!
  1281. Hi!
  1282. Hi!
  1283. Hi!
  1284. Hi!
  1285. ...</p>
  1286. <p>```</p>
  1287. <p>Hi forever.</p>
  1288. <p><code>while 1 == 1:
  1289. print("Hi!)</code></p>
  1290. <p><code>1 == 1</code> is also True, so this is the same as <code>while True</code></p>
  1291. <p>So <code>while &lt;condition&gt;</code> will keep running the code <strong>inside</strong> it, while the condition holds true, which in the case of <code>1 == 1</code> will always be the case.</p>
  1292. <p><code>while True:
  1293. zzz = input("what is your name: ")
  1294. print(zzz)</code></p>
  1295. <p><code>input</code> asks you to type something, and it returns whatever you typed.</p>
  1296. <p><code>zzz = input(....)</code> takes whatever input returns, and puts it into memory that we can use later. <code>zzz</code> 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 <code>print(zzz)</code></p>
  1297. <p><code>print(name)</code> prints whatever is in the memory pointed by <code>zzz</code>.</p>
  1298. <p><code>zzz</code> is called a <code>variable</code>, you can choose the names of your variables, and <code>zzz</code> 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:</p>
  1299. <p><code>while True:
  1300. name = input("what is your name: ")
  1301. print(name)</code></p>
  1302. <p>A group of statements with common parent, is called <strong>code block</strong>, in python we use spaces to say what belongs where, so the closest <code>while,for,if,elif,else</code> going up is the parent.</p>
  1303. <p><code>while True:
  1304. name = input("what is your name: ")
  1305. print(name)</code></p>
  1306. <p>Will throw an error: <code>IndentationError: unexpected indent</code> because it makes no sense, there is no valid parent to <code>print</code>, This is quite unique in python, most other languages make code blocks with <code>{}</code>, but python makes it prettier and easier to read by using indentation (the spaces/tabs). <code>print(name)</code> has 4 spaces, while <code>name = input..</code> has 2 spaces, so python expect everything in the <code>while:</code> to have 2 spaces unless a new block starts.</p>
  1307. <p><code>while True:
  1308. name = input("what is your name: ")
  1309. if name == "pikachu":
  1310. print(name)</code></p>
  1311. <p>This works fine, <code>print(name)</code> now has valid parent that also has a parent.</p>
  1312. <p><code>while True:
  1313. | \
  1314. | \
  1315. | \
  1316. | \
  1317. if: name = input
  1318. |
  1319. print(name)</code></p>
  1320. <p><code>while True</code> has two children, <code>name = input ..</code> and <code>if name == ..</code> so they must have same indentation, then <code>if ..:</code> also expects a code block, so the children of <code>if name == ..</code> need to have one more indentation to whatever indentation the <code>if</code> had.</p>
  1321. <p>Anyway..</p>
  1322. <p>Don't worry too much about it, just don't panic when you see <code>IndentationError</code>, 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.</p>
  1323. <p>You have seen by now in JavaScript we use <code>{}</code> to group statements into blocks.</p>
  1324. <p><code>if (name == "pikachu") {
  1325. console.log("pikaaaachuuuuu")
  1326. console.log("evolutiooonn!")
  1327. }</code></p>
  1328. <p>Now lets break out of the loop!</p>
  1329. <p><code>while True:
  1330. name = input("what is your name: ")
  1331. if name == "pikachu":
  1332. break</code></p>
  1333. <p><code>if name == "pikachu":</code> will run the code inside <code>if</code> if whatever is in the <code>name</code> variable is equal to the string "pikachu". In this case its only 1 instruction inside it, the <code>break</code> instruction.</p>
  1334. <p><code>break</code> breaks out of the closest <code>while</code> 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.</p>
  1335. <p>```
  1336. while True:
  1337. name = input("what is your name: ")
  1338. print(name)
  1339. if name == "pikachu":
  1340. break</p>
  1341. <p>print("DONE")
  1342. ```</p>
  1343. <p>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.</p>
  1344. <p>```
  1345. name = ''
  1346. while name != "pikachu":
  1347. name = input("what is your name: ")
  1348. print(name)</p>
  1349. <p>print("DONE")
  1350. ```</p>
  1351. <p>MAGIC!</p>
  1352. <p>we start by making name equal to empty string, a string with no characters, and then we check is the statement <code>name != "pikachu"</code> True? If this is True we will execute the code <strong>inside</strong> the while loop, after the last instruction in the loop, the program jumps back to <code>while name != "pikachu"</code> and checks again is name still not equal to "pikachu"? if the statement is False it will not run the code <strong>inside</strong> but will continue, in the above example it will print DONE, because this is the first thing <strong>after</strong> the while loop.</p>
  1353. <p>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.</p>
  1354. <p><code>while True:
  1355. name = input("what is your name: ")
  1356. if name == "pikachu":
  1357. print("pikaaaaaaachuuuuu")
  1358. break
  1359. else:
  1360. print("Hello, " + name)</code></p>
  1361. <p>In python you can add two strings, if you type "charmander" for name, <code>x = "Hello, " + name</code> will make x to be equal to "Hello, charmander". You can't do <code>"hello" - name</code>, but you can do <code>"hello" * 5</code> and get "hellohellohellohellohello".</p>
  1362. <p><code>while,if,else,break</code> are keywords, kind of like <code>&lt;html&gt;</code> and <code>&lt;body&gt;</code>, <code>&lt;h1&gt;</code> etc, those are coming from python itself. There are not many python keywords, for reference, this is the <strong>complete</strong> list:</p>
  1363. <p>```
  1364. False
  1365. True
  1366. None</p>
  1367. <p>and -&gt; name == "pikachu" and age == "33"
  1368. or -&gt; name == "pikachu" or name == "charmander"
  1369. not -&gt; not name == "pikachu" is the same as name != "pikachu"</p>
  1370. <p>for -&gt; used if you know how many times you want to do something
  1371. while -&gt; do something until condition is True
  1372. break -&gt; break out of the for or while loop
  1373. continue -&gt; go to the start of the while/for loop and continue from there</p>
  1374. <p>if -&gt; if something is true
  1375. elif -&gt; else if something else is true
  1376. else -&gt; else do this</p>
  1377. <p>in -&gt; checks if something is in somethhing else, e.g. "pika" in name
  1378. def -&gt; make a function</p>
  1379. <p>as
  1380. assert
  1381. async
  1382. await
  1383. class
  1384. del
  1385. except
  1386. finally
  1387. from
  1388. global
  1389. import
  1390. is
  1391. lambda
  1392. nonlocal
  1393. pass
  1394. raise
  1395. return
  1396. try
  1397. with
  1398. yield
  1399. ```</p>
  1400. <p>THATS THE WHOLE LANGUAGE, there are no more keywords.</p>
  1401. <h2>[DAY-29] Print; If</h2>
  1402. <p>```
  1403. print("Welcome to the forest!")
  1404. print("This is a world of magic and wonders. You are on a cross road, you can go north east south or west.")
  1405. print("South leads to the swamps, where the aligators live")
  1406. print("West leads to the mountains, where the yeti lives")
  1407. print("North leads to the jungle, where the tigres live")
  1408. print("East leads to the desert, where the meerkats live")
  1409. print("")</p>
  1410. <p>what = input("what would you do next: ")</p>
  1411. <p>if what == "east":
  1412. print("Welcome to the desert")
  1413. print("It is very hot, and you need remember to put sun screen.")
  1414. print("Oh, you remember to put your hat as well.")
  1415. print("In the distance you see a meerkat approaching.")
  1416. print("What would you do? Run or Fight the meerkat?")
  1417. print("")</p>
  1418. <p>what = input("what would you do next: ")
  1419. if what == "run":
  1420. print("You start running, and the meerkat is super fast, it catches you in no time.")
  1421. elif what == "fight":
  1422. print("You try to fight it, but turns out it was friendly and wants to become your friend.")
  1423. print("What would you do?")
  1424. print("")
  1425. what = input("Do you want to be its friend: ")</p>
  1426. <pre><code>if what == "yes":
  1427. print("Great! Now the meerkat wants to introduce you to his family.")
  1428. elif what == "no":
  1429. print("The meerkat starts crying!")
  1430. </code></pre>
  1431. <p>else:
  1432. print("I dont understand: " + what)
  1433. ```</p>
  1434. <p>That is a lot of typing.</p>
  1435. <p>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 <code>print("The meerkat starts crying!")</code> is <code>elif what == "no":</code></p>
  1436. <p><code>|
  1437. |
  1438. if what == "east"
  1439. |
  1440. / | \
  1441. / | \
  1442. / | \
  1443. / | \
  1444. / | \
  1445. if else elif
  1446. what == "run" | what == "fight
  1447. | | |
  1448. print print / \
  1449. / \
  1450. / \
  1451. / \
  1452. if elif
  1453. what == "yes" what == "no"
  1454. | |
  1455. [ ... ] [ ... ]</code></p>
  1456. <p>Lets discuss another example:</p>
  1457. <p><code>a = "he"
  1458. b = "ll"
  1459. c = "o"
  1460. if a == "he":
  1461. if b == "ll":
  1462. if c == "o":
  1463. print("hello")</code></p>
  1464. <p>Can you tell who is the parent of who?</p>
  1465. <p>BTW, you can also use <code>and</code>, <code>or</code> and <code>not</code> when you want to see if something is <code>True</code></p>
  1466. <p><code>a = "he"
  1467. b = "ll"
  1468. c = "o"
  1469. if a == "he" and b == "ll" and c == "o":
  1470. print("hello")</code></p>
  1471. <h2>[DAY-30] Functions; Lists</h2>
  1472. <p>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.</p>
  1473. <p>```
  1474. def ask(possible_answers):
  1475. answer = ''
  1476. print("---") # print empty line
  1477. while True:
  1478. answer = input("&gt; What would you do next: ")
  1479. if answer not in possible_answers:
  1480. print("&gt; try again, it must be one of:", possible_answers)
  1481. else:
  1482. return answer</p>
  1483. <p>print("Welcome to the forest!")</p>
  1484. <h1>...</h1>
  1485. <p>what = ask(["east","west","north","south"])</p>
  1486. <p>if what == "east":
  1487. print("Welcome to the desert")
  1488. #...</p>
  1489. <p>what = ask(["run","fight"])
  1490. if what == "run":
  1491. print("You start running, and the meerkat is super fast, it catches you in no time.")
  1492. elif what == "fight":
  1493. print("You try to fight it, but turns out it was friendly and wants to become your friend.")
  1494. # ...
  1495. what = ask(["yes","no"])
  1496. if what == "yes":
  1497. print("Great! Now the meerkat wants to introduce you to his family.")
  1498. elif what == "no":
  1499. print("The meerkat starts crying!")
  1500. elif what == "north":
  1501. print("Welcome to the north pole, it is super cold here.")</p>
  1502. <p>```</p>
  1503. <p><code>ask</code> is a function, just like <code>print</code> or <code>input</code>, it will keep asking you <code>&gt; What would you do next:</code> 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 <code>zzz = ask(["yes","no"]</code> the value of <code>zzz</code> will be whatever is returned from <code>ask</code>. Same as <code>name = input("what is your name)</code> will put in <code>name</code> whatever is returned from <code>input</code> which is whatever you typed on your keyboard.</p>
  1504. <p>To make a function in python you need to use the <code>def</code> keyword.</p>
  1505. <p>```
  1506. def sum(a,b):
  1507. return a + b</p>
  1508. <p>r = sum(1737,1231231)
  1509. print(r)
  1510. ```</p>
  1511. <p>Whatever is between <code>def</code> and <code>(</code> is the name of the function, in the above example its <code>sum</code>. Between <code>()</code> 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 <code>a, b</code> and expect whoever calls my function to give me the numbers, like <code>r = sum(1737,1231231)</code></p>
  1512. <h2>[DAY-31] Functions; If; Random; Lists</h2>
  1513. <p>FIGHT TO THE DEATH!</p>
  1514. <p>```
  1515. import random
  1516. import time</p>
  1517. <p>def fight(playerHP, enemyHP, enemy_name):
  1518. # fight to the death!</p>
  1519. <p>while playerHP &gt;= 0 and enemyHP &gt;= 0:<br />
  1520. punch = random.randint(0, 20)
  1521. if random.choice(["player","enemy"]) == "player":
  1522. playerHP = playerHP - punch
  1523. print("&lt;"+enemy_name+"&gt; hits you for " + str(punch) + ", " + str(playerHP) + " left")
  1524. else:
  1525. enemyHP = enemyHP - punch
  1526. print("you hit &lt;"+enemy_name+"&gt; for " + str(punch) + ", " + str(enemyHP) + " left")</p>
  1527. <pre><code>time.sleep(1)
  1528. </code></pre>
  1529. <p>return playerHP</p>
  1530. <p>fight(100, 50, "meerkat")
  1531. ```</p>
  1532. <p><code>import</code> imports a module.</p>
  1533. <p><code>random</code> and <code>time</code> those are the <code>modules</code> you import, modules are just a group of functions that you can use, for example <code>time.sleep(1)</code> makes python sleep for 1 second, it calls the function <code>sleep()</code> in the <code>time</code> module. <code>random.choice()</code> you can give a list of things to choose from, and it will randomly select one of the list. <code>random.randint(0,20)</code> means give me a random number between 0 and 20.</p>
  1534. <p><code>str</code> 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 <code>str()</code> does that.</p>
  1535. <p>lets use it now in our dungeon game</p>
  1536. <p>```
  1537. import random
  1538. import time</p>
  1539. <p>def ask(possible_answers):
  1540. ...</p>
  1541. <p>def fight(playerHP, enemyHP, enemy_name):
  1542. ...</p>
  1543. <p>...</p>
  1544. <p>health = 100</p>
  1545. <p>what = ask(["east","west","north","south"])
  1546. if what == "east":
  1547. ...
  1548. what = ask(["run","fight"])
  1549. if what == "run":
  1550. ...
  1551. elif what == "fight":
  1552. meerkatHP = 50
  1553. health = fight(health, meerkatHP, "meerkat")
  1554. if health &lt;= 0:
  1555. print("GAME OVER! THE MEERKAT BEAT YOU")
  1556. else:
  1557. print("You won against the meerkat, you have " + str(health) + " HP left))
  1558. ```</p>
  1559. <h2>[DAY-32] Lists; While</h2>
  1560. <p>Today you have to make only two programs:</p>
  1561. <p>```
  1562. bad = ["broccoli","chocolate","pineapple"]</p>
  1563. <p>while True:
  1564. food = input("what is your favorite food: ")
  1565. if food in bad:
  1566. print("ewwwww I hate " + food)
  1567. else:
  1568. print("yumm, I love " + food)
  1569. ```</p>
  1570. <p>And the second one:</p>
  1571. <p><code>bad = ["broccoli","chocolate","pineapple"]
  1572. good = ["pizza","popcorn"]
  1573. while True:
  1574. food = input("what is your favorite food: ")
  1575. if food in bad:
  1576. print("ewwwww I hate " + food)
  1577. elif food in good:
  1578. print("yumm, I love " + food)
  1579. else:
  1580. print("I have never tried " + food)</code></p>
  1581. <p>Great job!</p>
  1582. <p>Spend the rest of the day touch typing.</p>
  1583. <h2>[DAY-33] For</h2>
  1584. <p><code>for</code> does something number of times, if I want to print the numbers from 0 to 99, I could do:
  1585. <code>for i range(100):
  1586. print(i)</code></p>
  1587. <p>or</p>
  1588. <p><code>for i in range(10, 20):
  1589. print(i)</code>
  1590. will print the numbers from 10 to 19</p>
  1591. <p><code>colors = ["red","green","blue"]
  1592. for color in colors:
  1593. print(color)</code></p>
  1594. <p>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:</p>
  1595. <p><code>name = "jack"
  1596. for c in name:
  1597. print(c)</code></p>
  1598. <p>prints:</p>
  1599. <p><code>j
  1600. a
  1601. c
  1602. k</code></p>
  1603. <h2>[DAY-34] Love Tester</h2>
  1604. <p>```
  1605. def love_test(a,b):
  1606. sum = 0
  1607. for c in a+b:
  1608. print(c + ': ' + str(ord(c)))
  1609. sum += ord(c)</p>
  1610. <p>print('sum is:' + str(sum))
  1611. return sum % 100</p>
  1612. <p>while True:
  1613. nameA = input("first name: ")
  1614. nameB = input("second name: ")</p>
  1615. <p>print("love test: " + str(love_test(nameA,nameB)))
  1616. ```</p>
  1617. <p><code>ord</code> takes the ascii code of a character.</p>
  1618. <p><code>%</code> is the remainder, so <code>109 % 100</code> is 9, basically what is left after you can cleanly divide two numbers, <code>812 % 100</code> is 12, you can fit 100 in 819 exactly 8 times, and then there is 12 left, this 12 is the remainder.</p>
  1619. <p>So in this program we take two names into the variables <code>nameA</code> and <code>nameB</code> and then we give them to the love_test function, which sums the ascii code of <code>nameA+nameB</code>, and then returns the remainder of 100.</p>
  1620. <p><code>first name: jack
  1621. second name: jane
  1622. j: 106
  1623. a: 97
  1624. c: 99
  1625. k: 107
  1626. j: 106
  1627. a: 97
  1628. n: 110
  1629. e: 101
  1630. sum is:823
  1631. love test: 23</code></p>
  1632. <p>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.</p>
  1633. <h2>[DAY-34] Touch Typing</h2>
  1634. <p>Whoaa it has been a difficult week.</p>
  1635. <p>Relax with some touch typing.</p>
  1636. <h2>[DAY-35] Lists; While; Continue</h2>
  1637. <p>This week there will be less talking and more programming.</p>
  1638. <p>Make a program to help you to decide what to do:</p>
  1639. <p>```
  1640. import random</p>
  1641. <p>possible = ["nothing"]
  1642. while True:
  1643. x = input("What would you like to do: ")
  1644. if x == "done":
  1645. break
  1646. else:
  1647. possible.append(x)</p>
  1648. <p>what = random.choice(possible)
  1649. print("possible choices: ")
  1650. print(possible)
  1651. print("the magic 8 ball decided: " + what)
  1652. ```</p>
  1653. <p>Make a program to help you multiply two numbers:</p>
  1654. <p><code>while True:
  1655. a = int(input("first number: "))
  1656. b = int(input("second number: "))
  1657. print(a, "*", b, "=", a*b)</code></p>
  1658. <p>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:</p>
  1659. <p>```
  1660. while True:
  1661. a = int(input("first number: "))
  1662. b = int(input("second number: "))
  1663. print(str(a) + " <em>" + str(b) + "=" + str(a</em>b))</p>
  1664. <p>```</p>
  1665. <p>What is your spy name?</p>
  1666. <p><code>name = input("what is your name: ")
  1667. print("Your spy name is: " + name[0] + name[1])</code></p>
  1668. <p>You can get individual characters from string by picking them up with <code>[]</code> so if name is 'jane' then <code>name[0]</code> is 'j'</p>
  1669. <p>Make a calculator
  1670. <code>while True:
  1671. a = int(input("first number: "))
  1672. b = int(input("second number: "))
  1673. op = input("operation * / + :")
  1674. result = 0
  1675. if op == "*":
  1676. result = a * b
  1677. elif op == "/":
  1678. result = a/b
  1679. elif op == "+":
  1680. result = a+b
  1681. else:
  1682. print("I dont understand " + op)
  1683. continue
  1684. print(a,op,b,'=',result)</code></p>
  1685. <p>See how we use <code>continue</code> to not print a result if we don't understand the operation. <code>continue</code> jumps to the beginning of the loop.</p>
  1686. <h2>[DAY-36] While; Range; Functions</h2>
  1687. <p>Print the numbers from 0 to 9 FOREVER</p>
  1688. <p><code>while True:
  1689. for i in range(10):
  1690. print(i)</code></p>
  1691. <p>Print each character of a string:</p>
  1692. <p><code>name = input("what is your name: ")
  1693. for c in name:
  1694. print(c)</code></p>
  1695. <p>Sum the numbers from 0 to 99</p>
  1696. <p>```
  1697. sum = 0</p>
  1698. <p>for i in range(100):
  1699. sum = sum + i
  1700. print(sum)</p>
  1701. <p>```</p>
  1702. <p>Print all the prime numbers from 0 to 100:</p>
  1703. <p>```
  1704. def is_prime(n):
  1705. if n == 1 or n == 0:
  1706. return False</p>
  1707. <p>for i in range(2, n):
  1708. if n % i == 0:
  1709. return False</p>
  1710. <p>return True</p>
  1711. <p>for i in range(100):
  1712. print(i, is_prime(i))
  1713. ```</p>
  1714. <p>multiply two numbers:</p>
  1715. <p>```
  1716. a = int(input("number 1: "))
  1717. b = int(input("number 2: "))
  1718. c = a * b</p>
  1719. <p>print(c)
  1720. ```</p>
  1721. <p>Timer:</p>
  1722. <p>```
  1723. import time</p>
  1724. <p>s = int(input("how many seconds: "))
  1725. for i in range(s):
  1726. print(i)
  1727. time.sleep(1)</p>
  1728. <p>print(s, "SECONDS ARE OVER")
  1729. ```</p>
  1730. <h2>[DAY-37] While; Functions</h2>
  1731. <p>Clock </p>
  1732. <p>```
  1733. import datetime
  1734. import time
  1735. import os</p>
  1736. <p>while True:
  1737. os.system('clear')
  1738. now = datetime.datetime.now()
  1739. print(now)
  1740. time.sleep(1)</p>
  1741. <p>```</p>
  1742. <p>Calendar</p>
  1743. <p>```
  1744. def show(calendar):
  1745. for row in calendar:
  1746. for day in row:
  1747. print(day,end=' ')
  1748. print('')</p>
  1749. <p>june = [
  1750. ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
  1751. [' ', ' ', ' 1', ' 2', ' 3', ' 4', ' 5'],
  1752. [' 6', ' 7', ' 8', ' 9', '10', '11', '12'],
  1753. ['13', '14', '15', '16', '17', '18', '19'],
  1754. ['20', '21', '22', '23', '24', '25', '26'],
  1755. ['27', '28', '29', '30', ' ', ' ', ' '],
  1756. ]</p>
  1757. <p>show(june)
  1758. ```</p>
  1759. <p>Growing list of food.</p>
  1760. <p>```
  1761. food = []</p>
  1762. <p>while True:
  1763. what = input("what is your favorite food: ")
  1764. food.append(what)
  1765. print(what)
  1766. ```</p>
  1767. <p>Guessing game</p>
  1768. <p><code>colors = ["red","green","blue"]
  1769. score = 0
  1770. while True:
  1771. guess = input("guess a color: ")
  1772. if guess in colors:
  1773. print("good guess! I like " + guess)
  1774. else:
  1775. print("nop, I dont like " + guess)</code></p>
  1776. <p>Guess again</p>
  1777. <p>```
  1778. def is_in_list(list,what):
  1779. for element in list:
  1780. if element == what:
  1781. return True
  1782. return False</p>
  1783. <p>colors = ["red","green","blue"]
  1784. score = 0
  1785. while True:
  1786. guess = input("guess a color: ")
  1787. if is_in_list(colors, guess):
  1788. print("good guess! I like " + guess)
  1789. else:
  1790. print("nop, I dont like " + guess)
  1791. ```</p>
  1792. <h2>[DAY-38] Strings</h2>
  1793. <p>What was your name again?</p>
  1794. <p><code>for i in range(10):
  1795. name = input("what is your name: ")
  1796. print(i)
  1797. print(name)</code></p>
  1798. <p>First and last letter:</p>
  1799. <p><code>name = input("what is your name: ")
  1800. print("first letter: " + name[0])
  1801. print("last letter: " + name[len(name)-1])</code></p>
  1802. <p>to get the last letter we have to count however letters are in the whole name, so <code>len(name)</code> will return 4 for 'jane' and it counts from 1</p>
  1803. <p>```
  1804. len("jane"):</p>
  1805. <p>j a n e
  1806. 1 2 3 4</p>
  1807. <p>len("ja")</p>
  1808. <p>j a
  1809. 1 2</p>
  1810. <p>```</p>
  1811. <p>but when we are using <code>[0]</code> to get to specific character from a string or element from a list, it counts from 0, so</p>
  1812. <p>```
  1813. j a n e
  1814. 0 1 2 3</p>
  1815. <p>name = "jane"
  1816. name[0] is j
  1817. name[1] is a
  1818. name[2] is n
  1819. name[3] is e</p>
  1820. <p>len(name) is 4 (because len counts from 1)
  1821. so name[len(name) - 1], is name[4 - 1] or name[3] which is the last letter
  1822. ```</p>
  1823. <p>Make a Line</p>
  1824. <p>```
  1825. def line(width, symbol):
  1826. for x in range(width):
  1827. print(symbol,end='')</p>
  1828. <p>line(20, '#')
  1829. line(30, '*')
  1830. line(40, '_')
  1831. ```</p>
  1832. <p>Make a triangle</p>
  1833. <p>```
  1834. def line(width, symbol):
  1835. for x in range(width):
  1836. print(symbol,end='')</p>
  1837. <p>for i in range(100):
  1838. line(i,'*')
  1839. print('')
  1840. ```</p>
  1841. <p>Make a beam</p>
  1842. <p>```
  1843. def line(width, symbol):
  1844. for x in range(width):
  1845. print(symbol,end='')</p>
  1846. <p>for i in range(50):
  1847. line(i, ' ')
  1848. line(i, '*')
  1849. print('')
  1850. ```</p>
  1851. <p>Make a box</p>
  1852. <p>```
  1853. def line(width, symbol):
  1854. for x in range(width):
  1855. print(symbol,end='')</p>
  1856. <p>def box(width,height,symbol):
  1857. for y in range(height):
  1858. line(width,symbol)
  1859. print('')</p>
  1860. <p>box(16,20)
  1861. box(10,20,'#')
  1862. box(15,13,'*')
  1863. ```</p>
  1864. <h2>[DAY-39] Touch Typing</h2>
  1865. <p>Do some touch typing.</p>
  1866. <h2>[DAY-40] Functions; Strings; Range</h2>
  1867. <p>Make inverse beam</p>
  1868. <p>```
  1869. def line(width, symbol):
  1870. for x in range(width):
  1871. print(symbol,end='')</p>
  1872. <p>count = 50
  1873. for i in range(count):
  1874. line(count - i, ' ')
  1875. line(i, '*')
  1876. print('')
  1877. ```</p>
  1878. <p>Make a tree</p>
  1879. <p>```
  1880. def line(width, symbol):
  1881. for x in range(width):
  1882. print(symbol,end='')</p>
  1883. <p>count = 50
  1884. for i in range(count):
  1885. half = int((count-i)/2)
  1886. line(half , ' ')
  1887. line(i, '*')
  1888. print('')
  1889. ```</p>
  1890. <p>Inverse</p>
  1891. <p>```
  1892. def line(width, symbol):
  1893. for x in range(width):
  1894. print(symbol,end='')</p>
  1895. <p>count = 50
  1896. for i in range(count):
  1897. line(count-i, '*')
  1898. print('')
  1899. ```</p>
  1900. <p>Inverse tree</p>
  1901. <p>```
  1902. def line(width, symbol):
  1903. for x in range(width):
  1904. print(symbol,end='')</p>
  1905. <p>count = 50
  1906. for i in range(count):
  1907. half = int(i/2)
  1908. line(half , ' ')
  1909. line(count-i, '*')
  1910. print('')
  1911. ```</p>
  1912. <p>Art</p>
  1913. <p>```
  1914. def line(width, symbol):
  1915. for x in range(width):
  1916. print(symbol,end='')</p>
  1917. <p>while True:
  1918. count = 10
  1919. for i in range(count):
  1920. line(count-i, '*')
  1921. print('')</p>
  1922. <p>for i in range(count):
  1923. line(i, '#')
  1924. print('')
  1925. ```</p>
  1926. <p>Looks so pretty!</p>
  1927. <p>```</p>
  1928. <h1></h1>
  1929. <h2></h2>
  1930. <h3></h3>
  1931. <h4></h4>
  1932. <h5></h5>
  1933. <h6></h6>
  1934. <h6></h6>
  1935. <h6></h6>
  1936. <h6></h6>
  1937. <hr />
  1938. <hr />
  1939. <hr />
  1940. <hr />
  1941. <hr />
  1942. <hr />
  1943. <hr />
  1944. <hr />
  1945. <p>**
  1946. *</p>
  1947. <h1></h1>
  1948. <h2></h2>
  1949. <h3></h3>
  1950. <h4></h4>
  1951. <h5></h5>
  1952. <h6></h6>
  1953. <h6></h6>
  1954. <h6></h6>
  1955. <h6></h6>
  1956. <hr />
  1957. <hr />
  1958. <hr />
  1959. <hr />
  1960. <hr />
  1961. <hr />
  1962. <hr />
  1963. <hr />
  1964. <p>**
  1965. *</p>
  1966. <p>```</p>
  1967. <h2>[DAY-41] Basics of Basics</h2>
  1968. <p>More Art</p>
  1969. <p>```
  1970. import random</p>
  1971. <p>def line(width, symbol):
  1972. for x in range(width):
  1973. print(symbol,end='')</p>
  1974. <p>symbols = ['*','#','%','^','&amp;']
  1975. while True:
  1976. count = random.randint(5,80)</p>
  1977. <p>symbol = random.choice(symbols)
  1978. for i in range(count):
  1979. line(count-i, symbol)
  1980. print('')</p>
  1981. <p>symbol = random.choice(symbols)
  1982. for i in range(count):
  1983. line(i, symbol)
  1984. print('')
  1985. ```</p>
  1986. <p>Staircase</p>
  1987. <p>```
  1988. def line(width, symbol):
  1989. for x in range(width):
  1990. print(symbol,end='')</p>
  1991. <p>count = 100
  1992. for i in range(0, count, 5):
  1993. line(i, '*')
  1994. print('')</p>
  1995. <p>```</p>
  1996. <p>Range is so cool, and you didnt even notice!</p>
  1997. <p>Try this:
  1998. <code>for i in range(0, 100, 10):
  1999. print(i)</code></p>
  2000. <p>it will print
  2001. <code>0
  2002. 10
  2003. 20
  2004. 30
  2005. 40
  2006. 50
  2007. 60
  2008. 70
  2009. 80
  2010. 90</code></p>
  2011. <p>so every 10th number, now try:</p>
  2012. <p><code>for i in range(0, 100, 5):
  2013. print(i)</code></p>
  2014. <p>and</p>
  2015. <p><code>for i in range(0, 100, 2):
  2016. print(i)</code></p>
  2017. <p>Of course you dont have to start counting from 0:</p>
  2018. <p><code>for i in range(50, 100, 2):
  2019. print(i)</code></p>
  2020. <p>Do some touch typing if there is time left.</p>
  2021. <h2>[DAY-41] Lists; If; While</h2>
  2022. <p>```
  2023. import random</p>
  2024. <p>words = ["pizza","pikachu","ball","pokemon"]</p>
  2025. <p>while True:
  2026. word = random.choice(words)
  2027. guessed = []
  2028. life = 10
  2029. while True:</p>
  2030. <pre><code>print('*' * 10, ' HANGMAN ', '*' * 10)
  2031. matching = 0
  2032. for c in word:
  2033. if c in guessed:
  2034. print(c,end='')
  2035. matching = matching + 1
  2036. else:
  2037. print('-',end='')
  2038. print('')
  2039. print('*' * 31)
  2040. if matching == len(word):
  2041. print('congratz you won!')
  2042. break
  2043. character = input("guess a character: ")
  2044. if character in word:
  2045. guessed.append(character)
  2046. else:
  2047. print(character + " is not in the word, " + str(life) + ' lives left')
  2048. life = life - 1
  2049. if life == 0:
  2050. print('you lost!')
  2051. break
  2052. </code></pre>
  2053. <p>```</p>
  2054. <h2>[DAY-42] Lists; Functions; Grid; While</h2>
  2055. <p>World without a player</p>
  2056. <p>```
  2057. def render(world):
  2058. for row in world:
  2059. for col in row:
  2060. print(col,end=' ')
  2061. print('')</p>
  2062. <p>def empty():
  2063. return [
  2064. ['-','-','-','-'],
  2065. ['-','-','-','-'],
  2066. ['-','-','-','-'],
  2067. ['-','-','-','-'],
  2068. ['-','-','-','-'],
  2069. ['-','-','-','-'],
  2070. ['-','-','-','-'],
  2071. ]</p>
  2072. <p>world = empty()</p>
  2073. <p>render(world)
  2074. while True:
  2075. row = int(input("which row (count from 0): "))
  2076. col = int(input("which column (count from 0): "))</p>
  2077. <p>world[row][col] = 'x'
  2078. render(world)</p>
  2079. <p>```</p>
  2080. <p>World with a player</p>
  2081. <p>```
  2082. def render(world):
  2083. for row in world:
  2084. for col in row:
  2085. print(col,end=' ')
  2086. print('')</p>
  2087. <p>def empty():
  2088. return [
  2089. ['-','-','-','-'],
  2090. ['-','-','-','-'],
  2091. ['-','-','-','-'],
  2092. ['-','-','-','-'],
  2093. ['-','-','-','-'],
  2094. ['-','-','-','-'],
  2095. ['-','-','-','-'],
  2096. ]</p>
  2097. <p>world = empty()
  2098. player_row = 0
  2099. player_col = 0
  2100. world[player_row][player_col] = 'x'</p>
  2101. <p>render(world)
  2102. while True:
  2103. direction = input("which direction: ")</p>
  2104. <p>world[player_row][player_col] = '*'
  2105. if direction == "up":
  2106. player_row = player_row - 1
  2107. elif direction == "down":
  2108. player_row = player_row + 1
  2109. elif direction == "left":
  2110. player_col = player_col - 1
  2111. elif direction == "right":
  2112. player_col = player_col + 1</p>
  2113. <p>world[player_row][player_col] = 'x'
  2114. render(world)</p>
  2115. <p>```</p>
  2116. <h2>[DAY-43] If; Range</h2>
  2117. <p>Even and Odd</p>
  2118. <p><code>number = int(input("give me a number: "))
  2119. if number % 2 == 0:
  2120. print("this number is even")
  2121. else:
  2122. print("this number is odd")</code></p>
  2123. <p>Fizz Buzz</p>
  2124. <p>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.</p>
  2125. <p>```
  2126. n = 100</p>
  2127. <p>for i in range(1,n+1):
  2128. if i % 5 == 0 and i % 3 == 0:
  2129. print("fizz buzz")
  2130. elif i % 3 == 0:
  2131. print("fizz")
  2132. elif i % 5 == 0:
  2133. print("buzz")
  2134. else:
  2135. print(i)
  2136. ```</p>
  2137. <p>or different version</p>
  2138. <p>```
  2139. n = 100
  2140. for i in range(1,n+1):
  2141. fizzbuzzing = False
  2142. if i % 3 == 0:
  2143. fizzbuzzing = True
  2144. print("fizz", end = '')</p>
  2145. <p>if i % 5 == 0:
  2146. fizzbuzzing = True
  2147. print("buzz", end = '')</p>
  2148. <p>if not fizzbuzzing:
  2149. print(i, end = '')</p>
  2150. <p>print('')
  2151. ```</p>
  2152. <p>There are many ways to write this, lets just have fun.</p>
  2153. <p>```
  2154. n = 100
  2155. numbers = []</p>
  2156. <h1>first make empty list with 100 elements</h1>
  2157. <p>for i in range(1, n+1):
  2158. numbers.append('')</p>
  2159. <h1>then fill in the fizzes</h1>
  2160. <p>for i in range(1, n+1):
  2161. if i % 3 == 0:
  2162. numbers[i-1] += 'fizz'</p>
  2163. <h1>then fill in the buzzess</h1>
  2164. <p>for i in range(1, n+1):
  2165. if i % 5 == 0:
  2166. numbers[i-1] += 'buzz'</p>
  2167. <h1>then fill in the numbers</h1>
  2168. <p>for i in range(1, n+1):
  2169. if numbers[i-1] == '':
  2170. numbers[i-1] = i</p>
  2171. <h1>then we print it</h1>
  2172. <p>for x in numbers:
  2173. print(x)
  2174. ```</p>
  2175. <p>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 <code>+=</code>, so it automatically works to put fizzbuzz for 15.</p>
  2176. <h2>[DAY-44] Lists</h2>
  2177. <p>Reviews</p>
  2178. <p>```
  2179. reviews =[5,3,2,4,1,2,3,4,2,1,5,5,3,2]</p>
  2180. <p>sum = 0
  2181. for r in reviews:
  2182. sum += r</p>
  2183. <p>rating = sum / len(reviews)
  2184. print(str(rating) + "⭐ out ot 5")
  2185. ```</p>
  2186. <p>Icecream Maker</p>
  2187. <p>```
  2188. import random
  2189. flavors = ['vanilla','chocolate','blue','banana','bluberry']</p>
  2190. <p>flavorA = random.choice(flavors)
  2191. flavorB = random.choice(flavors)</p>
  2192. <p>print(flavorA + " + " + flavorB)
  2193. ```</p>
  2194. <p>Spend the rest of the day touch typing.</p>
  2195. <h2>[DAY-45] Lists; Functions</h2>
  2196. <p>Different touch typing</p>
  2197. <p>```
  2198. import random
  2199. vowels = ['a', 'e', 'i', 'o', 'u', 'y']
  2200. consonants = ['b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','z']</p>
  2201. <p>def make_word(n_chars):
  2202. word = ''</p>
  2203. <p>for i in range(n_chars):
  2204. if random.randint(1,100) &lt; 40:
  2205. word += random.choice(vowels)
  2206. else:
  2207. word += random.choice(consonants)
  2208. return word</p>
  2209. <p>def make_sentence(n_words):
  2210. sentence = ''
  2211. for i in range(n_words):
  2212. sentence += make_word(random.randint(3,6))
  2213. sentence += ' '</p>
  2214. <p># this will remove the last element from the sentence string
  2215. # so we dont have empty space in the end
  2216. return sentence[:-1]</p>
  2217. <p>while True:
  2218. sentence = make_sentence(random.randint(10,20))
  2219. print(sentence)
  2220. guess = input('write the sentence: ')
  2221. if guess != sentence:
  2222. print("SORRY")
  2223. else:
  2224. print("GOOD JOB")
  2225. ```</p>
  2226. <p>spend the rest of the day trying it out</p>
  2227. <h2>[DAY-46] Basic Turtle</h2>
  2228. <p>Some turtle!</p>
  2229. <p><code>import turtle
  2230. turtle.circle(30)</code></p>
  2231. <p>Many circles</p>
  2232. <p><code>import turtle
  2233. for i in range(30):
  2234. turtle.circle(i)</code></p>
  2235. <p>Bigger circles</p>
  2236. <p>```
  2237. import turtle</p>
  2238. <p>turtle.color("blue")
  2239. for i in range(30):
  2240. turtle.circle(50 + i)
  2241. ```</p>
  2242. <p>Smile</p>
  2243. <p>```
  2244. import turtle</p>
  2245. <p>turtle.color("blue")
  2246. turtle.circle(100)
  2247. turtle.penup()
  2248. turtle.goto(60,120)
  2249. turtle.pendown()
  2250. turtle.circle(20)
  2251. turtle.penup()
  2252. turtle.goto(20,120)
  2253. turtle.pendown()
  2254. turtle.circle(20)
  2255. turtle.penup()
  2256. turtle.goto(-30,20)
  2257. turtle.pendown()
  2258. turtle.right(45)
  2259. turtle.circle(20, 120)
  2260. ```</p>
  2261. <h2>[DAY-47] Range; While</h2>
  2262. <p>Try to make a program that prints a symbol N times, where N is coming from the user input.</p>
  2263. <p>Try by yourself.</p>
  2264. <h2>[DAY-48] Strings; Functions</h2>
  2265. <p>How big can a string be?</p>
  2266. <p>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?</p>
  2267. <p>NB: before you try that, save all your files because you might have to restart your computer, depending on the operation system version.</p>
  2268. <p><code>try_me = 'x' * (8 * 1024 * 1024 * 1024)
  2269. print(len(try_me))</code></p>
  2270. <p>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.</p>
  2271. <p>lets try another thing</p>
  2272. <p>```
  2273. def forever(n):
  2274. print(n)
  2275. forever(n+1)</p>
  2276. <p>forever(1)
  2277. ```</p>
  2278. <p>this will throw a weird error</p>
  2279. <p><code>RecursionError: maximum recursion depth exceeded while pickling an object</code></p>
  2280. <p>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:</p>
  2281. <p><code>forever(1)
  2282. forever(1+1)
  2283. forever(1+1+1)
  2284. forever(....)</code></p>
  2285. <p>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.</p>
  2286. <p>Play with it a bit.</p>
  2287. <p>```
  2288. def one(n):
  2289. print("one", n)
  2290. two(n+1)</p>
  2291. <p>def two(n):
  2292. print("two", n)
  2293. one(n+1)</p>
  2294. <p>one(1)</p>
  2295. <p>```</p>
  2296. <h2>[DAY-49] List; Dictionaries</h2>
  2297. <p>```
  2298. import random
  2299. game = [
  2300. ['What is the capital of France?','Paris','London','Paris','Berlin','Tokyo'],
  2301. ['What is the capital of Japan?','Tokyo','London','Paris','Berlin','Tokyo'],
  2302. ["What is Jane's favorite food?",'Popcorn','Pizza','Popcorn','Cucumber','Sushi']
  2303. ]</p>
  2304. <p>while True:
  2305. quiz = random.choice(game)
  2306. print(quiz[0])
  2307. for index, possible in enumerate(quiz):
  2308. if index &gt;= 2:
  2309. print(possible)
  2310. answer = input('What is your answer: ')</p>
  2311. <pre><code>if answer == quiz[1]:
  2312. print("✨✨✨ CORRECT ✨✨✨")
  2313. else:
  2314. print("INCORRECT")
  2315. </code></pre>
  2316. <p>```</p>
  2317. <p>see <code>enumerate</code> is quite handy, you get the index of something and its value while you are doing the <code>for</code></p>
  2318. <p><code>x = ['a','b','c','d']
  2319. for index ,element in enumerate(x):
  2320. print(index)
  2321. print(' ' + element)</code></p>
  2322. <p>make it easier to read:</p>
  2323. <p>```
  2324. import random
  2325. QUESTION_IDX = 0
  2326. ANSWER_IDX = 1
  2327. game = [
  2328. ['What is the capital of France?','Paris','London','Paris','Berlin','Tokyo'],
  2329. ['What is the capital of Japan?','Tokyo','London','Paris','Berlin','Tokyo'],
  2330. ["What is Jane's favorite food?",'Popcorn','Pizza','Popcorn','Cucumber','Sushi']
  2331. ]</p>
  2332. <p>while True:
  2333. quiz = random.choice(game)
  2334. print(quiz[QUESTION_IDX])</p>
  2335. <pre><code>for index, possible in enumerate(quiz):
  2336. if index &gt;= ANSWER_IDX+1:
  2337. print(possible)
  2338. answer = input('What is your answer: ')
  2339. if answer == quiz[ANSWER_IDX]:
  2340. print("✨✨✨ CORRECT ✨✨✨")
  2341. else:
  2342. print("INCORRECT")
  2343. </code></pre>
  2344. <p>```</p>
  2345. <p>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:</p>
  2346. <p>```
  2347. import random
  2348. game = [
  2349. {
  2350. "question": "What is the capital of France?",
  2351. "answer": "Paris",
  2352. "possible": ['London','Paris','Berlin','Tokyo'],
  2353. },
  2354. {
  2355. "question": "What is the capital of Japan?",
  2356. "answer": "Tokyo",
  2357. "possible": ['London','Paris','Berlin','Tokyo'],
  2358. },<br />
  2359. ]</p>
  2360. <p>while True:
  2361. quiz = random.choice(game)
  2362. print(quiz["question"])
  2363. for p in quiz["possible"]:
  2364. print(' --&gt; ' + p)
  2365. answer = input('What is your answer: ')</p>
  2366. <pre><code>if answer == quiz["answer"]:
  2367. print("✨✨✨ CORRECT ✨✨✨")
  2368. else:
  2369. print("INCORRECT")
  2370. </code></pre>
  2371. <p>```</p>
  2372. <p>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 </p>
  2373. <h2>[DAY-50] Lists; If</h2>
  2374. <p>Print the odd numbers from 0 to 999</p>
  2375. <p><code>for i in range(1000):
  2376. if i % 2 != 0:
  2377. print(i)</code></p>
  2378. <p>rock paper scissors</p>
  2379. <p>```
  2380. import random
  2381. game = ["rock","paper","scissors"]</p>
  2382. <p>rounds = 3</p>
  2383. <p>nameA = input("name player A: ")
  2384. nameB = input("name player B: ")
  2385. winsA = 0
  2386. winsB = 0
  2387. for i in range(rounds):
  2388. playerA = random.choice(game)
  2389. playerB = random.choice(game)
  2390. print("ROUND: " + str(i + 1))
  2391. print("playerA : " + playerA)
  2392. print("playerB : " + playerB)</p>
  2393. <pre><code>if playerA == playerB:
  2394. print(" &gt; DRAW")
  2395. elif playerA == "rock" and playerB == "paper":
  2396. print(" &gt; " + nameB + " WINS")
  2397. winsB += 1
  2398. elif playerA == "rock" and playerB == "scissors":
  2399. print(" &gt; " + nameA + " WINS")
  2400. winsA += 1
  2401. elif playerA == "paper" and playerB == "rock":
  2402. print(" &gt; " + nameA + " WINS")
  2403. winsA += 1
  2404. elif playerA == "paper" and playerB == "scissors":
  2405. print(" &gt; " + nameB + " WINS")
  2406. winsB += 1
  2407. elif playerA == "scissors" and playerB == "rock":
  2408. print(" &gt; " + nameB + " WINS")
  2409. winsB += 1
  2410. elif playerA == "scissors" and playerB == "paper":
  2411. print(" &gt; " + nameA + " WINS")
  2412. winsA += 1
  2413. else:
  2414. print("WTF " + playerA + " " + playerB)
  2415. print("---")
  2416. </code></pre>
  2417. <p>print(nameA + " has " + str(winsA) + " points")
  2418. print(nameB + " has " + str(winsB) + " points")
  2419. if winsA &gt; winsB:
  2420. print(nameA + " IS THE WINNER")
  2421. elif winsA &lt; winsB:
  2422. print(nameB + " IS THE WINNER")
  2423. else:
  2424. # this will show only if we have even number of rounds
  2425. print("THERE IS NO WINNER")
  2426. ```</p>
  2427. <h2>[DAY-51] Internet Awareness - Scams/Viruses</h2>
  2428. <p>Today is an important day, its Internet awareness day.</p>
  2429. <p>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.</p>
  2430. <p>After you are done reload the page to see it is not actually changed.</p>
  2431. <p>Now do that on roblox, make it look like you have 999999 robux.</p>
  2432. <p>Go to google and search for <code>Speed up your internet connection</code>, 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.</p>
  2433. <p>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.</p>
  2434. <p>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 </p>
  2435. <p>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.</p>
  2436. <h2>[DAY-52] Internet Awareness - How Login Works</h2>
  2437. <p>Ok now for something more serious!</p>
  2438. <p>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.</p>
  2439. <p>So imagine websites have a table like so:</p>
  2440. <p>|username|password|
  2441. |-|-|
  2442. |jane|123456|
  2443. |john|blabla|</p>
  2444. <p>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.</p>
  2445. <p>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 <em>always</em> the same castle will spit out the same 8 pieces.</p>
  2446. <p>So in reality the excel sheet looks a bit like this:</p>
  2447. <p>|username|encrypted password|salt|
  2448. |-|-|-|
  2449. |jane|4c87d9b2ecfbd99c483aedfae8045fe578912e63|someRandom123|
  2450. |john|065ce4538c7c51687270972babdeaa986f3ce1bd|someRandom435|</p>
  2451. <p>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:</p>
  2452. <p>|username|token|
  2453. |-|-|
  2454. |jane|bbd0bff806a177f082f3ba2cff33030d335c296e|</p>
  2455. <p>then tell your browser, hey set this cookies:</p>
  2456. <p><code>the username for amazon.com is 'jane'
  2457. the token is bbd0bff806a177f082f3ba2cff33030d335c296e</code></p>
  2458. <p>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.</p>
  2459. <p>Now lets see how someone can login as you without knowing your password.</p>
  2460. <p>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:</p>
  2461. <p><code>var cookies = []
  2462. for (cookie of document.cookie.split(";")) {
  2463. cookies.push(cookie.replace(" ", ""))
  2464. }
  2465. console.log(JSON.stringify(cookies))</code>
  2466. This will print all the cookies amazon has set on your browser in a list.</p>
  2467. <p>Copy the whole list of cookies, now on the private mode browser's console(press F12 to open the console) type:</p>
  2468. <p><code>var newCookies = ["session-id....." .. .. ] // just paste the whole string from the other browser
  2469. for (cookie of newCookies) {
  2470. document.cookie = cookie;
  2471. }</code></p>
  2472. <p>Paste the whole list there, and refresh the page.</p>
  2473. <p>And voila! You are logged in now without typing a password. </p>
  2474. <p>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 <code>base64 encoded</code> that looks like this:</p>
  2475. <p><code>d = atob('dmFyIGNvb2tpZXMgPSBbXQpmb3IgKGNvb2tpZSBvZiBkb2N1bWVudC5jb29raWUuc3BsaXQoIjsiKSkgewogICAgY29va2llcy5wdXNoKGNvb2tpZS5yZXBsYWNlKCIgIiwgIiIpKQp9CmNvbnNvbGUubG9nKGNvb2tpZXMpCg==')
  2476. console.log(d)
  2477. eval(d)</code></p>
  2478. <p>You see how it printed your cookies? The thing that runs the code is <code>eval</code> 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 <code>console.log(atob('....'))</code> this will just decode the base64 encoding into a string you can read. <code>atob</code> decodes base64 string into the real string, it is kind of like in python <code>ord('a')</code> gives you 97 and <code>chr(97)</code> gives you 'a'.</p>
  2479. <p>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.</p>
  2480. <p>That is why if you open facebook.com and press F12 you will see giant message:</p>
  2481. <p>```
  2482. STOP STOP STOP</p>
  2483. <p>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.
  2484. ```</p>
  2485. <p>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.</p>
  2486. <h2>[DAY-53] Basics of the Internet - IP/DNS</h2>
  2487. <p>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.</p>
  2488. <p>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.</p>
  2489. <p>```
  2490. ROOT
  2491. "."
  2492. / | \
  2493. / | \
  2494. .de .com .io
  2495. / |
  2496. amazon /|\
  2497. / | \
  2498. / | \
  2499. / | \
  2500. / | \
  2501. amazon netflix yahoo</p>
  2502. <p>```</p>
  2503. <p>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.</p>
  2504. <p>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.</p>
  2505. <p>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).</p>
  2506. <p>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.</p>
  2507. <h2>[DAY-54] Touch Typing</h2>
  2508. <p>Touch typing day is finally here! Enjoy keybr.com!</p>
  2509. <h2>[DAY-55] Lists; Functions</h2>
  2510. <p>Tic Tac Toe</p>
  2511. <p>```
  2512. def empty_game():
  2513. game = [
  2514. [' ','a','b','c','d'],
  2515. ['1','-','-','-','-'],
  2516. ['2','-','-','-','-'],
  2517. ['3','-','-','-','-'],
  2518. ['4','-','-','-','-']
  2519. ]
  2520. return game</p>
  2521. <p>def show_game(game):
  2522. for row in game:
  2523. #[' ','a','b','c','d']
  2524. #...
  2525. for col in row:
  2526. #' '
  2527. #'a'
  2528. #'b'
  2529. print (col, end=' ')
  2530. print('')</p>
  2531. <p>g = empty_game()
  2532. x_or_zero='x'
  2533. while True:
  2534. show_game(g)
  2535. p = input('place ' + x_or_zero + ': ')</p>
  2536. <pre><code>if p == 'a1':
  2537. g[1][1]=x_or_zero
  2538. if p == 'a2':
  2539. g[2][1]=x_or_zero
  2540. if p == 'a3':
  2541. g[3][1]=x_or_zero
  2542. if p == 'a4':
  2543. g[4][1]=x_or_zero
  2544. if p == 'b1':
  2545. g[1][2]=x_or_zero
  2546. if p == 'b2':
  2547. g[2][2]=x_or_zero
  2548. if p == 'b3':
  2549. g[3][2]=x_or_zero
  2550. if p == 'b4':
  2551. g[4][2]=x_or_zero
  2552. if p == 'c1':
  2553. g[1][3]=x_or_zero
  2554. if p == 'c2':
  2555. g[2][3]=x_or_zero
  2556. if p == 'c3':
  2557. g[3][3]=x_or_zero
  2558. if p == 'c4':
  2559. g[4][3]=x_or_zero
  2560. if p == 'd1':
  2561. g[1][4]=x_or_zero
  2562. if p == 'd2':
  2563. g[2][4]=x_or_zero
  2564. if p == 'd3':
  2565. g[3][4]=x_or_zero
  2566. if p == 'd4':
  2567. g[4][4]=x_or_zero
  2568. if p == 'clear':
  2569. g = empty_game()
  2570. if x_or_zero =='x':
  2571. x_or_zero = '0'
  2572. else:
  2573. x_or_zero='x'
  2574. </code></pre>
  2575. <p>```</p>
  2576. <p>Spend the rest of the day playing.</p>
  2577. <h2>[DAY-56] Functions; If; Random</h2>
  2578. <p>Trivia game</p>
  2579. <p>```
  2580. def check(question, answer):
  2581. x = input(question + ": ")
  2582. if x == answer:
  2583. return True
  2584. else:
  2585. return False</p>
  2586. <p>score = 0
  2587. if check("which animal lives on the north pole?", "polar bear"):
  2588. score += 1
  2589. if check("which animal lives in the jungle?", "tiger"):
  2590. score += 1</p>
  2591. <p>print("your score is: " + str(score))
  2592. ```</p>
  2593. <p>Math test:</p>
  2594. <p>```
  2595. import random</p>
  2596. <p>while True:
  2597. a = random.randint(1,10)
  2598. b = random.randint(1,10)</p>
  2599. <pre><code>r = int(input("what is " + str(a) + " * " + str(b) + "? " ))
  2600. if r == a * b:
  2601. print("Correct!")
  2602. else:
  2603. print("Incorrect, the answer was: " + str(a * b))
  2604. </code></pre>
  2605. <p>```</p>
  2606. <p>Random characters</p>
  2607. <p>```
  2608. import random</p>
  2609. <p>while True:
  2610. x = random.randint(ord('a'), ord('z'))
  2611. print(chr(x))
  2612. ```</p>
  2613. <h2>[DAY-57] Lists; Functions; Grid</h2>
  2614. <p>Snake</p>
  2615. <p>```
  2616. import random
  2617. APPLE_SYMBOL = '@'</p>
  2618. <p>def render(world):
  2619. for row in world:
  2620. for col in row:
  2621. print(col,end=' ')
  2622. print('')</p>
  2623. <p>def empty():
  2624. return [
  2625. ['-','-','-','-'],
  2626. ['-','-','-','-'],
  2627. ['-','-','-','-'],
  2628. ['-','-','-','-'],
  2629. ['-','-','-','-'],
  2630. ['-','-','-','-'],
  2631. ['-','-','-','-'],
  2632. ]</p>
  2633. <p>def snake_eats_itself(positions, current_col, current_row):
  2634. for (col,row) in positions:
  2635. if col == current_col and row == current_row:
  2636. return True</p>
  2637. <p>def place_apple(world):
  2638. # just place it on a random square from all possible squares
  2639. possible = []
  2640. for index_row in range(len(world)):
  2641. for index_col in range(len(world[index_row])):
  2642. if world[index_row][index_col] == '-':
  2643. possible.append((index_col,index_row))</p>
  2644. <pre><code>if len(possible) == 0:
  2645. # we cant place an apple
  2646. return False
  2647. else:
  2648. (col,row) = random.choice(possible)
  2649. world[row][col] = APPLE_SYMBOL
  2650. return True
  2651. </code></pre>
  2652. <p>world = empty()
  2653. player_row = 0
  2654. player_col = 0
  2655. player_history = []</p>
  2656. <p>world[player_row][player_col] = '%'
  2657. player_history.append((player_col,player_row))</p>
  2658. <p>place_apple(world)
  2659. render(world)</p>
  2660. <p>while True:
  2661. direction = input("which direction: ")</p>
  2662. <p>world[player_row][player_col] = '='
  2663. if direction == "u":
  2664. player_row = player_row - 1
  2665. elif direction == "d":
  2666. player_row = player_row + 1
  2667. elif direction == "l":
  2668. player_col = player_col - 1
  2669. elif direction == "r":
  2670. player_col = player_col + 1
  2671. else:
  2672. print("try again, u for up/d for down/l for left/r for right")
  2673. continue
  2674. if snake_eats_itself(player_history, player_col, player_row):
  2675. print("GAME OVER")
  2676. break</p>
  2677. <p>if world[player_row][player_col] == APPLE_SYMBOL:</p>
  2678. <pre><code> world[player_row][player_col] = '$'
  2679. if not place_apple(world):
  2680. print("YOU WON!")
  2681. break
  2682. </code></pre>
  2683. <p>else:
  2684. world[player_row][player_col] = '%'</p>
  2685. <p>player_history.append((player_col,player_row))</p>
  2686. <p>render(world)</p>
  2687. <p>```</p>
  2688. <h2>[DAY-58] Continue Previous Day</h2>
  2689. <p>Keep working on the snake game if you are not done. if you are do touch typing</p>
  2690. <h2>[DAY-59] Tuples; Lists</h2>
  2691. <p>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</p>
  2692. <p>```
  2693. position = (1,2)</p>
  2694. <p>(x,y) = position
  2695. print(x)
  2696. print(y)
  2697. ```</p>
  2698. <p>it can have more elements</p>
  2699. <p>```
  2700. posittion = (1,2,3)
  2701. (width,depth,height) = position</p>
  2702. <p>print(width)
  2703. print(depth)
  2704. print(height)
  2705. ```</p>
  2706. <p>You see how we used it in the snake game, to make a list of tuples, where we had the player history.</p>
  2707. <p><code>positions = [(1,2),(3,4),(5,6)]
  2708. print(positions)
  2709. for p in positions:
  2710. print(p)
  2711. (x,y) = p
  2712. print(x)
  2713. print(y)</code></p>
  2714. <p>It is quite handy when you know you have pairs of data, like X and Y position or Season number and Episode number.</p>
  2715. <p>```
  2716. favorite_miraculous = [(3,1),(3,2),(2,1)]</p>
  2717. <p>for m in favorite_miraculous:
  2718. (season,episode) = m
  2719. print(str(season) + " season episode: " + str(episode))
  2720. ```</p>
  2721. <p>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</p>
  2722. <h2>[DAY-60] Go Back In Time</h2>
  2723. <p>Back to the beginning.</p>
  2724. <ul>
  2725. <li>Write a program to make a spy name</li>
  2726. <li>Write a program to ask for favorite food</li>
  2727. <li>Write a program to ask what is your name forever</li>
  2728. </ul>
  2729. <h2>[DAY-61] PyGame; PyGameZero; Coordinates</h2>
  2730. <p>open <code>cmd</code> and run:</p>
  2731. <p><code>pip install pygame
  2732. pip install pgzero</code></p>
  2733. <p>then make a circle</p>
  2734. <p>```
  2735. import pgzrun
  2736. WIDTH = 400
  2737. HEIGHT = 400</p>
  2738. <p>def draw():
  2739. screen.clear()
  2740. x = WIDTH/2
  2741. y = WIDTH/2
  2742. pos = (x,y)
  2743. radius = 30
  2744. screen.draw.circle(pos, radius, 'white')</p>
  2745. <p>pgzrun.go()
  2746. ```</p>
  2747. <p>Now lets move it:</p>
  2748. <p>```
  2749. import pgzrun
  2750. import random</p>
  2751. <p>WIDTH = 400
  2752. HEIGHT = 400</p>
  2753. <p>x = WIDTH/2
  2754. y = WIDTH/2</p>
  2755. <p>def on_mouse_down(pos):
  2756. global x,y
  2757. (mouse_x, mouse_y) = pos</p>
  2758. <pre><code>x = mouse_x
  2759. y = mouse_y
  2760. </code></pre>
  2761. <p>def draw():
  2762. screen.clear()
  2763. pos = (x,y)
  2764. radius = 30
  2765. screen.draw.circle(pos, radius, 'white')</p>
  2766. <p>pgzrun.go()
  2767. ```</p>
  2768. <p>Move it with keyboard</p>
  2769. <p>```
  2770. import pgzrun
  2771. import random</p>
  2772. <p>WIDTH = 400
  2773. HEIGHT = 400
  2774. STEP = 10
  2775. x = WIDTH/2
  2776. y = WIDTH/2</p>
  2777. <p>def on_key_down(key):
  2778. global x,y
  2779. if key == keys.LEFT:
  2780. x -= STEP
  2781. elif key == keys.RIGHT:
  2782. x += STEP
  2783. elif key == keys.UP:
  2784. # coordinates start 0,0 on the upper left corner
  2785. y -= STEP
  2786. elif key == keys.DOWN:
  2787. y += STEP</p>
  2788. <p>def draw():
  2789. screen.clear()
  2790. pos = (x,y)
  2791. radius = 30
  2792. screen.draw.circle(pos, radius, 'white')</p>
  2793. <p>pgzrun.go()
  2794. ```</p>
  2795. <p>Lets say we have 400 width and 300 height window</p>
  2796. <p><code>(0,0)
  2797. +---------------------------+
  2798. | |
  2799. | |
  2800. | |
  2801. | |
  2802. | |
  2803. | |
  2804. +---------------------------+
  2805. (400, 300)</code></p>
  2806. <p>top left corner is y = 0 and x = 0, bottom right is <code>x = 400</code> and <code>y = 300</code>. So when we move 'UP' with the keyboard we actually have to decrease <code>y</code> instead of increasing it like in <code>turtle</code>, where 0,0 is in the center of the screen, so top left is <code>(-half_x, -half_y)</code> and bottom right is <code>(half_x, half_y)</code></p>
  2807. <h2>[DAY-62] Collisions; Callbacks</h2>
  2808. <p>Smooth movement.</p>
  2809. <p>```
  2810. import pgzrun
  2811. import random</p>
  2812. <p>WIDTH = 400
  2813. HEIGHT = 400
  2814. STEP = 10
  2815. x = WIDTH/2
  2816. y = WIDTH/2</p>
  2817. <p>def update():
  2818. global x,y
  2819. if keyboard.LEFT:
  2820. x -= STEP
  2821. elif keyboard.RIGHT:
  2822. x += STEP
  2823. elif keyboard.UP:
  2824. y -= STEP
  2825. elif keyboard.DOWN:
  2826. y += STEP</p>
  2827. <p>def draw():
  2828. screen.clear()
  2829. pos = (x,y)
  2830. radius = 30
  2831. screen.draw.circle(pos, radius, 'white')</p>
  2832. <p>pgzrun.go()
  2833. ```</p>
  2834. <p><code>pgzero</code> will call your <code>update</code> function 60 times per second, and now it will just check at the time of the call, is <code>keyboard.UP</code>, and if it is it will just move. Which is completely different, where each time you press the <code>up</code> key the <code>on_key_down</code> function is called. So previously you had ot press the key every time to move, now you can just hold it.</p>
  2835. <p>Where do those <code>keyboard</code> and <code>screen</code> magic variables come from? In python there is such thing as <code>__builtin__</code> which literally adds new keywords, kind of like <code>input</code> or <code>print</code>, when you <code>import pgzrun</code> it will import also those builtins. <code>Actor</code>, <code>Rect</code>, <code>keyboard</code> etc.. you can check them at https://pygame-zero.readthedocs.io/en/stable/builtins.html</p>
  2836. <p>COLLIDE!</p>
  2837. <p><img alt="game-62.png" src="./screenshots/game-62.png" title="game 62 screenshot" /></p>
  2838. <p>```
  2839. import pgzrun
  2840. import random</p>
  2841. <p>WIDTH = 400
  2842. HEIGHT = 400
  2843. STEP = 10
  2844. x = WIDTH/2
  2845. y = WIDTH/2</p>
  2846. <p>box = Rect((20,20),(100,100))</p>
  2847. <p>game_over = False</p>
  2848. <p>def update():
  2849. global x, y, game_over
  2850. if keyboard.LEFT:
  2851. x -= STEP
  2852. elif keyboard.RIGHT:
  2853. x += STEP
  2854. elif keyboard.UP:
  2855. y -= STEP
  2856. elif keyboard.DOWN:
  2857. y += STEP</p>
  2858. <pre><code>if box.collidepoint((x,y)):
  2859. game_over = True
  2860. </code></pre>
  2861. <p>def draw():
  2862. screen.clear()
  2863. pos = (x,y)
  2864. radius = 30
  2865. screen.draw.rect(box, color="red")
  2866. screen.draw.circle(pos, radius, 'white')</p>
  2867. <pre><code>if game_over:
  2868. screen.draw.text("GAME OVER", (50, 30), color="blue")
  2869. </code></pre>
  2870. <p>pgzrun.go()</p>
  2871. <p>```</p>
  2872. <h2>[DAY-63] Functions</h2>
  2873. <p>Catch the snake</p>
  2874. <p><img alt="game-63.png" src="./screenshots/game-63.png" title="game 63 screenshot" /></p>
  2875. <p>Make images/ folder and download the images from https://github.com/jackdoe/programming-for-kids. When you say <code>Actor("c1")</code> it will look for <code>c1.png</code> in images/ folder in the current directory.</p>
  2876. <p>```
  2877. import pgzrun
  2878. import random</p>
  2879. <p>HEIGHT = 200
  2880. WIDTH = 200</p>
  2881. <p>score = 0
  2882. speed = 1
  2883. elf = Actor("c1")
  2884. snake = Actor("snake")
  2885. elf.x = WIDTH/2
  2886. elf.y = HEIGHT/2
  2887. def place_snake():
  2888. snake.x = random.randint(10,WIDTH-10)
  2889. snake.y = random.randint(10,HEIGHT-10)</p>
  2890. <p>place_snake()</p>
  2891. <p>def update():
  2892. global game_over, speed, score
  2893. if keyboard.left:
  2894. elf.x = elf.x-speed
  2895. if keyboard.right:
  2896. elf.x = elf.x+speed
  2897. if keyboard.up:
  2898. elf.y = elf.y-speed
  2899. if keyboard.down:
  2900. elf.y= elf.y+speed
  2901. if keyboard.R:
  2902. speed = 1
  2903. score = 0</p>
  2904. <pre><code>if elf.colliderect(snake):
  2905. score += 1
  2906. speed += 1
  2907. place_snake()
  2908. </code></pre>
  2909. <p>def draw():
  2910. screen.fill('black')
  2911. elf.draw()
  2912. snake.draw()</p>
  2913. <pre><code>screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  2914. </code></pre>
  2915. <p>pgzrun.go()</p>
  2916. <p>```</p>
  2917. <h2>[DAY-64] Lists; Functions</h2>
  2918. <p>Many Snakes</p>
  2919. <p><img alt="game-64.png" src="./screenshots/game-64.png" title="game 64 screenshot" /></p>
  2920. <p>```
  2921. import pgzrun
  2922. import random</p>
  2923. <p>HEIGHT = 200
  2924. WIDTH = 200</p>
  2925. <p>score = 1
  2926. speed = 1
  2927. elf = Actor("c1")
  2928. snakes = []
  2929. elf.x = WIDTH/2
  2930. elf.y = HEIGHT/2
  2931. def place_snakes():
  2932. global snakes
  2933. snakes = []
  2934. for i in range(score):
  2935. snake = Actor("snake")
  2936. snake.x = random.randint(10,WIDTH-10)
  2937. snake.y = random.randint(10,HEIGHT-10)
  2938. snakes.append(snake)</p>
  2939. <p>place_snakes()</p>
  2940. <p>def update():
  2941. global game_over, speed, score, snakes
  2942. if keyboard.left:
  2943. elf.x = elf.x-speed
  2944. if keyboard.right:
  2945. elf.x = elf.x+speed
  2946. if keyboard.up:
  2947. elf.y = elf.y-speed
  2948. if keyboard.down:
  2949. elf.y= elf.y+speed
  2950. if keyboard.R:
  2951. speed = 1
  2952. score = 0
  2953. snakes = []
  2954. place_snakes()
  2955. for s in snakes:
  2956. if elf.colliderect(s):
  2957. score += 1
  2958. speed += 1
  2959. place_snakes()</p>
  2960. <p>def draw():
  2961. screen.fill('black')
  2962. elf.draw()
  2963. for s in snakes:
  2964. s.draw()</p>
  2965. <pre><code>screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  2966. </code></pre>
  2967. <p>pgzrun.go()
  2968. ```</p>
  2969. <h2>[DAY-65] Functions; Collisions</h2>
  2970. <p>```
  2971. import pgzrun
  2972. import random</p>
  2973. <p>HEIGHT = 200
  2974. WIDTH = 200</p>
  2975. <p>score = 0
  2976. speed = 1
  2977. game_over = False
  2978. elf = Actor("c1")
  2979. snake = Actor("snake")
  2980. elf.x = WIDTH/2
  2981. elf.y = HEIGHT/2
  2982. def place_snake():
  2983. snake.x = random.randint(10,WIDTH-10)
  2984. snake.y = random.randint(10,HEIGHT-10)</p>
  2985. <p>place_snake()</p>
  2986. <p>def update():
  2987. global game_over, speed, score
  2988. if keyboard.left:
  2989. elf.x = elf.x-speed
  2990. if keyboard.right:
  2991. elf.x = elf.x+speed
  2992. if keyboard.up:
  2993. elf.y = elf.y-speed
  2994. if keyboard.down:
  2995. elf.y= elf.y+speed
  2996. if keyboard.R:
  2997. speed = 1
  2998. score = 0</p>
  2999. <pre><code>if elf.colliderect(snake):
  3000. score += 1
  3001. speed += 1
  3002. place_snake()
  3003. </code></pre>
  3004. <p>def draw():
  3005. screen.fill('black')
  3006. elf.draw()
  3007. snake.draw()</p>
  3008. <pre><code>screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3009. </code></pre>
  3010. <p>pgzrun.go()</p>
  3011. <p>```</p>
  3012. <h2>[DAY-66] Schedule; Callbacks; Functions</h2>
  3013. <p>Catch as many snakes as you can in 5 seconds.</p>
  3014. <p>```
  3015. import pgzrun
  3016. import random</p>
  3017. <p>HEIGHT = 200
  3018. WIDTH = 200</p>
  3019. <p>game_over = False
  3020. score = 0
  3021. speed = 1
  3022. elf = Actor("c1")
  3023. snake = Actor("snake")
  3024. elf.x = WIDTH/2
  3025. elf.y = HEIGHT/2
  3026. def place_snake():
  3027. snake.x = random.randint(10,WIDTH-10)
  3028. snake.y = random.randint(10,HEIGHT-10)</p>
  3029. <p>place_snake()</p>
  3030. <p>def time_is_up():
  3031. global game_over
  3032. game_over = True</p>
  3033. <p>def update():
  3034. global game_over, speed, score
  3035. if keyboard.left:
  3036. elf.x = elf.x-speed
  3037. if keyboard.right:
  3038. elf.x = elf.x+speed
  3039. if keyboard.up:
  3040. elf.y = elf.y-speed
  3041. if keyboard.down:
  3042. elf.y= elf.y+speed
  3043. if keyboard.R:
  3044. speed = 1
  3045. score = 0</p>
  3046. <pre><code>if elf.colliderect(snake):
  3047. score += 1
  3048. speed += 1
  3049. place_snake()
  3050. </code></pre>
  3051. <p>def draw():
  3052. screen.fill('black')
  3053. elf.draw()
  3054. snake.draw()</p>
  3055. <pre><code>screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3056. if game_over:
  3057. screen.fill('blue')
  3058. screen.draw.text("GAME OVER, Score: "+ str(score), color="white", topleft=(10,10))
  3059. </code></pre>
  3060. <p>clock.schedule(time_is_up, 5)
  3061. pgzrun.go()
  3062. ```</p>
  3063. <p>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.</p>
  3064. <p>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</p>
  3065. <p>Example:</p>
  3066. <p>```
  3067. def update():
  3068. ...
  3069. if keyboard.left:
  3070. elf.x = elf.x-speed
  3071. if elf.x &gt; WIDTH:
  3072. elf.x = WIDTH</p>
  3073. <p>```</p>
  3074. <h2>[DAY-67] Lists; Functions</h2>
  3075. <p>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</p>
  3076. <p>```
  3077. import pgzrun
  3078. import random</p>
  3079. <p>HEIGHT = 1000
  3080. WIDTH = 1200</p>
  3081. <p>score = 0
  3082. step = 5
  3083. coin_speed = 1
  3084. fox = Actor("fox")
  3085. gate = Actor("door")
  3086. gate.y = HEIGHT - 50
  3087. gate.x = WIDTH/2 - 20
  3088. cars=[
  3089. [Actor("car-2"),Actor("car-5"),Actor("car-3")],
  3090. [Actor("car-1"),Actor("car-5")],
  3091. [Actor("car-3"),Actor("car-4"),Actor("car-2")],
  3092. ]</p>
  3093. <p>for a in cars:
  3094. for (coin_index,f) in enumerate(a):
  3095. f.x += coin_index * int(WIDTH/len(a)) + 30
  3096. def move_coins():
  3097. for (index,a) in enumerate(cars):
  3098. for (coin_index, f) in enumerate(a):</p>
  3099. <pre><code> f.y = (index * int(HEIGHT/len(cars))) + int(HEIGHT/len(cars))/2
  3100. f.x += coin_speed
  3101. if f.x &gt; WIDTH:
  3102. f.x = 0
  3103. </code></pre>
  3104. <p>game_over = False
  3105. move_coins()</p>
  3106. <p>def update():
  3107. global score
  3108. global step
  3109. global game_over
  3110. global coin_speed
  3111. if keyboard.left:
  3112. fox.x = fox.x-step
  3113. if fox.x &lt;0:
  3114. fox.x=0
  3115. if keyboard.right:
  3116. fox.x = fox.x+step
  3117. if fox.x &gt;WIDTH:
  3118. fox.x=WIDTH
  3119. if keyboard.up:
  3120. fox.y =fox.y-step
  3121. if fox.y &lt;0:
  3122. fox.y=0
  3123. if keyboard.down:
  3124. fox.y= fox.y+step
  3125. if fox.y &gt;HEIGHT:
  3126. fox.y=HEIGHT
  3127. if keyboard.R:
  3128. game_over = False
  3129. score = 0
  3130. fox.x = 0
  3131. fox.y = 0
  3132. coin_speed = 1
  3133. for i in cars:
  3134. for s in i:
  3135. if fox.colliderect(s):
  3136. game_over = 1 == 1</p>
  3137. <pre><code>if fox.colliderect(gate):
  3138. fox.x = 0
  3139. fox.y = 0
  3140. score += 1
  3141. coin_speed += 2
  3142. move_coins()
  3143. </code></pre>
  3144. <p>def draw():
  3145. screen.fill('black')
  3146. fox.draw()
  3147. gate.draw()</p>
  3148. <pre><code>for i in cars:
  3149. for k in i:
  3150. k.draw()
  3151. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3152. if game_over:
  3153. screen.fill("blue")
  3154. screen.draw.text("Final Score: "+ str(score), color="white", topleft=(10,10),fontsize=60)
  3155. </code></pre>
  3156. <p>pgzrun.go()
  3157. ```</p>
  3158. <h2>[DAY-68] Lists; Functions</h2>
  3159. <p>Shoot bullets and remove them from the list, play sound, and also level up after killing 3 snakes!</p>
  3160. <p><img alt="game-68.png" src="./screenshots/game-68.png" title="game 68 screenshot" /></p>
  3161. <p>```
  3162. import pgzrun
  3163. import random</p>
  3164. <p>HEIGHT = 200
  3165. WIDTH = 200</p>
  3166. <p>score = 0
  3167. speed = 1
  3168. elf = Actor("c1")
  3169. snake = Actor("snake")
  3170. beep = tone.create('A3', 0.5)</p>
  3171. <p>elf.x = WIDTH/2
  3172. elf.y = HEIGHT/2
  3173. bullets = []</p>
  3174. <p>def place_snake():
  3175. snake.x = random.randint(10,WIDTH-10)
  3176. snake.y = random.randint(10,HEIGHT-10)</p>
  3177. <p>place_snake()</p>
  3178. <p>def bullet_out_of_screen():
  3179. # just delete the first bullet
  3180. bullets.pop(0)</p>
  3181. <p>def on_key_down(key):
  3182. if key == keys.SPACE:
  3183. b = Actor("bullet2")
  3184. b.x = elf.x + 5
  3185. b.y = elf.y
  3186. animate(b, pos=(WIDTH + 100, elf.y), tween='accelerate', on_finished=bullet_out_of_screen)
  3187. bullets.append(b)</p>
  3188. <p>def update():
  3189. global game_over, speed, score, bullets
  3190. if keyboard.left:
  3191. elf.x = elf.x-speed
  3192. if keyboard.right:
  3193. elf.x = elf.x+speed
  3194. if keyboard.up:
  3195. elf.y = elf.y-speed
  3196. if keyboard.down:
  3197. elf.y= elf.y+speed
  3198. if keyboard.R:
  3199. speed = 1
  3200. score = 0
  3201. elf.image = "c1"
  3202. bullets = []</p>
  3203. <pre><code>for b in bullets:
  3204. if b.colliderect(snake):
  3205. score += 1
  3206. speed += 1
  3207. if score == 3:
  3208. elf.image = "c2"
  3209. beep.play()
  3210. place_snake()
  3211. </code></pre>
  3212. <p>def draw():
  3213. screen.fill('black')
  3214. elf.draw()
  3215. snake.draw()
  3216. for b in bullets:
  3217. b.draw()</p>
  3218. <pre><code>screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3219. </code></pre>
  3220. <p>pgzrun.go()
  3221. ```</p>
  3222. <p>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 <code>for b in bullets</code> it will bet slower and slower. Computers can only do so many things per second.</p>
  3223. <p>So when the animation finishes, it will call <code>bullets_out_of_screen</code>, and from there we just say <code>bullets.pop(0)</code> 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.</p>
  3224. <p>Lets say you pressed space 3 times, and shot 3 bullets, so the list, and how the bullets are traveling kindof looks like this:</p>
  3225. <p><code>0 -&gt; bbbbbbbbbbbbbb
  3226. 1 -&gt; bbbbbbb
  3227. 2 -&gt; bbbb</code></p>
  3228. <p>So you see when 0 finishes because it is the oldest, when it does bullets.pop(0), it will actually delete itself.</p>
  3229. <p>pretty cool!</p>
  3230. <h2>[DAY-69] Sockets; Functions; Callbacks</h2>
  3231. <p><img alt="game-69.png" src="./screenshots/game-69.png" title="game 69 screenshot" /></p>
  3232. <p>Multiplayer!</p>
  3233. <p>```
  3234. import pgzrun
  3235. import socket
  3236. import threading
  3237. import sys</p>
  3238. <p>HEIGHT = 200
  3239. WIDTH = 200
  3240. MULTIPLAYER_PORT = 5025
  3241. OTHER_COMPUTER_IP = "192.168.0.10"</p>
  3242. <p>speed = 4
  3243. me = Actor("c1")
  3244. other = Actor("c2")</p>
  3245. <p>me.x = WIDTH/2
  3246. me.y = HEIGHT/2</p>
  3247. <p>socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  3248. socket.bind(("0.0.0.0", MULTIPLAYER_PORT))</p>
  3249. <p>data = None
  3250. def multiplayer():
  3251. global data
  3252. while True:
  3253. data, addr = socket.recvfrom(1024)</p>
  3254. <p>def update():
  3255. if data != None:
  3256. message = data.decode("utf8")
  3257. (x,y) = message.split(":")</p>
  3258. <pre><code> other.x = float(x)
  3259. other.y = float(y)
  3260. </code></pre>
  3261. <p>def on_key_down(key):
  3262. if key == keys.LEFT:
  3263. me.x = me.x-speed
  3264. if key == keys.RIGHT:
  3265. me.x = me.x+speed
  3266. if key == keys.UP:
  3267. me.y = me.y-speed
  3268. if key == keys.DOWN:
  3269. me.y= me.y+speed</p>
  3270. <pre><code>if key == keys.Q:
  3271. sys.exit(0)
  3272. message = bytearray(str(me.x) + ':' + str(me.y),"utf8")
  3273. socket.sendto(message, (OTHER_COMPUTER_IP, MULTIPLAYER_PORT))
  3274. </code></pre>
  3275. <p>def draw():
  3276. screen.fill('black')
  3277. me.draw()
  3278. other.draw()</p>
  3279. <p>threading.Thread(target=multiplayer).start()</p>
  3280. <p>pgzrun.go()
  3281. ```</p>
  3282. <p>There are two important parts here, first is the <code>socket</code> and then the <code>Thread</code>. 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 <code>data</code> variable, then in the <code>update</code> function it splits the message by <code>:</code> and extract the <code>x</code> and <code>y</code> and sets it to the <code>other</code> actor.</p>
  3283. <p>The <code>multiplayer()</code> 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 <code>while True</code>) and the multiplayer loop which is also <code>while True</code>.</p>
  3284. <h2>[DAY-70] Lists; Functions</h2>
  3285. <p>print numbers in a list</p>
  3286. <p><code>data = [1,2,3,4,5]
  3287. for item in data:
  3288. print(e)</code></p>
  3289. <p><code>list_of_lists = [[1,2,3,4,5], [1,2,3], [4,5,6]]
  3290. for l in list_of_lists:
  3291. for item in l:
  3292. print(item)</code></p>
  3293. <p><code>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]]]
  3294. for list_of_lists in list_of_list_of_lists:
  3295. for l in list_of_lists:
  3296. for item in l:
  3297. print(item)</code></p>
  3298. <p>```
  3299. list_of_list_of_list_of_lists = [
  3300. [
  3301. [
  3302. [1,2,3,4,5],
  3303. [1,2,3],
  3304. [4,5,6]
  3305. ],
  3306. [
  3307. [1,2,3,4,5],
  3308. [1,2,3],
  3309. [4,5,6]
  3310. ]
  3311. ],
  3312. [
  3313. [
  3314. [1,2,3,4,5],
  3315. [1,2,3],
  3316. [4,5,6]
  3317. ],
  3318. [
  3319. [1,2,3,4,5],
  3320. [1,2,3],
  3321. [4,5,6]
  3322. ]
  3323. ],
  3324. ]</p>
  3325. <p>for list_of_list_of_lists in list_of_list_of_list_of_lists:
  3326. for list_of_lists in list_of_list_of_lists:
  3327. for l in list_of_lists:
  3328. for item in l:
  3329. print(item)
  3330. ```</p>
  3331. <p>```
  3332. def sum(x):
  3333. r = 0
  3334. for item in x:
  3335. r += item
  3336. return r</p>
  3337. <p>data = [1,2,3,4,5]
  3338. print(sum(data))
  3339. ```</p>
  3340. <p>```
  3341. def sum(x):
  3342. r = 0
  3343. for l in x:
  3344. for item in l:
  3345. r += item
  3346. return r</p>
  3347. <p>data = [[1,2,3,4,5], [1,2,3,4,5]]
  3348. print(sum(data))
  3349. ```</p>
  3350. <h2>[DAY-71] Strings; Integers; While; Functions</h2>
  3351. <p>make a calculator</p>
  3352. <p>```
  3353. while True:
  3354. n1 = int(input("number 1: "))
  3355. n2 = int(input("number 2: "))
  3356. op = input("operation +/-* : ")
  3357. r = 0</p>
  3358. <pre><code>if op == "quit":
  3359. break
  3360. elif op == "+":
  3361. r = n1 + n2
  3362. elif op == "-":
  3363. r = n1 - n2
  3364. elif op == "*":
  3365. r = n1 * n2
  3366. else:
  3367. print("i dont know " + op)
  3368. continue
  3369. print(n1, op, n2, '=',r)
  3370. </code></pre>
  3371. <p>```</p>
  3372. <p>sum numbers from input</p>
  3373. <p>```
  3374. def sum(x):
  3375. r = 0
  3376. for item in x:
  3377. r += item
  3378. return r</p>
  3379. <p>x = []
  3380. while True:
  3381. k = input("enter number: ")
  3382. x.append(int(k))
  3383. print(x)
  3384. print(sum(x))</p>
  3385. <p>```</p>
  3386. <h2>[DAY-72] Reading Code</h2>
  3387. <p>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.</p>
  3388. <p>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.</p>
  3389. <p><img alt="day-72-0.jpg" src="./reading/day-72-0.jpg" title="day 72 example 0" /></p>
  3390. <p><img alt="day-72-1.jpg" src="./reading/day-72-1.jpg" title="day 72 example 1" /></p>
  3391. <p><img alt="day-72-2.jpg" src="./reading/day-72-2.jpg" title="day 72 example 2" /></p>
  3392. <p>Those are just examples, you have to print the programs and go over them with your parent.</p>
  3393. <h2>[DAY-73] Reading Code</h2>
  3394. <p>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.</p>
  3395. <p><img alt="day-73-0.jpg" src="./reading/day-73-0.jpg" title="day 73 example 0" /></p>
  3396. <p><img alt="day-73-1.jpg" src="./reading/day-73-1.jpg" title="day 73 example 1" /></p>
  3397. <p><img alt="day-73-2.jpg" src="./reading/day-73-2.jpg" title="day 73 example 2" /></p>
  3398. <p><img alt="day-73-3.jpg" src="./reading/day-73-3-0.jpg" title="day 73 example 3" /></p>
  3399. <p>Again you can use something else as well, those are just the ones I picked. Be messy with the pencil, connect things together!</p>
  3400. <h2>[DAY-74] Strings; While; Lists</h2>
  3401. <p>Today its up to you what to write, my kid came up with those programs:</p>
  3402. <ol>
  3403. <li>Ask forever what your favorite sport is, if yours is not here use https://emojipedia.org/ to find good emojis.</li>
  3404. </ol>
  3405. <p>```
  3406. while True:
  3407. k = input('what is your favorite sport: ')</p>
  3408. <pre><code>if k == 'soccer':
  3409. print('⚽')
  3410. elif k == 'hockey':
  3411. print('🏑')
  3412. elif k == 'tennis':
  3413. print('🎾')
  3414. elif k == 'volleyball':
  3415. print('🏐')
  3416. elif k == 'table tennis':
  3417. print('🏓')
  3418. elif k == 'baseball':
  3419. print('⚾')
  3420. elif k == 'basketball':
  3421. print('🏀')
  3422. elif k == 'golf':
  3423. print('🏌️‍♂️')
  3424. else:
  3425. print('i dont now ' +k)
  3426. </code></pre>
  3427. <p>```</p>
  3428. <ol>
  3429. <li>and one simple, append and pop from a list.</li>
  3430. </ol>
  3431. <p><code>k = []
  3432. while True:
  3433. s = input('What are you thinking of: ')
  3434. if s == 'pop':
  3435. k.pop(0)
  3436. else:
  3437. k.append(s)
  3438. print(k)</code></p>
  3439. <h2>[DAY-75] Functions; Callbacks; Lists; Encoding</h2>
  3440. <p><img alt="game-75.png" src="./screenshots/game-75.png" title="game 75 screenshot" /></p>
  3441. <p>Enemies come to get you, and you shoot half moons at them. pretty cool.</p>
  3442. <p>```
  3443. import pgzrun
  3444. import random</p>
  3445. <p>HEIGHT = 200
  3446. WIDTH = 200</p>
  3447. <p>score = 0
  3448. speed = 1
  3449. elf = Actor("c1")</p>
  3450. <p>beep = tone.create('A3', 0.5)
  3451. elf.x = 10
  3452. elf.y = HEIGHT/2</p>
  3453. <p>game_over = False</p>
  3454. <p>bullets = []
  3455. enemies = []</p>
  3456. <p>def make_enemies():
  3457. level = int(score / 5) + 1</p>
  3458. <pre><code>duration = (5 - level)
  3459. if duration &lt; 1:
  3460. duration = 1
  3461. for i in range(level):
  3462. snake = Actor("snake")
  3463. snake.x = WIDTH-20
  3464. snake.y = random.randint(10,HEIGHT-10)
  3465. animate(snake, pos=(-100, snake.y), tween='accelerate', duration=duration)
  3466. enemies.append(snake)
  3467. </code></pre>
  3468. <p>def bullet_out_of_screen():
  3469. bullets.pop(0)</p>
  3470. <p>def on_key_down(key):
  3471. if key == keys.SPACE:
  3472. b = Actor("bullet2")
  3473. b.x = elf.x + 5
  3474. b.y = elf.y
  3475. animate(b, pos=(WIDTH + 100, elf.y), tween='accelerate', on_finished=bullet_out_of_screen)
  3476. bullets.append(b)</p>
  3477. <p>def update():
  3478. global game_over, speed, score, bullets, enemies
  3479. if keyboard.left:
  3480. elf.x = elf.x-speed
  3481. if keyboard.right:
  3482. elf.x = elf.x+speed
  3483. if keyboard.up:
  3484. elf.y = elf.y-speed
  3485. if keyboard.down:
  3486. elf.y= elf.y+speed
  3487. if keyboard.R:
  3488. speed = 1
  3489. score = 0
  3490. bullets = []
  3491. enemies = []
  3492. game_over = False</p>
  3493. <pre><code>hit = []
  3494. for b in bullets:
  3495. for e in enemies:
  3496. if b.colliderect(e):
  3497. hit.append(e)
  3498. if len(hit) &gt; 0:
  3499. score += len(hit)
  3500. if speed &lt; 4:
  3501. speed += 1
  3502. beep.play()
  3503. for e in hit:
  3504. enemies.remove(e)
  3505. for e in enemies:
  3506. if e.colliderect(elf):
  3507. game_over = True
  3508. </code></pre>
  3509. <p>def draw():
  3510. if game_over:
  3511. screen.fill('black')
  3512. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3513. else:
  3514. screen.fill('black')
  3515. elf.draw()</p>
  3516. <pre><code> for b in bullets:
  3517. b.draw()
  3518. for e in enemies:
  3519. e.draw()
  3520. screen.draw.text("Score: "+ str(score), color="white", topleft=(10,10))
  3521. </code></pre>
  3522. <p>make_enemies()
  3523. clock.schedule_interval(make_enemies, 2)</p>
  3524. <p>pgzrun.go()
  3525. ```
  3526. <img alt="day-75-1.jpg" src="./reading/day-75-1.jpg" title="day 75 example 1" /></p>
  3527. <p>tic tac toe but with one character variable names</p>
  3528. <p>```
  3529. x = [
  3530. # 0 1 2 3
  3531. ['〰️','🅰️','🅱️','🅾️'], # 0
  3532. ['🥇','〰️','〰️','〰️'], # 1
  3533. ['🥈','〰️','〰️','〰️'], # 2
  3534. ['🥉','〰️','〰️','〰️'], # 3</p>
  3535. <pre><code>]
  3536. </code></pre>
  3537. <p>k = '🛹'</p>
  3538. <p>while True:
  3539. for i in x:
  3540. for s in i:
  3541. print(s,end=' ')
  3542. print('')</p>
  3543. <pre><code>l = input(k + ": ")
  3544. if l == 'a1':
  3545. x[1][1]=k
  3546. elif l == 'a2':
  3547. x[2][1]=k
  3548. elif l == 'a3':
  3549. x[3][1]=k
  3550. elif l == 'b1':
  3551. x[1][2]=k
  3552. elif l == 'b2':
  3553. x[2][2]=k
  3554. elif l == 'b3':
  3555. x[3][2]=k
  3556. elif l == 'o1':
  3557. x[1][3]=k
  3558. elif l == 'o2':
  3559. x[2][3]=k
  3560. elif l == 'o3':
  3561. x[3][3]=k
  3562. else:
  3563. continue
  3564. if k == '🛹':
  3565. k = '⚽'
  3566. else:
  3567. k = '🛹'
  3568. </code></pre>
  3569. <p>```</p>
  3570. <p>30 and back</p>
  3571. <p><code>for i in range(1,31):
  3572. print(i)
  3573. for i in range(1,31):
  3574. print(30 - i)</code></p>
  3575. <p>football mania</p>
  3576. <p><code>d = 30
  3577. while True:
  3578. for i in range(1,d):
  3579. print('⚽' * i)
  3580. for i in range(1,d):
  3581. h = (d - i)
  3582. print('⚽' * h)</code></p>
  3583. <h2>[DAY-76] Functions; Callbacks; Lists</h2>
  3584. <p><img alt="game-76.png" src="./screenshots/game-76.png" title="game 76 screenshot" /></p>
  3585. <p>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.</p>
  3586. <p>```
  3587. import pgzrun
  3588. import random</p>
  3589. <p>HEIGHT = 200
  3590. WIDTH = 200</p>
  3591. <p>speedA = 3
  3592. speedB = 3</p>
  3593. <p>playerA = Actor("c1")
  3594. playerB = Actor("c2")</p>
  3595. <p>playerA.x = 10
  3596. playerA.y = HEIGHT - 40</p>
  3597. <p>playerB.x = 10
  3598. playerB.y = 40</p>
  3599. <p>game_over = False</p>
  3600. <p>def random_speed():
  3601. global speedA, speedB
  3602. speedA = random.randint(1,5)
  3603. speedB = random.randint(1,5)</p>
  3604. <p>def on_key_down(key):
  3605. global game_over</p>
  3606. <pre><code># player A
  3607. if key == keys.A:
  3608. playerA.x -= speedA
  3609. if key == keys.D:
  3610. playerA.x += speedA
  3611. if key == keys.W:
  3612. playerA.y -= speedA
  3613. if key == keys.S:
  3614. playerA.y += speedA
  3615. # player B
  3616. if key == keys.LEFT:
  3617. playerB.x -= speedB
  3618. if key == keys.RIGHT:
  3619. playerB.x += speedB
  3620. if key == keys.UP:
  3621. playerB.y -= speedB
  3622. if key == keys.DOWN:
  3623. playerB.y += speedB
  3624. </code></pre>
  3625. <p>def update():
  3626. global game_over
  3627. if playerA.colliderect(playerB):
  3628. game_over = True</p>
  3629. <p>def draw():
  3630. if game_over:
  3631. screen.fill('black')
  3632. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3633. else:
  3634. screen.fill('black')
  3635. screen.draw.text("RUN! elf: " + str(speedA) + " king: " + str(speedB) , color="white", topleft=(10,10))
  3636. playerA.draw()
  3637. playerB.draw()</p>
  3638. <p>clock.schedule_interval(random_speed, 2)</p>
  3639. <p>pgzrun.go()
  3640. ```</p>
  3641. <p>Basic math quiz</p>
  3642. <p><code>import random
  3643. while True:
  3644. k = random.randint(1,13)
  3645. s = random.randint(1,13)
  3646. r = k * s
  3647. g = int(input('How much is '+str(k) +'*' +str(s) + ': '))
  3648. if g == r:
  3649. print('Wow nice job its CORRECT')
  3650. else:
  3651. print('wrong the answer was: ' + str(r))</code></p>
  3652. <p>7 days average</p>
  3653. <p>```
  3654. x = [1231,5123,6737,6725,6261,2664,62561]
  3655. n = len(x)</p>
  3656. <p>print(x)
  3657. print(n)</p>
  3658. <p>sum = 0
  3659. for i in x:
  3660. sum += i</p>
  3661. <p>print('sum: ' + str(sum))
  3662. print('average: ' + str(sum/n))
  3663. ```</p>
  3664. <h2>[DAY-77] Lists; Encode/Decode</h2>
  3665. <p>morse code translator</p>
  3666. <p>```
  3667. 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',' ','.',',']
  3668. morse = ['.-','-...','-.-.','-..','.','..-.','--.','....','..','.---','-.-','.-..','--','-.','---','.--.','--.-','.-.','...','-','..-','...-','.--','-..-','-.--','--..','/','.-.-.-','--..--']</p>
  3669. <p>print(len(morse))
  3670. print(len(alphabet))</p>
  3671. <p>for i in range(len(alphabet)):
  3672. print(alphabet[i] + " -&gt; " + morse[i])</p>
  3673. <p>text = '.... . .-.. .-.. --- / .-- --- .-. .-.. -.. .-.-.- / - .... .. ... / .. ... / -- --- .-. ... . / -.-. --- -.. . .-.-.- / - .... . .-. . / .- .-. . / -- .- -. -.-- / -.-. --- -.. . ... --..-- / -... ..- - / - .... .. ... / --- -. . / .. ... / .--. .-. . - - -.-- / -.-. --- --- .-.. --..-- / --. --- --- -.. / .--- --- -... / - .-. .- -. ... .-.. .- - .. -. --. / .. - .-.-.-'.split(' ')
  3674. for word in text:
  3675. found = False
  3676. for i in range(len(morse)):
  3677. x = morse[i]
  3678. if x == word:
  3679. print(alphabet[i], end = '')
  3680. found = True
  3681. if not found:
  3682. print(word , end='')
  3683. ```</p>
  3684. <h2>[DAY-78] Coordinates; Functions; Callbacks</h2>
  3685. <p><img alt="game-78.png" src="./screenshots/game-78.png" title="game 78 screenshot" /></p>
  3686. <p>Small modifications to the previous game, gold in the middle moves the king away, randomize the elf position every 2 seconds</p>
  3687. <p>```
  3688. import pgzrun
  3689. import random</p>
  3690. <p>HEIGHT = 200
  3691. WIDTH = 200</p>
  3692. <p>speedE = 3
  3693. speedK = 3</p>
  3694. <p>elf = Actor("c1")
  3695. king = Actor("c2")
  3696. gold = Actor("c3")</p>
  3697. <p>gold.x = WIDTH/2
  3698. gold.y = HEIGHT/2
  3699. elf.x = 10
  3700. elf.y = HEIGHT - 40
  3701. king.x = 10
  3702. king.y = 40</p>
  3703. <p>game_over = False</p>
  3704. <p>def random_speed():
  3705. global speedE, speedK
  3706. speedE = random.randint(3,5)
  3707. speedK = random.randint(2,5)</p>
  3708. <p>def random_place():
  3709. elf.x = random.randint(0,WIDTH)
  3710. elf.y = random.randint(0,HEIGHT)</p>
  3711. <p>def update():
  3712. global game_over</p>
  3713. <pre><code># elf
  3714. if keyboard.A:
  3715. elf.x -= speedE
  3716. if keyboard.D:
  3717. elf.x += speedE
  3718. if keyboard.W:
  3719. elf.y -= speedE
  3720. if keyboard.S:
  3721. elf.y += speedE
  3722. # king
  3723. if keyboard.left:
  3724. king.x -= speedK
  3725. if keyboard.right:
  3726. king.x += speedK
  3727. if keyboard.up:
  3728. king.y -= speedK
  3729. if keyboard.down:
  3730. king.y += speedK
  3731. if keyboard.SPACE:
  3732. elf.image = 'snake'
  3733. random_speed()
  3734. if keyboard.R:
  3735. game_over = 1==2
  3736. elf.x = 10
  3737. elf.y = HEIGHT - 40
  3738. king.x = 10
  3739. king.y = 40
  3740. if elf.x &lt; 0:
  3741. elf.x = 0
  3742. if elf.x &gt; WIDTH:
  3743. elf.x = WIDTH
  3744. if elf.y &lt; 0:
  3745. elf.y = 0
  3746. if elf.y &gt; HEIGHT:
  3747. elf.y = HEIGHT
  3748. if king.x &lt; 0:
  3749. king.x = 0
  3750. if king.x &gt; WIDTH:
  3751. king.x = WIDTH
  3752. if king.y &lt; 0:
  3753. king.y = 0
  3754. if king.y &gt; HEIGHT:
  3755. king.y = HEIGHT
  3756. if elf.colliderect(gold):
  3757. king.x = WIDTH
  3758. king.y = HEIGHT
  3759. if king.colliderect(gold):
  3760. game_over = True
  3761. if elf.colliderect(king):
  3762. game_over = True
  3763. </code></pre>
  3764. <p>def draw():
  3765. if game_over:
  3766. screen.fill('black')
  3767. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3768. else:
  3769. screen.fill('black')
  3770. screen.draw.text("RUN! elf: " + str(speedE) + " king: " + str(speedK) , color="white", topleft=(10,10))
  3771. elf.draw()
  3772. king.draw()
  3773. gold.draw()</p>
  3774. <p>clock.schedule_interval(random_speed, 2)
  3775. clock.schedule_interval(random_place, 5)</p>
  3776. <p>pgzrun.go()
  3777. ```</p>
  3778. <p>Explanation about setting x and y to be random:</p>
  3779. <p><img alt="day-78-explain.png" src="./reading/day-78-explain.png" title="day 78 explain coordinates" /></p>
  3780. <p>Write a program to compute the average of a list of numbers:</p>
  3781. <p><img alt="day-78-a.jpg" src="./reading/day-78-a.jpg" title="day 78 average of list of numbers" /></p>
  3782. <p>Decode morse code:</p>
  3783. <p><img alt="day-78-c.jpg" src="./reading/day-78-c.jpg" title="day 78 decode morse code" /></p>
  3784. <h2>[DAY-79] Lists; Encoding</h2>
  3785. <p>morse code agian</p>
  3786. <p>```
  3787. alphabet = ['a','b','c','d','e']
  3788. morse = ['.-','-...','-.-.','...','.']</p>
  3789. <p>for i in range(len(alphabet)):
  3790. print(alphabet[i])
  3791. print(morse[i])</p>
  3792. <p>text = ['.-..','.','.-..','.-']</p>
  3793. <p>for word in text:
  3794. for c in range(len(morse)):
  3795. if word == morse[c]:
  3796. print(alphabet[c])
  3797. ```</p>
  3798. <h2>[DAY-80] Lists; Functions</h2>
  3799. <p><img alt="game-80.png" src="./screenshots/game-80.png" title="game 80 screenshot" /></p>
  3800. <p>PONG (almost)</p>
  3801. <p>```
  3802. import pgzrun
  3803. import random</p>
  3804. <p>HEIGHT = 200
  3805. WIDTH = 200</p>
  3806. <p>left = Actor("c1")
  3807. left.x = 10
  3808. left.y = HEIGHT/2</p>
  3809. <p>right = Actor("c2")
  3810. right.x = WIDTH - 10
  3811. right.y = HEIGHT/2</p>
  3812. <p>ball = Actor("bullet")
  3813. ball.x = WIDTH/2
  3814. ball.y = HEIGHT/2</p>
  3815. <p>game_area = Rect((0, 0), (WIDTH, HEIGHT))</p>
  3816. <p>game_over = False</p>
  3817. <p>def send_ball_to(direction):
  3818. duration = 3
  3819. if direction == 'left':
  3820. animate(ball, pos=(-100, random.randint(0,HEIGHT)), tween='linear', duration=duration)
  3821. else:
  3822. animate(ball, pos=(WIDTH + 100, random.randint(0,HEIGHT)), tween='linear', duration=duration)</p>
  3823. <p>def update():
  3824. global game_over
  3825. speed = 3</p>
  3826. <pre><code>if keyboard.R:
  3827. ball.x = WIDTH/2
  3828. ball.y = HEIGHT/2
  3829. send_ball_to('left')
  3830. game_over = False
  3831. if keyboard.W:
  3832. left.y -= speed
  3833. if keyboard.S:
  3834. left.y += speed
  3835. if keyboard.up:
  3836. right.y -= speed
  3837. if keyboard.down:
  3838. right.y += speed
  3839. if left.colliderect(ball):
  3840. send_ball_to('right')
  3841. if right.colliderect(ball):
  3842. send_ball_to('left')
  3843. if not ball.colliderect(game_area):
  3844. game_over = True
  3845. </code></pre>
  3846. <p>def draw():
  3847. if game_over:
  3848. screen.fill('black')
  3849. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  3850. else:
  3851. screen.fill('black')
  3852. left.draw()
  3853. right.draw()
  3854. ball.draw()
  3855. screen.draw.rect(game_area, (200, 0, 0))</p>
  3856. <p>send_ball_to('left')</p>
  3857. <p>pgzrun.go()
  3858. ```</p>
  3859. <p><img alt="day-80-a.jpg" src="./reading/day-80-a.jpg" title="day 80 reading pong" /></p>
  3860. <p>average of two lists</p>
  3861. <p><img alt="day-80-b.jpg" src="./reading/day-80-b.jpg" title="day 80 reading average of two lists" /></p>
  3862. <h2>[DAY-81] Lists; Encoding</h2>
  3863. <p>First image</p>
  3864. <p><code>+-----+
  3865. | * * |
  3866. | * |
  3867. | * * |
  3868. +-----+</code></p>
  3869. <p>list of lists with pixels</p>
  3870. <p>```
  3871. image = [
  3872. [1,3,3,3,3,3,1],
  3873. [2,4,5,4,5,4,2],
  3874. [2,4,4,5,4,4,2],
  3875. [2,4,5,4,5,4,2],
  3876. [1,3,3,3,3,3,1],
  3877. ]</p>
  3878. <p>for row in image:
  3879. for pixel in row:
  3880. if pixel == 1:
  3881. print('+', end='')
  3882. elif pixel == 2:
  3883. print('|', end='')
  3884. elif pixel == 3:
  3885. print('-', end='')
  3886. elif pixel == 4:
  3887. print(' ', end='')
  3888. elif pixel == 5:
  3889. print('*', end='')
  3890. else:
  3891. print("dont know what to do with: " + str(pixel))
  3892. print('')
  3893. ```</p>
  3894. <p>just a list of pixels</p>
  3895. <p>```
  3896. image = [
  3897. 1,3,3,3,3,3,1,
  3898. 2,4,5,4,5,4,2,
  3899. 2,4,4,5,4,4,2,
  3900. 2,4,5,4,5,4,2,
  3901. 1,3,3,3,3,3,1,
  3902. ]</p>
  3903. <p>width = 7</p>
  3904. <p>for (index, pixel) in enumerate(image):
  3905. if index &gt; 0 and index % width == 0:
  3906. print('')</p>
  3907. <pre><code>if pixel == 1:
  3908. print('+', end='')
  3909. elif pixel == 2:
  3910. print('|', end='')
  3911. elif pixel == 3:
  3912. print('-', end='')
  3913. elif pixel == 4:
  3914. print(' ', end='')
  3915. elif pixel == 5:
  3916. print('*', end='')
  3917. else:
  3918. print("dont know what to do with: " + str(pixel))
  3919. </code></pre>
  3920. <p>```</p>
  3921. <p>some fun with lists
  3922. ```
  3923. x = ['a','b','c','d']
  3924. m = ['w','x','y','z']
  3925. d = ['g','h','j','k']</p>
  3926. <h1>a -&gt; 0</h1>
  3927. <h1>b -&gt; 1</h1>
  3928. <h1>c -&gt; 2</h1>
  3929. <p>for i in range(len(x)):
  3930. print(i,end=' ')
  3931. print(x[i],end=' ')
  3932. print(m[i],end=' ')
  3933. print(d[i])
  3934. ```</p>
  3935. <p>how similar are lists and strings</p>
  3936. <p>```
  3937. x = 'hello'</p>
  3938. <p>for i in range(len(x)):
  3939. print(i,end=' ')
  3940. print(x[i])
  3941. ```</p>
  3942. <p>similar, but not quite, you cant change the inside of a string, but you can change the inside of a list.</p>
  3943. <p>```
  3944. x = ['h','e','l','l','o']
  3945. y = 'hello'</p>
  3946. <p>x[2] = 'm'
  3947. y = 'hemlo'</p>
  3948. <p>for i in range(len(x)):
  3949. print(i,end=' ')
  3950. print(x[i], end=' ')
  3951. print(y[i])
  3952. ```</p>
  3953. <p>sum many lists
  3954. ```
  3955. a = [6,3,2]
  3956. b = [78,21,1]
  3957. c = [123,5,1]</p>
  3958. <p>sum = 0
  3959. for i in range(len(a)):
  3960. sum += a[i] + b[i] + c[i]</p>
  3961. <p>print(sum)
  3962. ```</p>
  3963. <p>another way to sum</p>
  3964. <p>```
  3965. a = [6,3,2]
  3966. b = [78,21,1]
  3967. c = [123,5,1]</p>
  3968. <p>sum = 0</p>
  3969. <p>for x in a:
  3970. sum += x</p>
  3971. <p>for x in b:
  3972. sum += x</p>
  3973. <p>for x in c:
  3974. sum += x</p>
  3975. <p>print(sum)
  3976. ```</p>
  3977. <h2>[DAY-82] Lists; Strings</h2>
  3978. <p><img alt="game-82.png" src="./screenshots/game-82.png" title="game 82 screenshot" /></p>
  3979. <p>simple game with history, press S to save your position to a list of positions, and then B to go back in time</p>
  3980. <p>```
  3981. import pgzrun
  3982. import random</p>
  3983. <p>HEIGHT = 200
  3984. WIDTH = 200</p>
  3985. <p>player = Actor("c1")
  3986. player.x = WIDTH/2
  3987. player.y = HEIGHT/2</p>
  3988. <p>history = []</p>
  3989. <p>def on_key_down(key):
  3990. speed = 3</p>
  3991. <pre><code>if key == keys.UP:
  3992. player.y -= speed
  3993. if key == keys.DOWN:
  3994. player.y += speed
  3995. if key == keys.LEFT:
  3996. player.x -= speed
  3997. if key == keys.RIGHT:
  3998. player.x += speed
  3999. if key == keys.S:
  4000. position = [player.x, player.y]
  4001. history.append(position)
  4002. print('append', history)
  4003. if key == keys.B and len(history) &gt; 0:
  4004. last = history.pop()
  4005. player.x = last[0]
  4006. player.y = last[1]
  4007. print('pop', history)
  4008. </code></pre>
  4009. <p>def draw():
  4010. screen.fill('black')
  4011. player.draw()</p>
  4012. <p>pgzrun.go()
  4013. ```</p>
  4014. <p>Two players, and more positions</p>
  4015. <p>```
  4016. import pgzrun
  4017. import random</p>
  4018. <p>HEIGHT = 200
  4019. WIDTH = 200
  4020. player1 = Actor("c1")
  4021. player2 = Actor('c2')
  4022. history = []</p>
  4023. <p>def on_key_down(key):
  4024. speed = 10
  4025. if key == keys.W:
  4026. player1.y-= speed
  4027. if key == keys.A:
  4028. player1.x-=speed
  4029. if key == keys.S:
  4030. player1.y += speed
  4031. if key == keys.D:
  4032. player1.x += speed</p>
  4033. <pre><code>if key == keys.UP:
  4034. player2.y-= speed
  4035. if key == keys.LEFT:
  4036. player2.x-=speed
  4037. if key == keys.DOWN:
  4038. player2.y += speed
  4039. if key == keys.RIGHT:
  4040. player2.x += speed
  4041. if key == keys.F:
  4042. positions = [player1.x,player1.y,player2.x,player2.y]
  4043. history.append(positions)
  4044. print('push', history)
  4045. if key == keys.G:
  4046. if len(history) &gt; 0:
  4047. positions = history.pop()
  4048. player1.x = positions[0]
  4049. player1.y = positions[1]
  4050. player2.x = positions[2]
  4051. player2.y = positions[3]
  4052. print('pop', history)
  4053. </code></pre>
  4054. <p>def draw():
  4055. screen.fill('black')
  4056. player1.draw()
  4057. player2.draw()
  4058. pgzrun.go()
  4059. ```</p>
  4060. <p>More lists</p>
  4061. <p>```
  4062. a = ['h','w','e']
  4063. b = ['e','o','a']
  4064. c = ['l','r','r']
  4065. d = ['l','l','t']
  4066. e = ['o','d','h']</p>
  4067. <p>sum1 = ''
  4068. sum2 = ''</p>
  4069. <p>sum1 = a[0] + b[0] + c[0] + d[0] + e[0]
  4070. sum2 = a[1] + b[1] + c[1] + d[1] + e[1]</p>
  4071. <p>print(sum1)
  4072. print(sum2)</p>
  4073. <p>sum = []
  4074. for i in range(len(a)):
  4075. sum.append('')
  4076. sum[i] = a[i] + b[i] + c[i] + d[i] + e[i]</p>
  4077. <p>print(sum)
  4078. ```</p>
  4079. <p>sum from the input</p>
  4080. <p>```
  4081. list = []
  4082. while True:
  4083. integer = int(input('enter a number: '))
  4084. list.append(integer)
  4085. sum = 0
  4086. for i in list:
  4087. sum += i</p>
  4088. <pre><code>print(list, sum)
  4089. </code></pre>
  4090. <p>```</p>
  4091. <h2>[DAY-83] Lists; Functions</h2>
  4092. <p><img alt="game-83.png" src="./screenshots/game-83.png" title="game 83 screenshot" /></p>
  4093. <p>```
  4094. import pgzrun
  4095. import random</p>
  4096. <p>HEIGHT = 200
  4097. WIDTH = 200</p>
  4098. <p>player = Actor("c1")
  4099. player.x = WIDTH/2
  4100. player.y = HEIGHT/2</p>
  4101. <p>things = []</p>
  4102. <p>def on_key_down(key):
  4103. speed = 10</p>
  4104. <pre><code>if key == keys.UP:
  4105. player.y -= speed
  4106. if key == keys.DOWN:
  4107. player.y += speed
  4108. if key == keys.LEFT:
  4109. player.x -= speed
  4110. if key == keys.RIGHT:
  4111. player.x += speed
  4112. if key == keys.F:
  4113. thing = Actor("flower")
  4114. thing.x = player.x
  4115. thing.y = player.y
  4116. things.append(thing)
  4117. if key == keys.R:
  4118. thing = Actor("rock")
  4119. thing.x = player.x
  4120. thing.y = player.y
  4121. things.append(thing)
  4122. </code></pre>
  4123. <p>def draw():
  4124. screen.fill('black')
  4125. player.draw()
  4126. for t in things:
  4127. t.draw()</p>
  4128. <p>pgzrun.go()
  4129. ```</p>
  4130. <p>With a function, so we can add more keys faster and we dont duplicate that much code</p>
  4131. <p>```
  4132. import pgzrun
  4133. import random</p>
  4134. <p>HEIGHT = 200
  4135. WIDTH = 200</p>
  4136. <p>player = Actor("c1")
  4137. player.x = WIDTH/2
  4138. player.y = HEIGHT/2</p>
  4139. <p>things = []
  4140. def place_thing(kind):
  4141. thing = Actor(kind)
  4142. thing.x = player.x
  4143. thing.y = player.y</p>
  4144. <pre><code>things.append(thing)
  4145. </code></pre>
  4146. <p>def on_key_down(key):
  4147. speed = 15</p>
  4148. <pre><code>if key == keys.UP:
  4149. player.y -= speed
  4150. if key == keys.DOWN:
  4151. player.y += speed
  4152. if key == keys.LEFT:
  4153. player.x -= speed
  4154. if key == keys.RIGHT:
  4155. player.x += speed
  4156. if key == keys.F:
  4157. place_thing("flower")
  4158. if key == keys.R:
  4159. place_thing("rock")
  4160. if key == keys.K:
  4161. place_thing("c2")
  4162. </code></pre>
  4163. <p>def draw():
  4164. screen.fill('black')
  4165. player.draw()
  4166. for t in things:
  4167. t.draw()</p>
  4168. <p>pgzrun.go()
  4169. ```</p>
  4170. <p>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</p>
  4171. <p>```
  4172. ...
  4173. game_map = []
  4174. def place_thing(kind):
  4175. thing = Actor(kind)
  4176. thing.x = player.x
  4177. thing.y = player.y</p>
  4178. <pre><code>things.append(thing)
  4179. game_map.append([kind, thing.x, thing.y])
  4180. print(game_map)
  4181. </code></pre>
  4182. <p>... <br />
  4183. ```</p>
  4184. <p>use the map:</p>
  4185. <p><img alt="game-83-a.png" src="./screenshots/game-83-a.png" title="game 83-a screenshot" /></p>
  4186. <p>```
  4187. import pgzrun
  4188. import random</p>
  4189. <p>HEIGHT = 200
  4190. WIDTH = 200</p>
  4191. <p>player = Actor("c1")
  4192. player.x = WIDTH/2
  4193. player.y = HEIGHT/2</p>
  4194. <p>things = []
  4195. def place_thing(kind,x,y):
  4196. thing = Actor(kind)
  4197. thing.x = x
  4198. thing.y = y
  4199. things.append(thing)</p>
  4200. <p>def on_key_down(key):
  4201. speed = 15</p>
  4202. <pre><code>if key == keys.UP:
  4203. player.y -= speed
  4204. if key == keys.DOWN:
  4205. player.y += speed
  4206. if key == keys.LEFT:
  4207. player.x -= speed
  4208. if key == keys.RIGHT:
  4209. player.x += speed
  4210. </code></pre>
  4211. <p>def draw():
  4212. screen.fill('black')
  4213. player.draw()
  4214. for t in things:
  4215. t.draw()</p>
  4216. <p>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]]
  4217. for g in game_map:
  4218. place_thing(g[0],g[1],g[2])</p>
  4219. <p>pgzrun.go()
  4220. ```</p>
  4221. <p><img alt="game-83-b.png" src="./screenshots/game-83-b.png" title="game 83-a screenshot" />
  4222. <img alt="game-83-c.png" src="./screenshots/game-83-c.png" title="game 83-c screenshot" /></p>
  4223. <p>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</p>
  4224. <p>```
  4225. import pgzrun
  4226. import random</p>
  4227. <p>HEIGHT = 200
  4228. WIDTH = 200</p>
  4229. <p>player = Actor("c1")</p>
  4230. <p>things = []</p>
  4231. <p>game = []
  4232. for g in game:
  4233. t = Actor(g[0])
  4234. t.x = g[1]
  4235. t.y = g[2]
  4236. things.append(t)</p>
  4237. <p>def on_key_down(key):
  4238. speed = 10</p>
  4239. <pre><code>if key == keys.UP:
  4240. player.y -= speed
  4241. if key == keys.DOWN:
  4242. player.y += speed
  4243. if key == keys.LEFT:
  4244. player.x -= speed
  4245. if key == keys.RIGHT:
  4246. player.x += speed
  4247. if key == keys.F:
  4248. f = Actor("flower")
  4249. f.x = player.x
  4250. f.y = player.y
  4251. things.append(f)
  4252. if key == keys.R:
  4253. f = Actor("rock")
  4254. f.x = player.x
  4255. f.y = player.y
  4256. things.append(f)
  4257. if key == keys.U:
  4258. things.pop()
  4259. if key == keys.D:
  4260. collide = []
  4261. for t in things:
  4262. if player.colliderect(t):
  4263. collide.append(t)
  4264. for t in collide:
  4265. things.remove(t)
  4266. if key == keys.S:
  4267. positions = []
  4268. for t in things:
  4269. positions.append([t.image,t.x,t.y])
  4270. print(positions)
  4271. </code></pre>
  4272. <p>def draw():
  4273. screen.fill('black')
  4274. player.draw()
  4275. for t in things:
  4276. t.draw()</p>
  4277. <p>pgzrun.go()
  4278. ```</p>
  4279. <h2>[DAY-84] Lists</h2>
  4280. <p><img alt="game-84.png" src="./screenshots/game-84.png" title="game 84 screenshot" /></p>
  4281. <p>Lets visualize the list, try to delete from the middle, and see how the indexes change.</p>
  4282. <p>```
  4283. import pgzrun
  4284. import random</p>
  4285. <p>HEIGHT = 200
  4286. WIDTH = 200</p>
  4287. <p>player = Actor("c1")</p>
  4288. <p>things = []</p>
  4289. <p>def on_key_down(key):
  4290. speed = 10</p>
  4291. <pre><code>if key == keys.UP:
  4292. player.y -= speed
  4293. if key == keys.DOWN:
  4294. player.y += speed
  4295. if key == keys.LEFT:
  4296. player.x -= speed
  4297. if key == keys.RIGHT:
  4298. player.x += speed
  4299. if key == keys.F:
  4300. f = Actor("flower")
  4301. f.x = player.x
  4302. f.y = player.y
  4303. things.append(f)
  4304. if key == keys.R:
  4305. f = Actor("rock")
  4306. f.x = player.x
  4307. f.y = player.y
  4308. things.append(f)
  4309. if key == keys.U:
  4310. things.pop()
  4311. if key == keys.D:
  4312. collide = []
  4313. for t in things:
  4314. if player.colliderect(t):
  4315. collide.append(t)
  4316. for t in collide:
  4317. things.remove(t)
  4318. </code></pre>
  4319. <p>def draw():
  4320. screen.fill('black')
  4321. player.draw()</p>
  4322. <pre><code>for i in range(len(things)):
  4323. t = things[i]
  4324. t.draw()
  4325. screen.draw.text(str(i), color=(255,255,255), topleft=(t.x,t.y))
  4326. if i &gt; 0:
  4327. p = things[i-1]
  4328. screen.draw.line((p.x,p.y), (t.x,t.y), (255,255,255))
  4329. </code></pre>
  4330. <p>pgzrun.go()
  4331. ```</p>
  4332. <p>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:</p>
  4333. <p>```</p>
  4334. <h1>change this to go from t to the next element of things, instead from t to previous</h1>
  4335. <p>for i in range(len(things)):
  4336. t = things[i]
  4337. ...
  4338. if i &gt; 0:
  4339. p = things[i-1]
  4340. ...
  4341. ```</p>
  4342. <h2>[DAY-85] List; Functions</h2>
  4343. <p>This day is more about reading than writing, those are few different examples you can use</p>
  4344. <p><img alt="game-85.png" src="./screenshots/game-85.png" title="game 85 screenshot" /></p>
  4345. <p>don't let the <strong>zombie</strong> flowers overrun you, smash them with rocks</p>
  4346. <p>```
  4347. import pgzrun
  4348. import random</p>
  4349. <p>HEIGHT = 200
  4350. WIDTH = 200</p>
  4351. <p>game_over = False</p>
  4352. <p>elf = Actor("c1")
  4353. elf.x = WIDTH/2
  4354. elf.y = HEIGHT-20
  4355. flowers = []
  4356. rocks = []</p>
  4357. <p>game_area = Rect((0, 0), (WIDTH, HEIGHT-40))</p>
  4358. <p>def add_one_row():
  4359. lastY = 0
  4360. if len(flowers) &gt; 0:
  4361. f = flowers[len(flowers)-1]
  4362. lastY = f.y</p>
  4363. <pre><code>for i in range(20, WIDTH-10, 20):
  4364. f = Actor("flower")
  4365. f.x = i
  4366. f.y = lastY + 10
  4367. flowers.append(f)
  4368. </code></pre>
  4369. <p>def rock_out_of_screen():
  4370. if len(rocks) &gt; 0:
  4371. rocks.pop(0)</p>
  4372. <p>def on_key_down(key):
  4373. speed = 10
  4374. if key == keys.LEFT:
  4375. elf.x -= speed
  4376. if key == keys.RIGHT:
  4377. elf.x += speed</p>
  4378. <pre><code>if key == keys.SPACE:
  4379. rock = Actor("rock")
  4380. rock.x = elf.x
  4381. rock.y = elf.y - 20
  4382. animate(rock,pos=(rock.x, -100), on_finished=rock_out_of_screen)
  4383. rocks.append(rock)
  4384. </code></pre>
  4385. <p>def update():
  4386. global game_over
  4387. hit = []
  4388. for b in rocks:
  4389. for f in flowers:
  4390. if b.colliderect(f) and random.randint(0,10) &gt; 7:
  4391. hit.append(f)</p>
  4392. <pre><code>for h in hit:
  4393. flowers.remove(h)
  4394. for f in flowers:
  4395. if not f.colliderect(game_area):
  4396. game_over = True
  4397. </code></pre>
  4398. <p>def draw():
  4399. if game_over:
  4400. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  4401. else:
  4402. screen.fill('black')
  4403. elf.draw()
  4404. for f in flowers:
  4405. f.draw()
  4406. for r in rocks:
  4407. r.draw()</p>
  4408. <pre><code> screen.draw.rect(game_area, (200, 0, 0))
  4409. </code></pre>
  4410. <p>add_one_row()
  4411. clock.schedule_interval(add_one_row, 5)</p>
  4412. <p>pgzrun.go()
  4413. ```</p>
  4414. <p><img alt="game-85-a.png" src="./screenshots/game-85-a.png" title="game 85-a screenshot" /></p>
  4415. <p>```
  4416. import turtle as t</p>
  4417. <p>size = 10</p>
  4418. <p>t.pensize(size)
  4419. t.left(45)
  4420. t.forward(90)
  4421. t.circle(45,extent=180)
  4422. t.right(90)
  4423. t.circle(45,extent=180)
  4424. t.forward(90)
  4425. t.penup()
  4426. t.goto(-35,-35)
  4427. t.pendown()
  4428. t.write('i love python')
  4429. t.penup()
  4430. ```</p>
  4431. <p><img alt="game-85-b.png" src="./screenshots/game-85-b.png" title="game 85-b screenshot" /></p>
  4432. <p>```
  4433. import turtle as t
  4434. import datetime
  4435. import time
  4436. def deg(h,m,s):
  4437. hDeg=(h<em>3600+m</em>60+s)/(3600<em>12)</em>360
  4438. mDeg=(m<em>60+s)/3600</em>360
  4439. sDeg=360/60*s</p>
  4440. <p>return (90+hDeg,90+mDeg,90+sDeg)</p>
  4441. <p>def show(h, size):
  4442. (hDeg,m,s) = deg(h,0,0)</p>
  4443. <p>t.penup()
  4444. t.goto(0, size)
  4445. t.pencolor('white')
  4446. t.setheading(hDeg)
  4447. t.forward(size)
  4448. t.write(str(h))</p>
  4449. <p>def klok(size, h, m, s):
  4450. t.reset()
  4451. (hDeg,mDeg,sDeg) = deg(h,m,s)</p>
  4452. <p>t.pendown()
  4453. t.pensize(7)
  4454. t.bgcolor('black')
  4455. t.pencolor('lime')</p>
  4456. <p>t.circle(size)</p>
  4457. <p>t.penup()
  4458. t.goto(0, size)
  4459. t.setheading(hDeg)
  4460. t.pendown()
  4461. t.pencolor('springgreen')
  4462. t.forward(size/3)</p>
  4463. <p>t.penup()
  4464. t.goto(0, size)
  4465. t.setheading(mDeg)
  4466. t.pendown()
  4467. t.pencolor('lawngreen')
  4468. t.forward(size/2)
  4469. t.penup()
  4470. t.pencolor('cyan')
  4471. t.goto(0, size)
  4472. t.setheading(sDeg)
  4473. t.pendown()
  4474. t.forward(size-25)
  4475. t.penup()</p>
  4476. <p>size = 150
  4477. while True:
  4478. now = datetime.datetime.now()
  4479. klok(size,now.hour, now.minute, now.second)</p>
  4480. <p>for h in range(1, 13):
  4481. show(h,size)
  4482. time.sleep(10)
  4483. ```</p>
  4484. <p><img alt="game-85-c.png" src="./screenshots/game-85-c.png" title="game 85-c screenshot" /></p>
  4485. <p>Just one rock that hits the zombies above you</p>
  4486. <p>```
  4487. import pgzrun
  4488. import random</p>
  4489. <p>HEIGHT = 200
  4490. WIDTH = 200</p>
  4491. <p>game_over = False</p>
  4492. <p>elf = Actor("c1")
  4493. elf.x = WIDTH/2
  4494. elf.y = HEIGHT-20
  4495. rock = Actor("rock")
  4496. rock.x = elf.x + 10
  4497. rock.y = elf.y - 20</p>
  4498. <p>flowers = []</p>
  4499. <p>def add_one_row():
  4500. lastY = 0
  4501. if len(flowers) &gt; 0:
  4502. f = flowers[len(flowers)-1]
  4503. lastY = f.y</p>
  4504. <pre><code>for i in range(20, WIDTH-10, 20):
  4505. f = Actor("flower")
  4506. f.x = i
  4507. f.y = lastY + 10
  4508. flowers.append(f)
  4509. </code></pre>
  4510. <p>def on_key_down(key):
  4511. speed = 10
  4512. if key == keys.LEFT:
  4513. elf.x -= speed
  4514. if key == keys.RIGHT:
  4515. elf.x += speed
  4516. if key == keys.UP:
  4517. elf.y -= speed
  4518. if key == keys.DOWN:
  4519. elf.y += speed</p>
  4520. <p>def update():
  4521. global game_over
  4522. hit = []
  4523. for f in flowers:
  4524. if rock.colliderect(f) and random.randint(0,10) &gt; 7:
  4525. hit.append(f)</p>
  4526. <pre><code>for h in hit:
  4527. flowers.remove(h)
  4528. rock.x -= 1
  4529. if rock.x &lt; elf.x - 10:
  4530. rock.x = elf.x + 10
  4531. rock.y = elf.y - 20
  4532. </code></pre>
  4533. <p>def draw():
  4534. screen.fill('black')
  4535. elf.draw()
  4536. rock.draw()
  4537. for f in flowers:
  4538. f.draw()</p>
  4539. <p>add_one_row()
  4540. clock.schedule_interval(add_one_row, 5)</p>
  4541. <p>pgzrun.go()
  4542. ```</p>
  4543. <p><img alt="day-85.jpg" src="./reading/day-85.jpg" title="day 85 reading" /></p>
  4544. <h2>[DAY-86] Lists</h2>
  4545. <p><img alt="game-86.png" src="./screenshots/game-86.png" title="game 86 screenshot" /></p>
  4546. <p>SNAKE</p>
  4547. <p>```
  4548. import pgzrun
  4549. import random</p>
  4550. <p>HEIGHT = 200
  4551. WIDTH = 200</p>
  4552. <p>snake = Actor("c1")
  4553. snake.x = WIDTH/2
  4554. snake.y = HEIGHT-20</p>
  4555. <p>apple = Actor("flower")
  4556. apple.x = WIDTH/2
  4557. apple.y = HEIGHT/2</p>
  4558. <p>snake_size = 20
  4559. snake_speed = 1
  4560. steps = []
  4561. direction = "up"
  4562. step_size = 1
  4563. game_over = False
  4564. game_area = Rect(0,0,WIDTH,HEIGHT)
  4565. def on_key_down(key):
  4566. global direction</p>
  4567. <pre><code>if key == keys.LEFT:
  4568. direction = "left"
  4569. if key == keys.RIGHT:
  4570. direction = "right"
  4571. if key == keys.UP:
  4572. direction = "up"
  4573. if key == keys.DOWN:
  4574. direction = "down"
  4575. </code></pre>
  4576. <p>def update():
  4577. global snake_size, game_over, snake_speed, steps</p>
  4578. <pre><code>s = Actor("snake")
  4579. s.x = snake.x
  4580. s.y = snake.y
  4581. steps.append(s)
  4582. if len(steps) &gt; snake_size:
  4583. steps = steps[-snake_size:]
  4584. if direction == "left":
  4585. snake.x -= step_size
  4586. if direction == "right":
  4587. snake.x += step_size
  4588. if direction == "up":
  4589. snake.y -= step_size
  4590. if direction == "down":
  4591. snake.y += step_size
  4592. if snake.colliderect(apple):
  4593. apple.x = random.randint(0,WIDTH)
  4594. apple.y = random.randint(0,HEIGHT)
  4595. snake_size += step_size * 10
  4596. if not snake.colliderect(game_area):
  4597. game_over = True
  4598. </code></pre>
  4599. <p>def draw():
  4600. screen.fill('black')</p>
  4601. <pre><code>if game_over:
  4602. screen.draw.text("GAME OVER", color="white", topleft=(10,10))
  4603. else:
  4604. screen.draw.rect(game_area, (255,0,0))
  4605. for s in steps:
  4606. s.draw()
  4607. snake.draw()
  4608. apple.draw()
  4609. </code></pre>
  4610. <p>pgzrun.go()
  4611. ```</p>
  4612. <p>There are few key moments to emphasize, but the most important one is <code>steps = steps[-snake_size:]</code>.</p>
  4613. <p>Try this in IDLE:</p>
  4614. <p><code>x = [1,2,3,4]
  4615. print(x[-1])</code></p>
  4616. <p>It will print '4', so in python you can get elements from the back of the list, just as easily as the front, try <code>x[-2]</code>, now try to get multiple elements from a list, <code>y = x[0:2]</code>, it will make new list <code>[1,2]</code>, it is a bit like this code:</p>
  4617. <p><code>x = [1,2,3,4]
  4618. y = []
  4619. for i in range(0,2):
  4620. y.append(x[i])</code></p>
  4621. <p>Now you can also ask python to give you the first 2 elements by saying <code>x[0:2]</code> or you can ask it for the elements <em>after</em> the second one by doing <code>x[2:len(x)]</code>, you can omit 0 and <code>len(x)</code> so it is a bit shorter, <code>x[:2]</code> and <code>x[2:]</code>. Sometimes you want the last 2 elements, to do that just say <code>x[-2:len(x)]</code> or <code>x[-2:]</code> and that's how we are getting the last <code>snake_size</code> elements of the <code>steps</code> list.</p>
  4622. <p>Again, <code>x[-2:len(x)]</code> just means from -2 elements from the end if the list, until the end of the list. It looks scary though.</p>
  4623. <p>Similar to this code:</p>
  4624. <p><code>x = [1,2,3,4]
  4625. y = []
  4626. for i in range(len(x)-2,len(x)):
  4627. y.append(x[i])</code></p>
  4628. <h2>[DAY-87] Read/Write Files</h2>
  4629. <p>Its File time!</p>
  4630. <p>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 <code>f.write</code> 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</p>
  4631. <p>```
  4632. f = open("day-87.txt", "w")</p>
  4633. <p>while True:
  4634. a = input("what do you want to write: ")
  4635. if a == "quit":
  4636. break
  4637. f.write(a + "\n")</p>
  4638. <p>f.close()
  4639. ```</p>
  4640. <p>Now you can open day-87.txt with Notepad or some other text editor and see what you wrote.</p>
  4641. <p>It is important to remember this pattern</p>
  4642. <ol>
  4643. <li>Open</li>
  4644. <li>Read or Write</li>
  4645. <li>Read or Write</li>
  4646. <li>Read or Write</li>
  4647. <li>Read or Write</li>
  4648. <li>...</li>
  4649. <li>Close</li>
  4650. </ol>
  4651. <p>lets see how you read a file:</p>
  4652. <p><code>f = open("day-87.txt", "r")
  4653. data = f.read()
  4654. print(data)</code></p>
  4655. <p>Make a game that persists the player position.</p>
  4656. <p>```
  4657. import pgzrun
  4658. import random</p>
  4659. <p>HEIGHT = 200
  4660. WIDTH = 200</p>
  4661. <p>elf = Actor("c1")
  4662. elf.x = WIDTH/2
  4663. elf.y = HEIGHT-20</p>
  4664. <p>try:
  4665. x = open("day-87-x.txt", "r")
  4666. elf.x = float(x.read())
  4667. x.close()</p>
  4668. <pre><code>y = open("day-87-y.txt", "r")
  4669. elf.y = float(y.read())
  4670. y.close()
  4671. </code></pre>
  4672. <p>except IOError:
  4673. pass</p>
  4674. <p>def on_key_down(key):
  4675. speed = 10
  4676. if key == keys.LEFT:
  4677. elf.x -= speed
  4678. if key == keys.RIGHT:
  4679. elf.x += speed
  4680. if key == keys.UP:
  4681. elf.y -= speed
  4682. if key == keys.DOWN:
  4683. elf.y += speed</p>
  4684. <pre><code>if key == keys.S:
  4685. x = open("day-87-x.txt", "w")
  4686. x.write(str(elf.x))
  4687. x.close()
  4688. y = open("day-87-y.txt", "w")
  4689. y.write(str(elf.y))
  4690. y.close()
  4691. </code></pre>
  4692. <p>def draw():
  4693. screen.fill('black')
  4694. elf.draw()</p>
  4695. <p>pgzrun.go()
  4696. ```</p>
  4697. <p>open <code>day-87-x.txt</code> and <code>day-87-y.txt</code> to see the positions of X and Y of the elf after you press <code>S</code>.</p>
  4698. <p>One other patter you will see is:</p>
  4699. <p><code>try:
  4700. try to do something
  4701. except some error:
  4702. handle error</code></p>
  4703. <p>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.</p>
  4704. <p>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.</p>
  4705. <h2>[DAY-88] Flask</h2>
  4706. <p>Reading exercise, a lot of unfamiliar code</p>
  4707. <p>```
  4708. from flask import Flask, redirect, request,make_response
  4709. import random
  4710. app = Flask(<strong>name</strong>)</p>
  4711. <p>tokens = {}</p>
  4712. <p>@app.route('/')
  4713. def index():
  4714. token = request.cookies.get('token')
  4715. if token in tokens:
  4716. response = make_response("""
  4717. welcome to the secure section of the website,
  4718. <a href="/logout">click here to logout
  4719. """)
  4720. return response</p>
  4721. <pre><code>response = make_response("""
  4722. &lt;html&gt;
  4723. &lt;form action="/login" method="post"&gt;
  4724. user: &lt;input name="user"&gt;
  4725. pass: &lt;input type="password" name="pass"&gt;
  4726. &lt;input type="submit"&gt;
  4727. &lt;/form&gt;
  4728. &lt;/html&gt;
  4729. """)
  4730. return response
  4731. </code></pre>
  4732. <p>@app.route('/logout')
  4733. def logout():
  4734. token = request.cookies.get('token')
  4735. try:
  4736. del tokens[token]
  4737. except KeyError:
  4738. pass</p>
  4739. <pre><code>response = make_response(redirect('/'))
  4740. response.set_cookie('token', '')
  4741. return response
  4742. </code></pre>
  4743. <p>@app.route('/login', methods = ['POST'])
  4744. def login():
  4745. user = request.form['user']
  4746. password = request.form['pass']
  4747. if user == "admin" and password == "123":
  4748. token = str(random.randint(0,10000000))
  4749. tokens[token] = "admin"</p>
  4750. <pre><code> response = make_response(redirect('/'))
  4751. response.set_cookie('token', token)
  4752. return response
  4753. else:
  4754. return "access denied"
  4755. </code></pre>
  4756. <p>if <strong>name</strong> == "<strong>main</strong>":
  4757. app.run(host="127.0.0.1",port=8000,debug=True)
  4758. ```</p>
  4759. <p>start the script, see what it does, try to debug how <code>tokens</code> changes. Inspect your cookies, try to hack it, login from private mode and steal the cookie from the console.</p>
  4760. <h2>[DAY-89] Files; Strings; Lists</h2>
  4761. <p>super simple text editor</p>
  4762. <p><img alt="game-89.png" src="./screenshots/game-89.png" title="game 89 screenshot" /></p>
  4763. <p>Reading exercise, make a text editor, save with <code>ctrl+s</code> and quit with <code>ctrl+q</code></p>
  4764. <p>```
  4765. import pgzrun
  4766. import random</p>
  4767. <p>HEIGHT = 480
  4768. WIDTH = 640
  4769. filename = "example.py"
  4770. lines = [[]]
  4771. cursor_row = 0
  4772. cursor_col = 0</p>
  4773. <p>try:
  4774. x = open(filename, "r")
  4775. for c in x.read():
  4776. if c== '\n' or c == '\r':
  4777. lines.append([])
  4778. cursor_row += 1
  4779. cursor_col = 0
  4780. else:
  4781. lines[cursor_row].append(c)
  4782. cursor_col += 1</p>
  4783. <pre><code>x.close()
  4784. </code></pre>
  4785. <p>except IOError:
  4786. pass</p>
  4787. <p>def lines_to_string():
  4788. s = ''
  4789. for r in lines:
  4790. for c in r:
  4791. s += c
  4792. s += '\n'
  4793. return s</p>
  4794. <p>def on_key_down(key, mod, unicode):
  4795. global cursor_row, cursor_col</p>
  4796. <pre><code>if key == keys.Q and mod == keymods.LCTRL:
  4797. exit()
  4798. if key == keys.S and mod == keymods.LCTRL:
  4799. x = open(filename, "w")
  4800. s = lines_to_string()
  4801. x.write(s)
  4802. x.close()
  4803. elif key == keys.LEFT:
  4804. if cursor_col &gt; 0:
  4805. cursor_col -= 1
  4806. elif key == keys.RIGHT:
  4807. if cursor_col &lt; len(lines[cursor_row]):
  4808. cursor_col += 1
  4809. elif key == keys.UP:
  4810. if cursor_row &gt; 0:
  4811. cursor_row -= 1
  4812. if cursor_col &gt; len(lines[cursor_row]):
  4813. cursor_col = len(lines[cursor_row])
  4814. elif key == keys.DOWN:
  4815. if cursor_row &lt; len(lines) - 1:
  4816. cursor_row += 1
  4817. if cursor_col &gt; len(lines[cursor_row]):
  4818. cursor_col = len(lines[cursor_row])
  4819. elif key == keys.BACKSPACE:
  4820. if cursor_col == 0:
  4821. if cursor_row &gt;= 1:
  4822. row = lines.pop(cursor_row)
  4823. cursor_col = len(lines[cursor_row-1])
  4824. for c in row:
  4825. lines[cursor_row-1].append(c)
  4826. cursor_row -= 1
  4827. else:
  4828. row = lines[cursor_row]
  4829. if len(row) &gt; 0:
  4830. cursor_col -= 1
  4831. row.pop(cursor_col)
  4832. elif key == keys.RETURN:
  4833. # get the rest of the lines
  4834. left = []
  4835. right = []
  4836. if cursor_col &lt; len(lines[cursor_row]):
  4837. # split the line if we are pressing enter in the middle
  4838. row = lines[cursor_row]
  4839. left = row[:cursor_col]
  4840. right = row[cursor_col:]
  4841. if cursor_row &lt; len(lines):
  4842. lines[cursor_row] = left
  4843. cursor_col = 0
  4844. cursor_row += 1
  4845. lines.insert(cursor_row, right)
  4846. elif len(unicode) &gt; 0 and ord(unicode) &gt;= 20 and ord(unicode) &lt;= 125:
  4847. lines[cursor_row].insert(cursor_col, unicode)
  4848. cursor_col += 1
  4849. </code></pre>
  4850. <p>def draw():
  4851. screen.fill('black')
  4852. screen.draw.text(filename + ", " + str(cursor_row) + ":" + str(cursor_col), (0,0), fontsize=20,fontname="437-win", color="green")</p>
  4853. <pre><code>x = 0
  4854. y = 30
  4855. stepX = 10
  4856. stepY = 22
  4857. for (index_row, row) in enumerate(lines):
  4858. for (index_col, c) in enumerate(row):
  4859. screen.draw.text(c, (x,y), fontsize=20,fontname="437-win")
  4860. x += stepX
  4861. y += stepY
  4862. x = 0
  4863. cursorX = cursor_col * stepX
  4864. cursorY = 30 + (cursor_row * stepY)
  4865. screen.draw.rect(Rect((cursorX,cursorY,stepX,stepY)), (255,0,0))
  4866. </code></pre>
  4867. <p>pgzrun.go()
  4868. ```</p>
  4869. <p>write some python, and then run it with <code>python3 example.py</code></p>
  4870. <h2>[DAY-90] Strings</h2>
  4871. <p><img alt="game-90.png" src="./screenshots/game-90.png" title="game 90 screenshot" /></p>
  4872. <p>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?</p>
  4873. <p>```
  4874. import pgzrun</p>
  4875. <p>HEIGHT = 480
  4876. WIDTH = 640</p>
  4877. <p>text = ''</p>
  4878. <p>def on_key_down(key, mod, unicode):
  4879. global text</p>
  4880. <pre><code>if key == keys.Q and mod == keymods.LCTRL:
  4881. exit()
  4882. elif key == keys.BACKSPACE:
  4883. if len(text) &gt; 0:
  4884. text = text[:len(text)-1]
  4885. elif key == keys.RETURN:
  4886. text += '\n'
  4887. elif len(unicode) &gt; 0 and ord(unicode) &gt;= 20 and ord(unicode) &lt;= 125:
  4888. text += unicode
  4889. </code></pre>
  4890. <p>def draw():
  4891. screen.fill('black')
  4892. x = 0
  4893. y = 0
  4894. stepX = 10
  4895. stepY = 22</p>
  4896. <pre><code>for c in text:
  4897. if c == '\n':
  4898. y += stepY
  4899. x = 0
  4900. else:
  4901. screen.draw.text(c, (x,y), fontsize=20,fontname="437-win")
  4902. x += stepX
  4903. screen.draw.rect(Rect((x,y,stepX,stepY)), (255,0,0))
  4904. </code></pre>
  4905. <p>pgzrun.go()
  4906. ```</p>
  4907. <p>This is kind of what <code>screen.draw.text</code> does, you can of course just do <code>screen.draw.text(text, (0,0), fontsize=20,fontname="437-win")</code> 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.</p>
  4908. <h2>[DAY-91] Lists</h2>
  4909. <p>list your favorite games, and rank them</p>
  4910. <p>```
  4911. games = [
  4912. ["mario smash bros", 3],
  4913. ["mario party", 4],
  4914. ["super mario", 2]
  4915. ]</p>
  4916. <p>while True:
  4917. for game in games:
  4918. print(game[0])
  4919. what = input("which game are you interested in: ")
  4920. for game in games:
  4921. if what in game[0]:
  4922. print("i like " + game[0] + ", score: " + str(game[1]))
  4923. ```</p>
  4924. <p>print the lyrics of songs:</p>
  4925. <p>```
  4926. songs = [
  4927. ["wellerman", """There once was a ship that put to sea
  4928. The name of the ship was the Billy of Tea
  4929. The winds blew up, her bow dipped down
  4930. Oh blow, my bully boys, blow (huh)</p>
  4931. <p>Soon may the Wellerman come
  4932. To bring us sugar and tea and rum
  4933. One day, when the tonguing is done
  4934. We'll take our leave and go"""],
  4935. ]</p>
  4936. <p>while True:
  4937. what = input("which song are you interested in: ")
  4938. for song in songs:
  4939. if what in song[0]:
  4940. print('-' * 40)
  4941. print(song[1])
  4942. print('-' * 40)
  4943. ```</p>
  4944. <h2>[DAY-92] Command Line; Command Line Arguments; Files</h2>
  4945. <p>Today is command line day.</p>
  4946. <blockquote>
  4947. <p>First quickly go back to the start and read about files and folders (directories).</p>
  4948. </blockquote>
  4949. <p>The same way functions can get parameters, your program can get parameters as well, try this:</p>
  4950. <p><code>import sys
  4951. print(sys.argv)</code></p>
  4952. <p>save it as <code>a.py</code> and then run <code>python3 a.py hello those are paremeters</code> from the Terminal app, you will see <code>['a.py', 'hello', 'those', 'are', 'paremeters']</code>, sys.argv[0] is the name of the program, and then the parameters you gave it.</p>
  4953. <p>Now lets make few handy programs to help us with our command line:</p>
  4954. <hr />
  4955. <p>xcat.py</p>
  4956. <p>```
  4957. import sys</p>
  4958. <p>x = open(sys.argv[1], "r")
  4959. data = x.read()
  4960. print(data)
  4961. ```</p>
  4962. <hr />
  4963. <p>xls.py
  4964. ```
  4965. import os
  4966. import sys</p>
  4967. <p>files = os.listdir(sys.argv[1])
  4968. files.sort()</p>
  4969. <p>for f in files:
  4970. if os.path.isdir(f):
  4971. print(f + "/")
  4972. else:
  4973. print(f)
  4974. ```</p>
  4975. <hr />
  4976. <p>xed.py</p>
  4977. <p>```
  4978. import sys
  4979. import os</p>
  4980. <p>text = ''</p>
  4981. <p>filename = sys.argv[1]</p>
  4982. <p>try:
  4983. f = open(filename, "r")
  4984. text = f.read()
  4985. f.close()
  4986. except IOError:
  4987. pass</p>
  4988. <p>while True:
  4989. what = input("&gt; ")
  4990. if what == '?':
  4991. print("""
  4992. * ? - help
  4993. * p - print
  4994. * s - save
  4995. * d [n] - delete last N lines
  4996. * a text - append text to the end
  4997. """)
  4998. elif what == 'q':
  4999. sys.exit(0)
  5000. elif what == 'p':
  5001. print(text, end = '')
  5002. elif what == 's':
  5003. f = open(filename, "w")
  5004. f.write(text)
  5005. f.close()
  5006. elif what[0] == 'a' and what[1] == ' ':
  5007. text += what[2:] + '\n'
  5008. elif what[0] == 'd':
  5009. lines = text.split('\n')</p>
  5010. <pre><code> n = 1
  5011. if len(what) &gt; 2:
  5012. n = int(what[2:])
  5013. for i in range(0, n):
  5014. lines.pop()
  5015. text = "\n".join(lines)
  5016. else:
  5017. print("* use ? for help")
  5018. </code></pre>
  5019. <p>```</p>
  5020. <hr />
  5021. <p>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 :)</p>
  5022. <p>try this:</p>
  5023. <p>```
  5024. $ python3 xed,py example.py</p>
  5025. <blockquote>
  5026. <p>a for i in range(100)
  5027. a print(i)
  5028. p
  5029. s</p>
  5030. </blockquote>
  5031. <p>$ python3 xls.py .
  5032. $ python3 xcat.py example.py
  5033. $ python3 example.py
  5034. ```</p>
  5035. <h2>[DAY-93] PyDoc</h2>
  5036. <p>Reading docs. type this in the terminal: <code>pydoc3 open</code> <code>pydoc3 input</code> <code>pydoc3 print</code> and <code>pydoc3 pgzero.actor</code>.</p>
  5037. <p>Lets take <code>open</code> as an example.</p>
  5038. <p>```
  5039. Help on built-in function open in module io:</p>
  5040. <p>open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
  5041. Open file and return a stream. Raise OSError upon failure.</p>
  5042. <pre><code>file is either a text or byte string giving the name (and the path
  5043. if the file isn't in the current working directory) of the file to
  5044. be opened or an integer file descriptor of the file to be
  5045. wrapped. (If a file descriptor is given, it is closed when the
  5046. returned I/O object is closed, unless closefd is set to False.)
  5047. mode is an optional string that specifies the mode in which the file
  5048. is opened. It defaults to 'r' which means open for reading in text
  5049. mode. Other common values are 'w' for writing (truncating the file if
  5050. it already exists), 'x' for creating and writing to a new file, and
  5051. 'a' for appending (which on some Unix systems, means that all writes
  5052. append to the end of the file regardless of the current seek position).
  5053. In text mode, if encoding is not specified the encoding used is platform
  5054. dependent: locale.getpreferredencoding(False) is called to get the
  5055. current locale encoding. (For reading and writing raw bytes use binary
  5056. mode and leave encoding unspecified.) The available modes are:
  5057. ========= ===============================================================
  5058. Character Meaning
  5059. --------- ---------------------------------------------------------------
  5060. 'r' open for reading (default)
  5061. 'w' open for writing, truncating the file first
  5062. 'x' create a new file and open it for writing
  5063. 'a' open for writing, appending to the end of the file if it exists
  5064. 'b' binary mode
  5065. 't' text mode (default)
  5066. '+' open a disk file for updating (reading and writing)
  5067. 'U' universal newline mode (deprecated)
  5068. ========= ===============================================================
  5069. The default mode is 'rt' (open for reading text). For binary random
  5070. access, the mode 'w+b' opens and truncates the file to 0 bytes, while
  5071. 'r+b' opens the file without truncation. The 'x' mode implies 'w' and
  5072. raises an `FileExistsError` if the file already exists.
  5073. Python distinguishes between files opened in binary and text modes,
  5074. even when the underlying operating system doesn't. Files opened in
  5075. binary mode (appending 'b' to the mode argument) return contents as
  5076. bytes objects without any decoding. In text mode (the default, or when
  5077. 't' is appended to the mode argument), the contents of the file are
  5078. returned as strings, the bytes having been first decoded using a
  5079. platform-dependent encoding or using the specified encoding if given.
  5080. 'U' mode is deprecated and will raise an exception in future versions
  5081. of Python. It has no effect in Python 3. Use newline to control
  5082. universal newlines mode.
  5083. buffering is an optional integer used to set the buffering policy.
  5084. Pass 0 to switch buffering off (only allowed in binary mode), 1 to select
  5085. line buffering (only usable in text mode), and an integer &gt; 1 to indicate
  5086. the size of a fixed-size chunk buffer. When no buffering argument is
  5087. given, the default buffering policy works as follows:
  5088. * Binary files are buffered in fixed-size chunks; the size of the buffer
  5089. is chosen using a heuristic trying to determine the underlying device's
  5090. "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`.
  5091. On many systems, the buffer will typically be 4096 or 8192 bytes long.
  5092. * "Interactive" text files (files for which isatty() returns True)
  5093. use line buffering. Other text files use the policy described above
  5094. for binary files.
  5095. encoding is the name of the encoding used to decode or encode the
  5096. file. This should only be used in text mode. The default encoding is
  5097. platform dependent, but any encoding supported by Python can be
  5098. passed. See the codecs module for the list of supported encodings.
  5099. errors is an optional string that specifies how encoding errors are to
  5100. be handled---this argument should not be used in binary mode. Pass
  5101. 'strict' to raise a ValueError exception if there is an encoding error
  5102. (the default of None has the same effect), or pass 'ignore' to ignore
  5103. errors. (Note that ignoring encoding errors can lead to data loss.)
  5104. See the documentation for codecs.register or run 'help(codecs.Codec)'
  5105. for a list of the permitted encoding error strings.
  5106. newline controls how universal newlines works (it only applies to text
  5107. mode). It can be None, '', '\n', '\r', and '\r\n'. It works as
  5108. follows:
  5109. * On input, if newline is None, universal newlines mode is
  5110. enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
  5111. these are translated into '\n' before being returned to the
  5112. caller. If it is '', universal newline mode is enabled, but line
  5113. endings are returned to the caller untranslated. If it has any of
  5114. the other legal values, input lines are only terminated by the given
  5115. string, and the line ending is returned to the caller untranslated.
  5116. * On output, if newline is None, any '\n' characters written are
  5117. translated to the system default line separator, os.linesep. If
  5118. newline is '' or '\n', no translation takes place. If newline is any
  5119. of the other legal values, any '\n' characters written are translated
  5120. to the given string.
  5121. If closefd is False, the underlying file descriptor will be kept open
  5122. when the file is closed. This does not work when a file name is given
  5123. and must be True in that case.
  5124. A custom opener can be used by passing a callable as *opener*. The
  5125. underlying file descriptor for the file object is then obtained by
  5126. calling *opener* with (*file*, *flags*). *opener* must return an open
  5127. file descriptor (passing os.open as *opener* results in functionality
  5128. similar to passing None).
  5129. open() returns a file object whose type depends on the mode, and
  5130. through which the standard file operations such as reading and writing
  5131. are performed. When open() is used to open a file in a text mode ('w',
  5132. 'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open
  5133. a file in a binary mode, the returned class varies: in read binary
  5134. mode, it returns a BufferedReader; in write binary and append binary
  5135. modes, it returns a BufferedWriter, and in read/write mode, it returns
  5136. a BufferedRandom.
  5137. It is also possible to use a string or bytearray as a file for both
  5138. reading and writing. For strings StringIO can be used like a file
  5139. opened in a text mode, and for bytes a BytesIO can be used like a file
  5140. opened in a binary mode.
  5141. </code></pre>
  5142. <p>```</p>
  5143. <p>It's a lot! But I guarantee you its the best way to learn about something, the people who wrote the <code>open</code> 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.</p>
  5144. <p>The other way find things is to google <code>python3 open</code> 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'</p>
  5145. <p>You can also do pydoc3 on modules, e.g. <code>pydoc3 sys</code> or <code>pydoc3 sys.argv</code>. Sometimes it might look a bit intimidating, but its usually much better than using google.</p>
  5146. <p>Try also <code>pydoc3 pgzero</code>, <code>pydoc3 pygame</code> and <code>pydoc3 pygame.Rect</code>. There is also a way to find documentation for the command line programs, try <code>man python3</code>, <code>man</code> from <code>manual</code>, if you want to search for something use <code>man -k something</code> for example <code>man -k python</code>.</p>
  5147. <h2>[DAY-94] Editors - Ed/Nano/Vi/Emacs..</h2>
  5148. <p>Command line editors:</p>
  5149. <ul>
  5150. <li>nano, pico</li>
  5151. </ul>
  5152. <p>super easy to use, press ctrl+x to exit, ctrl+k to cut text, and ctrl+u to uncut (paste)</p>
  5153. <ul>
  5154. <li>vi</li>
  5155. </ul>
  5156. <p>Type <code>vimtutor</code> to see how it works, to quit use <code>ESC</code> then type <code>:</code> and then <code>q!</code></p>
  5157. <ul>
  5158. <li>emacs</li>
  5159. </ul>
  5160. <p>emacs is my favorite editor, in in fact I am writing this book using it. type <code>ctrl+x ctrl+c</code> to quit, and <code>ctrl+x ctrl+s</code> to save.</p>
  5161. <ul>
  5162. <li>ed</li>
  5163. </ul>
  5164. <p>ed is super old editor, it is somewhat similar to xed.py that you wrote, its called 'line editor'. To quit use <code>q</code> or <code>Q</code> if you want to quit without saving, to print the contents of the file use <code>1,$n</code> which prints the lines from 1 to $, or you can print specific line with <code>1n</code> or <code>2n</code> where 1 or 2 is the linue number.</p>
  5165. <p>try this:</p>
  5166. <p><code>$ ed zzz
  5167. a
  5168. for i in range(10);
  5169. print(i)
  5170. .
  5171. w
  5172. 31
  5173. 1,$n
  5174. 1 for i in range(10);
  5175. 2 print(i)
  5176. q</code></p>
  5177. <p><code>a</code> will append to the file, <code>w</code> will save the file, <code>1,$n</code> will print the contents, and <code>q</code> will quit. Commands like <code>a,i,d</code> (append,insert,delete) take line numbers as parameters as well. Use <code>man ed</code> to see the docs.</p>
  5178. <p>I don't think anyone uses <code>ed</code> anymore, at least not as a text editor, but sometimes its handy to know how to use it.</p>
  5179. <hr />
  5180. <p>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.</p>
  5181. <p>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.</p>
  5182. <h2>[DAY-95] Memory; Virtual Computer; Instructions; Strings; Lists</h2>
  5183. <p>Memory.</p>
  5184. <p>Lets make a huuuuuge list.</p>
  5185. <p>```
  5186. memory = []
  5187. for i in range(1000000):
  5188. memory.append(0)</p>
  5189. <p>```</p>
  5190. <p>Our memory looks like this:</p>
  5191. <p><code>[0,0,0,..............0,0,0,0....0,0,0,0,0]</code></p>
  5192. <p>Now we can make variables in this list of numbers, by addressing each variable with its index in the list, for exampke <code>x</code> can be at index 1000 and <code>y</code> can be at position 1001.</p>
  5193. <p>```
  5194. def add(a_address,b_address):
  5195. return memory[a_address] + memory[b_address]</p>
  5196. <p>x_address = 1000
  5197. y_address = 1001
  5198. memory[x_address] = 5
  5199. memory[y_address] = 10</p>
  5200. <p>r = add(x_address,y_address)</p>
  5201. <p>print(r)
  5202. ```</p>
  5203. <p>This is cheating though, because python uses its own memory to store the result from x and y, lets fix that:</p>
  5204. <p>```
  5205. def add(a_address,b_address,r_address):
  5206. memory[r_address] = memory[a_address] + memory[b_address]</p>
  5207. <p>x_address = 1000
  5208. memory[x_address] = 5</p>
  5209. <p>y_address = 1001
  5210. memory[y_address] = 10</p>
  5211. <p>r_address = 1002
  5212. add(x_address,y_address,r_address)</p>
  5213. <p>print(memory[r_address])
  5214. ```</p>
  5215. <p>This is how our memory looks like
  5216. ```
  5217. [....0,0,0,5,10,15,0,...]
  5218. ^ ^ ^
  5219. | | |
  5220. x | |
  5221. y |
  5222. r</p>
  5223. <p>x at index 1000
  5224. y at index 1001
  5225. r at index 1002
  5226. ```</p>
  5227. <p>The code above translates roughly to:</p>
  5228. <p><code>x = 5
  5229. y = 10
  5230. r = x + y
  5231. print(r)</code></p>
  5232. <p>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.
  5233. ```</p>
  5234. <p>h_address = 2000
  5235. memory[h_address] = 5
  5236. memory[h_address+1] = ord('h')
  5237. memory[h_address+2] = ord('e')
  5238. memory[h_address+3] = ord('l')
  5239. memory[h_address+4] = ord('l')
  5240. memory[h_address+5] = ord('o')</p>
  5241. <p>def xprint(address):
  5242. l = memory[address]
  5243. for i in range(l):
  5244. # +1 is because of the length
  5245. c = memory[address + 1 + i]
  5246. print(chr(c), end = '')
  5247. print('')
  5248. ```</p>
  5249. <p>Strings with without length. We can also just say 'the string ends with 0' so start reading and stop when you see 0.</p>
  5250. <p>```</p>
  5251. <p>n_address = 3000
  5252. memory[n_address+0] = ord('h')
  5253. memory[n_address+1] = ord('e')
  5254. memory[n_address+2] = ord('l')
  5255. memory[n_address+3] = ord('l')
  5256. memory[n_address+4] = ord('o')</p>
  5257. <p>def nprint(address):
  5258. for addr in range(address, len(memory)):
  5259. c = memory[addr]
  5260. if c == 0:
  5261. break
  5262. print(chr(c), end = '')
  5263. print('')</p>
  5264. <p>nprint(n_address)</p>
  5265. <p>```</p>
  5266. <p>Now lets add a funciton to add two strings:</p>
  5267. <p>```</p>
  5268. <p>a_address = 4000
  5269. memory[a_address] = 5
  5270. memory[a_address+1] = ord('h')
  5271. memory[a_address+2] = ord('e')
  5272. memory[a_address+3] = ord('l')
  5273. memory[a_address+4] = ord('l')
  5274. memory[a_address+5] = ord('o')</p>
  5275. <p>b_address = 4006
  5276. memory[b_address] = 5
  5277. memory[b_address+1] = ord('w')
  5278. memory[b_address+2] = ord('o')
  5279. memory[b_address+3] = ord('r')
  5280. memory[b_address+4] = ord('l')
  5281. memory[b_address+5] = ord('d')</p>
  5282. <p>c_address = 7000</p>
  5283. <p>def xadd(a,b,dst):
  5284. len_a = memory[a]
  5285. len_b = memory[b]
  5286. memory[dst] = len_a + len_b
  5287. for i in range(len_a):
  5288. c = memory[a + 1 + i]
  5289. memory[dst + 1 + i] = c</p>
  5290. <pre><code>for i in range(len_b):
  5291. c = memory[b + 1 +i]
  5292. memory[dst + 1 + len_a + i] = c
  5293. </code></pre>
  5294. <p>xadd(a_address, b_address, c_address)
  5295. xprint(c_address)
  5296. ```</p>
  5297. <p>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 <em>know</em> 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.</p>
  5298. <p>```
  5299. i_address = 3996
  5300. memory[i_address] = 9999</p>
  5301. <p>[....9999,0,0,0,5,104,101,108,108,111,5,119,111,114,108,100....]
  5302. ^ ^ ^
  5303. i this is a this is b
  5304. idx: 3996 idx: 4000 idx: 4006</p>
  5305. <p>```</p>
  5306. <p>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. <em>WHERE</em> to read and write.</p>
  5307. <p>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:</p>
  5308. <p>```
  5309. world</p>
  5310. <ul>
  5311. <li>reduce the length to 4</li>
  5312. <li>move r to the left</li>
  5313. <li>move l to the left</li>
  5314. <li>move d to the left</li>
  5315. </ul>
  5316. <p>```</p>
  5317. <p>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.</p>
  5318. <p>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.</p>
  5319. <p>There are different way to store collections of things, Linked Lists are one example</p>
  5320. <p>```</p>
  5321. <p>[0, value] # w
  5322. |
  5323. [next_address, value] # o
  5324. |
  5325. [next_address, value] # r
  5326. |
  5327. [next_address, value] # l
  5328. |
  5329. [0, value ] # d
  5330. ```</p>
  5331. <p>Arrays and Lists are very differentm arrays are <em>always</em> 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.</p>
  5332. <p>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 <code>o</code> point to <code>l</code>, and then <code>r</code> will disappear.</p>
  5333. <p>Our format will be (next element from the list, value)</p>
  5334. <p>```
  5335. memory[20000] = 30000
  5336. memory[20001] = 1</p>
  5337. <p>memory[30000] = 30500
  5338. memory[30001] = 2</p>
  5339. <p>memory[30500] = 30605
  5340. memory[30501] = 3</p>
  5341. <p>memory[30605] = 0
  5342. memory[30606] = 4
  5343. ```</p>
  5344. <p>the memory now looks like this:</p>
  5345. <p><code>[ ....30000, 1, .... 30500, 2, .... 30605, 3, .... 0, 4, ...]
  5346. ^ ^ ^ ^
  5347. first second third forth element</code></p>
  5348. <p>This is an example function that will print all the values in a linked list, following the links.</p>
  5349. <p>```
  5350. def lprint(start_address):
  5351. done = False
  5352. while not done:
  5353. # check if this is the last element of the list
  5354. done = memory[start_address] == 0</p>
  5355. <pre><code> # print the value at address + 1
  5356. print(memory[start_address+1])
  5357. # go to the next element from the list
  5358. start_address = memory[start_address]
  5359. </code></pre>
  5360. <p>lprint(20000)
  5361. ```</p>
  5362. <p>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.</p>
  5363. <p>Check this out:
  5364. ```
  5365. memory[20000] = 30000
  5366. memory[20001] = 1</p>
  5367. <p>memory[30000] = 20000
  5368. memory[30001] = 2</p>
  5369. <p>lprint(20000)
  5370. ```</p>
  5371. <p>Inifinite loop! How cool is that!</p>
  5372. <p><code>1
  5373. 2
  5374. 1
  5375. 2
  5376. 1
  5377. 2
  5378. 1
  5379. 2
  5380. 1
  5381. 2
  5382. 1
  5383. 2
  5384. 1
  5385. 2
  5386. 1
  5387. 2</code></p>
  5388. <p>Lets make a computer, it needs Memory and CPU, the CPU will read instructions from memory and produce results back in memory.</p>
  5389. <p>```
  5390. memory = []
  5391. for i in range(1000000):
  5392. memory.append(0)</p>
  5393. <p>memory[1000] = 5 # a
  5394. memory[1001] = 10 # b
  5395. memory[1002] = 0 # result</p>
  5396. <h1>lets multiply a * b</h1>
  5397. <h1>the code looks like this</h1>
  5398. <h1>counter = b</h1>
  5399. <h1>while counter &gt; 0:</h1>
  5400. <h1>r = r + a</h1>
  5401. <h1>counter -= 1</h1>
  5402. <h1>print(r)</h1>
  5403. <h1>counter = b</h1>
  5404. <p>memory[1003] = memory[1001]</p>
  5405. <h1>jump to position 10 if counter is 0</h1>
  5406. <p>memory[0] = 4
  5407. memory[1] = 1003
  5408. memory[2] = 13</p>
  5409. <h1>r = r + a</h1>
  5410. <p>memory[3] = 1
  5411. memory[4] = 1002
  5412. memory[5] = 1000
  5413. memory[6] = 1002</p>
  5414. <h1>since our add operation adds two things in memory, we</h1>
  5415. <h1>need to store the value -1 somewhere to subtract it from the counter</h1>
  5416. <h1></h1>
  5417. <h1>counter -= 1</h1>
  5418. <p>memory[9999] = -1
  5419. memory[7] = 1
  5420. memory[8] = 1003
  5421. memory[9] = 9999
  5422. memory[10] = 1003</p>
  5423. <h1>go back to the if counter == 0 instruction</h1>
  5424. <p>memory[11] = 5
  5425. memory[12] = 0</p>
  5426. <h1>print(r)</h1>
  5427. <p>memory[13] = 3
  5428. memory[14] = 1002</p>
  5429. <h1>stop the program</h1>
  5430. <p>memory[15] = 0</p>
  5431. <p>position = 0
  5432. while True:
  5433. instruction = memory[position]
  5434. print('instruction',instruction, 'position',position)
  5435. # quit if instruction is 0
  5436. if instruction == 0:
  5437. break</p>
  5438. <pre><code># add position+1 and position+2 and write result in position+3
  5439. elif instruction == 1:
  5440. a_address = memory[position+1]
  5441. b_address = memory[position+2]
  5442. r_address = memory[position+3]
  5443. memory[r_address] = memory[a_address] + memory[b_address]
  5444. position += 4
  5445. # print position + 1
  5446. elif instruction == 3:
  5447. address = memory[position+1]
  5448. print(memory[address])
  5449. position+=2
  5450. # if memory[position+1] is 0 jump to positon+2, else continue to position+3
  5451. elif instruction == 4:
  5452. address = memory[position+1]
  5453. if memory[address] == 0:
  5454. position = memory[position+2]
  5455. else:
  5456. position += 3
  5457. # jump to value of position+1
  5458. elif instruction == 5:
  5459. position = memory[position+1]
  5460. </code></pre>
  5461. <p>```</p>
  5462. <p>start the computer and see the result!</p>
  5463. <p><code>('instruction', 4, 'position', 0)
  5464. ('instruction', 1, 'position', 3)
  5465. ('instruction', 1, 'position', 7)
  5466. ('instruction', 5, 'position', 11)
  5467. ('instruction', 4, 'position', 0)
  5468. ('instruction', 1, 'position', 3)
  5469. ('instruction', 1, 'position', 7)
  5470. ('instruction', 5, 'position', 11)
  5471. ('instruction', 4, 'position', 0)
  5472. ('instruction', 1, 'position', 3)
  5473. ('instruction', 1, 'position', 7)
  5474. ('instruction', 5, 'position', 11)
  5475. ('instruction', 4, 'position', 0)
  5476. ('instruction', 1, 'position', 3)
  5477. ('instruction', 1, 'position', 7)
  5478. ('instruction', 5, 'position', 11)
  5479. ('instruction', 4, 'position', 0)
  5480. ('instruction', 1, 'position', 3)
  5481. ('instruction', 1, 'position', 7)
  5482. ('instruction', 5, 'position', 11)
  5483. ('instruction', 4, 'position', 0)
  5484. ('instruction', 1, 'position', 3)
  5485. ('instruction', 1, 'position', 7)
  5486. ('instruction', 5, 'position', 11)
  5487. ('instruction', 4, 'position', 0)
  5488. ('instruction', 1, 'position', 3)
  5489. ('instruction', 1, 'position', 7)
  5490. ('instruction', 5, 'position', 11)
  5491. ('instruction', 4, 'position', 0)
  5492. ('instruction', 1, 'position', 3)
  5493. ('instruction', 1, 'position', 7)
  5494. ('instruction', 5, 'position', 11)
  5495. ('instruction', 4, 'position', 0)
  5496. ('instruction', 1, 'position', 3)
  5497. ('instruction', 1, 'position', 7)
  5498. ('instruction', 5, 'position', 11)
  5499. ('instruction', 4, 'position', 0)
  5500. ('instruction', 1, 'position', 3)
  5501. ('instruction', 1, 'position', 7)
  5502. ('instruction', 5, 'position', 11)
  5503. ('instruction', 4, 'position', 0)
  5504. ('instruction', 3, 'position', 13)
  5505. 50
  5506. ('instruction', 0, 'position', 15)</code></p>
  5507. <p>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.</p>
  5508. <p>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</p>
  5509. <p>```
  5510. ...</p>
  5511. <h1>instructions</h1>
  5512. <p>HALT = 0
  5513. ADD = 1
  5514. PRINT = 3
  5515. JUMP_IF_ZERO = 4
  5516. JUMP = 5</p>
  5517. <h1>variabnles</h1>
  5518. <p>A = 1000
  5519. B = 1001
  5520. R = 1002
  5521. MINUS_1 = 9999
  5522. COUNTER = 1003</p>
  5523. <h1>program</h1>
  5524. <p>memory[A] = 5 # A = 5
  5525. memory[B] = 10 # B = 5
  5526. memory[R] = 0 # R = 0
  5527. memory[COUNTER] = memory[B] # COUNTER = B</p>
  5528. <h1>jump to position 10 if counter is 0</h1>
  5529. <p>memory[0] = JUMP_IF_ZERO
  5530. memory[1] = COUNTER
  5531. memory[2] = 13</p>
  5532. <h1>r = r + a</h1>
  5533. <p>memory[3] = ADD
  5534. memory[4] = R
  5535. memory[5] = A
  5536. memory[6] = R</p>
  5537. <h1>counter -= 1</h1>
  5538. <p>memory[MINUS_1] = -1</p>
  5539. <h1>counter = counter + minus_1</h1>
  5540. <p>memory[7] = ADD
  5541. memory[8] = COUNTER
  5542. memory[9] = MINUS_1
  5543. memory[10] = COUNTER</p>
  5544. <h1>go back to the if counter == 0 instruction</h1>
  5545. <p>memory[11] = JUMP
  5546. memory[12] = 0</p>
  5547. <h1>print(r)</h1>
  5548. <p>memory[13] = PRINT
  5549. memory[14] = R</p>
  5550. <h1>stop the program</h1>
  5551. <p>memory[15] = HALT
  5552. ...</p>
  5553. <p>```</p>
  5554. <p>The whole program is actually quite small:</p>
  5555. <p><code>[4, 1003, 13, 1, 1000, 1002, 1002, 1, 1003, 9999, 1003, 5, 0, 3, 1002, 0]
  5556. ^ ^
  5557. jump to 13 if memory[1003] is zero jump to 0</code></p>
  5558. <h2>[DAY-95] Memory; Machine Code; Virtual Computer</h2>
  5559. <p>It will be super nice if our multiply program can be used from multiple places from a bigger program:</p>
  5560. <p><code>...
  5561. r = multiply(5, 10)
  5562. print(r)
  5563. ...</code></p>
  5564. <p>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.</p>
  5565. <p>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. <code>[5, 10, ZZZ]</code> 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.</p>
  5566. <p>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.</p>
  5567. <p>If I push 1,2,3 then if i pop 3 times I will print 3 2 1</p>
  5568. <p>```
  5569. stack = [1,2,3]</p>
  5570. <p>print(stack.pop())
  5571. print(stack.pop())
  5572. print(stack.pop())
  5573. ```</p>
  5574. <p>Here is our updated program, and computer:</p>
  5575. <p>```
  5576. memory = []
  5577. for i in range(1000000):
  5578. memory.append(0)</p>
  5579. <p>HALT = 0
  5580. ADD = 1
  5581. PRINT = 3
  5582. JUMP_IF_ZERO = 4
  5583. JUMP = 5
  5584. PUSH = 8
  5585. POP = 9
  5586. SET = 10</p>
  5587. <p>JUMPV = 11 # same as jump, but jumps to the
  5588. # value of the address instead of the address itself
  5589. # so jumpv 9, will jump to the value of memory[9]</p>
  5590. <p>PUSHV = 12 # same as jumpv but for push</p>
  5591. <h1>just used for debug</h1>
  5592. <p>instruction_lookup = dict([
  5593. (HALT , 'HALT'),
  5594. (ADD , 'ADD'),
  5595. (PRINT , 'PRINT'),
  5596. (JUMP_IF_ZERO , 'JUMP_IF_ZERO'),
  5597. (JUMP , 'JUMP'),
  5598. (PUSH , 'PUSH'),
  5599. (POP , 'POP'),
  5600. (SET , 'SET'),
  5601. (PUSHV , 'PUSHV'),
  5602. (JUMPV , 'JUMPV')
  5603. ])</p>
  5604. <pre><code> # pushv 9, will push memory[9] instead of 9
  5605. </code></pre>
  5606. <h1>constants addressess</h1>
  5607. <h1>there is no such thing as constants though, we just think of them as such</h1>
  5608. <p>MINUS_1 = 9999</p>
  5609. <h1>set "global" variable MINUS_1 to -1</h1>
  5610. <p>memory[MINUS_1] = -1 # minus_1 = -1</p>
  5611. <h1>MAIN FUNCTION</h1>
  5612. <h1>main function has only one variable, the MULTIPLY_RESULT</h1>
  5613. <p>MULTIPLY_RESULT = 1000</p>
  5614. <h1>MULTIPLY_RESULT = multiply (5, 10)</h1>
  5615. <p>memory[0] = PUSH # | |
  5616. memory[1] = 5 # ^ |
  5617. memory[2] = PUSH # |
  5618. memory[3] = 10 # &gt;--+
  5619. memory[4] = PUSH # &gt;-------------+
  5620. memory[5] = 8 # | after the function is called
  5621. memory[6] = JUMP # | jump to get the value
  5622. memory[7] = 198 # | from the stack
  5623. memory[8] = POP # &lt;-------------+
  5624. memory[9] = MULTIPLY_RESULT #
  5625. memory[10] = PRINT
  5626. memory[11] = MULTIPLY_RESULT</p>
  5627. <h6># MULTIPLY FUNCTION</h6>
  5628. <h1>get the value of A</h1>
  5629. <p>A = 9000
  5630. B = 9001
  5631. COUNTER = 9003
  5632. R = 9004
  5633. BACK_TO_ADDRESS = 9005</p>
  5634. <h1>get the value for where to return to</h1>
  5635. <p>memory[198] = POP
  5636. memory[199] = BACK_TO_ADDRESS</p>
  5637. <h1>get the value for A</h1>
  5638. <p>memory[200] = POP
  5639. memory[201] = A</p>
  5640. <h1>get the value for B</h1>
  5641. <p>memory[202] = POP
  5642. memory[203] = B</p>
  5643. <h1>COUNTER = B (which is counter = 0 ; counter = counter + b)</h1>
  5644. <h1>COUNTER = 0</h1>
  5645. <p>memory[204] = SET
  5646. memory[205] = COUNTER
  5647. memory[206] = 0</p>
  5648. <h1>COUNTER = COUNTER + B</h1>
  5649. <p>memory[207] = ADD
  5650. memory[208] = COUNTER
  5651. memory[209] = B
  5652. memory[210] = COUNTER</p>
  5653. <h1>the actual loop</h1>
  5654. <p>memory[211] = JUMP_IF_ZERO
  5655. memory[212] = COUNTER
  5656. memory[213] = 224</p>
  5657. <h1>r = r + a</h1>
  5658. <p>memory[214] = ADD
  5659. memory[215] = A
  5660. memory[216] = R
  5661. memory[217] = R</p>
  5662. <h1>since our add operation adds two things in memory, we</h1>
  5663. <h1>need to store the value -1 somewhere to subtract it from the counter</h1>
  5664. <h1></h1>
  5665. <h1>counter -= 1</h1>
  5666. <p>memory[218] = ADD
  5667. memory[219] = COUNTER
  5668. memory[220] = MINUS_1
  5669. memory[221] = COUNTER</p>
  5670. <h1>go back to the if counter == 0 instruction</h1>
  5671. <p>memory[222] = JUMP
  5672. memory[223] = 211</p>
  5673. <h1>return(r)</h1>
  5674. <p>memory[224] = PUSHV
  5675. memory[225] = R</p>
  5676. <p>memory[226] = JUMPV
  5677. memory[227] = BACK_TO_ADDRESS</p>
  5678. <h1>start the computer from position 80, we will use positions up-to 80 for our function call stack</h1>
  5679. <p>position = 0
  5680. stack = []
  5681. while True:
  5682. instruction = memory[position]</p>
  5683. <pre><code>print(instruction_lookup[instruction], 'position',position, 'stack', stack)
  5684. # quit if instruction is 0
  5685. if instruction == HALT:
  5686. break
  5687. # add position+1 and position+2 and write result in position+3
  5688. elif instruction == ADD:
  5689. a_address = memory[position+1]
  5690. b_address = memory[position+2]
  5691. r_address = memory[position+3]
  5692. memory[r_address] = memory[a_address] + memory[b_address]
  5693. position += 4
  5694. # print position + 1
  5695. elif instruction == PRINT:
  5696. address = memory[position+1]
  5697. print(memory[address])
  5698. position+=2
  5699. # if memory[position+1] is 0 jump to positon+2, else continue to position+3
  5700. elif instruction == JUMP_IF_ZERO:
  5701. address = memory[position+1]
  5702. if memory[address] == 0:
  5703. position = memory[position+2]
  5704. else:
  5705. position += 3
  5706. # jump to value of position+1
  5707. elif instruction == JUMP:
  5708. position = memory[position+1]
  5709. elif instruction == JUMPV:
  5710. position = memory[memory[position+1]]
  5711. elif instruction == PUSH:
  5712. stack.append(memory[position+1])
  5713. position += 2
  5714. elif instruction == PUSHV:
  5715. stack.append(memory[memory[position+1]])
  5716. position += 2
  5717. elif instruction == POP:
  5718. memory[memory[position+1]] = stack.pop()
  5719. position += 2
  5720. elif instruction == SET:
  5721. memory[position+1] = memory[position+2]
  5722. position += 3
  5723. </code></pre>
  5724. <p>```</p>
  5725. <p>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 <code>memory[[memory[100000]] = value, memory[100000] += 1</code>, and pop will do <code>memory[100000] -= 1</code> and use <code>memory[memory[100000]]</code> as value.</p>
  5726. <p>You see how powerfull are continous pieces of memory? Arrays and Lists are how computers are built!</p>
  5727. <p>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.</p>
  5728. <p>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.</p>
  5729. <p>There is no magic, it is all built on this. Built with few numbers in a block of memory.</p>
  5730. <p>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.</p>
  5731. <p><code>PUSH position 0 stack-before [] stack-after [5]
  5732. PUSH position 2 stack-before [5] stack-after [5, 10]
  5733. PUSH position 4 stack-before [5, 10] stack-after [5, 10, 8]
  5734. JUMP position 6 stack-before [5, 10, 8] stack-after [5, 10, 8]
  5735. POP position 198 stack-before [5, 10, 8] stack-after [5, 10]
  5736. POP position 200 stack-before [5, 10] stack-after [5]
  5737. POP position 202 stack-before [5] stack-after []
  5738. SET position 204 stack-before [] stack-after []
  5739. ADD position 207 stack-before [] stack-after []
  5740. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5741. ADD position 214 stack-before [] stack-after []
  5742. ADD position 218 stack-before [] stack-after []
  5743. JUMP position 222 stack-before [] stack-after []
  5744. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5745. ADD position 214 stack-before [] stack-after []
  5746. ADD position 218 stack-before [] stack-after []
  5747. JUMP position 222 stack-before [] stack-after []
  5748. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5749. ADD position 214 stack-before [] stack-after []
  5750. ADD position 218 stack-before [] stack-after []
  5751. JUMP position 222 stack-before [] stack-after []
  5752. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5753. ADD position 214 stack-before [] stack-after []
  5754. ADD position 218 stack-before [] stack-after []
  5755. JUMP position 222 stack-before [] stack-after []
  5756. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5757. ADD position 214 stack-before [] stack-after []
  5758. ADD position 218 stack-before [] stack-after []
  5759. JUMP position 222 stack-before [] stack-after []
  5760. JUMP_IF_ZERO position 211 stack-before [] stack-after []
  5761. PUSHV position 224 stack-before [] stack-after [50]
  5762. JUMPV position 226 stack-before [50] stack-after [50]
  5763. POP position 8 stack-before [50] stack-after []
  5764. PRINT position 10 stack-before [] stack-after []
  5765. 50
  5766. HALT position 12 stack-before []</code></p>
  5767. <p>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.</p>
  5768. <p>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.</p>
  5769. <p>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.</p>
  5770. <h2>[DAY-96] Binary; ASCII; Memory</h2>
  5771. <p>Lets spend a day on bits and bytes.</p>
  5772. <p>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.</p>
  5773. <p><code>0 # tails
  5774. 1 # heads</code>
  5775. 2 possible</p>
  5776. <p><code>0 0 # both coins are tails
  5777. 0 1 # second coin is heads
  5778. 1 0 # first coin is heads
  5779. 1 1 # both coins are heads</code></p>
  5780. <p>2 * 2 possible</p>
  5781. <p>We have 4 distinct values, in 2 bits, lets try 3 coins</p>
  5782. <p><code>000
  5783. 001
  5784. 010
  5785. 011
  5786. 100
  5787. 101
  5788. 110
  5789. 111</code>
  5790. 2 * 2 * 2 possible</p>
  5791. <p>we have 8 distinct values in 3 bits, and in 4 bits we have 16 distinct values</p>
  5792. <p><code>0000
  5793. 0001
  5794. 0010
  5795. 0011
  5796. 0100
  5797. 0101
  5798. 0110
  5799. 0111
  5800. 1000
  5801. 1001
  5802. 1010
  5803. 1011
  5804. 1100
  5805. 1101
  5806. 1110
  5807. 1111</code></p>
  5808. <p>2 * 2 * 2 * 2 possible</p>
  5809. <p>in 32 bits we can store 4294967295 distinct values! and in 64 bits we can store 18446744073709551615.</p>
  5810. <p>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.</p>
  5811. <p>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.</p>
  5812. <p>The reason is 2 * 2 * 2 * 2 * 2 * 2... 31 times is twice smaller than 2 * 2 * 2 * 2 ... 32 times.</p>
  5813. <p>We can also count in this system (called binary system) to make it represent numbers.</p>
  5814. <p>try this:</p>
  5815. <p><code>for i in range(255):
  5816. print(i, ' -&gt; ', format(i, '08b'))</code></p>
  5817. <p>in python format can take a number and print it as binary number:</p>
  5818. <p><code>0 -&gt; 00000000
  5819. 1 -&gt; 00000001
  5820. 2 -&gt; 00000010
  5821. 3 -&gt; 00000011
  5822. 4 -&gt; 00000100
  5823. 5 -&gt; 00000101
  5824. 6 -&gt; 00000110
  5825. 7 -&gt; 00000111
  5826. 8 -&gt; 00001000
  5827. 9 -&gt; 00001001
  5828. 10 -&gt; 00001010
  5829. 11 -&gt; 00001011
  5830. 12 -&gt; 00001100
  5831. 13 -&gt; 00001101
  5832. 14 -&gt; 00001110
  5833. 15 -&gt; 00001111
  5834. 16 -&gt; 00010000
  5835. ...</code></p>
  5836. <p>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.</p>
  5837. <p>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.</p>
  5838. <p>So if you need to store the number <code>x = 47917437</code>, 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.</p>
  5839. <p>example if we want to store <code>5, h e l l o</code>, the computer memory might look like this:
  5840. ```
  5841. 5 h e l l o
  5842. 5 104 101 108 108 111</p>
  5843. <p>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
  5844. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5845. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5846. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5847. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5848. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5849. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5850. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5851. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5852. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5853. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5854. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5855. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5856. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5857. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5858. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5859. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5860. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5861. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5862. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5863. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5864. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5865. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5866. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5867. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5868. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5869. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5870. 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
  5871. ...
  5872. ```</p>
  5873. <p>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.</p>
  5874. <h2>[DAY-97] Lists;</h2>
  5875. <p><img alt="game-97.png" src="./screenshots/game-97.png" title="game 97 screenshot" /></p>
  5876. <p>Catch all the falling snakes.</p>
  5877. <p>Take this skeleton, and fill in the blanks.</p>
  5878. <p>```
  5879. import pgzrun
  5880. import random</p>
  5881. <p>HEIGHT = 400
  5882. WIDTH = 300</p>
  5883. <p>falling = []
  5884. game_area = Rect(0,0,WIDTH,HEIGHT)
  5885. elf = Actor("c1")</p>
  5886. <p>elf.y = HEIGHT - 10
  5887. elf.x = WIDTH/2
  5888. game_over = False</p>
  5889. <p>def drop():
  5890. f = Actor("snake")
  5891. f.x = random.randint(0,WIDTH)
  5892. f.y = random.randint(0, 150)
  5893. falling.append(f)</p>
  5894. <p>def update():
  5895. global game_over</p>
  5896. <pre><code># move the elf left or right
  5897. ...
  5898. # detect the collisions between snakes and elf
  5899. # and remove them if they collide
  5900. ...
  5901. # advance the snakes downwards
  5902. ...
  5903. # check if the snakes are outside of the game area, and set game over
  5904. ...
  5905. # add new snakes if there are less than 5 on the screen
  5906. ...
  5907. </code></pre>
  5908. <p>def draw():
  5909. if game_over:
  5910. screen.fill('pink')
  5911. else:
  5912. screen.fill('black')
  5913. for f in falling:
  5914. f.draw()</p>
  5915. <pre><code> screen.draw.rect(game_area, (255,0,0))
  5916. elf.draw()
  5917. </code></pre>
  5918. <p>pgzrun.go()</p>
  5919. <p>```</p>
  5920. <p>This is one example of implementing it, can you think of another?</p>
  5921. <p>```
  5922. import pgzrun
  5923. import random</p>
  5924. <p>HEIGHT = 400
  5925. WIDTH = 300</p>
  5926. <p>falling = []
  5927. game_area = Rect(0,0,WIDTH,HEIGHT)
  5928. elf = Actor("c1")</p>
  5929. <p>elf.y = HEIGHT - 10
  5930. elf.x = WIDTH/2
  5931. game_over = False</p>
  5932. <p>def drop():
  5933. f = Actor("snake")
  5934. f.x = random.randint(0,WIDTH)
  5935. f.y = random.randint(0, 150)
  5936. falling.append(f)</p>
  5937. <p>def update():
  5938. global game_over</p>
  5939. <pre><code># move the elf left or right
  5940. if keyboard.left:
  5941. elf.x = elf.x-5
  5942. if keyboard.right:
  5943. elf.x = elf.x+5
  5944. # detect the collisions between snakes and elf
  5945. # and remove them if they collide
  5946. remove = []
  5947. for f in falling:
  5948. if f.colliderect(elf):
  5949. remove.append(f)
  5950. for r in remove:
  5951. falling.remove(r)
  5952. # advance the snakes downwards
  5953. for f in falling:
  5954. f.y += 1
  5955. # check if the snakes are outside of the game area, and set game over
  5956. for f in falling:
  5957. if not f.colliderect(game_area):
  5958. game_over = True
  5959. # add new snakes if there are less than 5 on the screen
  5960. if len(falling) &lt; 5:
  5961. drop()
  5962. </code></pre>
  5963. <p>def draw():
  5964. if game_over:
  5965. screen.fill('pink')
  5966. else:
  5967. screen.fill('black')
  5968. for f in falling:
  5969. f.draw()</p>
  5970. <pre><code> screen.draw.rect(game_area, (255,0,0))
  5971. elf.draw()
  5972. </code></pre>
  5973. <p>pgzrun.go()
  5974. ```</p>
  5975. <p>Another possible implementation, this one uses <code>list()</code> to make a copy of the falling list and also has score and lives.</p>
  5976. <p>```
  5977. import pgzrun
  5978. import random</p>
  5979. <p>HEIGHT = 400
  5980. WIDTH = 300</p>
  5981. <p>falling = []
  5982. game_area = Rect(0,0,WIDTH,HEIGHT)
  5983. elf = Actor("c1")</p>
  5984. <p>elf.y = HEIGHT - 10
  5985. elf.x = WIDTH/2
  5986. game_over = False
  5987. score = 0
  5988. lives = 5</p>
  5989. <p>def drop():
  5990. f = Actor("snake")
  5991. f.x = random.randint(0,WIDTH)
  5992. f.y = random.randint(0, 150)
  5993. falling.append(f)</p>
  5994. <p>def update():
  5995. global game_over, score, lives</p>
  5996. <pre><code>if keyboard.A:
  5997. elf.x -= 5
  5998. if keyboard.D:
  5999. elf.x += 5
  6000. for i in falling:
  6001. i.y += 1
  6002. for i in list(falling):
  6003. if not i.colliderect(game_area):
  6004. falling.remove(i)
  6005. lives -= 1
  6006. game_over = lives &lt;= 0
  6007. if len(falling) &lt; 5:
  6008. drop()
  6009. for i in list(falling):
  6010. if i.colliderect(elf):
  6011. falling.remove(i)
  6012. score += 1
  6013. </code></pre>
  6014. <p>def draw():
  6015. if game_over:
  6016. screen.fill('pink')
  6017. else:
  6018. screen.fill('black')
  6019. screen.draw.text("score: " + str(score) + " lives: " + str(lives), topleft=(10,10))</p>
  6020. <pre><code> for f in falling:
  6021. f.draw()
  6022. screen.draw.rect(game_area, (255,0,0))
  6023. elf.draw()
  6024. </code></pre>
  6025. <p>pgzrun.go()
  6026. ```</p>
  6027. <h2>[DAY-98] Lists; Read/Write File</h2>
  6028. <p><img alt="game-98-a.png" src="./screenshots/game-98-a.png" title="game 98-a screenshot" /></p>
  6029. <p>```
  6030. import pgzrun
  6031. import sys # for sys.exit()</p>
  6032. <p>HEIGHT = 300
  6033. WIDTH = 300</p>
  6034. <p>elf = Actor("c1")
  6035. colors = [
  6036. [(255,0,0), Rect(0,0,40,40)],
  6037. [(0,255,0), Rect(60,0,40,40)],
  6038. [(0,0,255), Rect(120,0,40,40)],
  6039. ]
  6040. color = None
  6041. pixels = []</p>
  6042. <p>def update():
  6043. global color, pixels</p>
  6044. <pre><code>if keyboard.LEFT:
  6045. elf.x -= 2
  6046. if keyboard.RIGHT:
  6047. elf.x += 2
  6048. if keyboard.UP:
  6049. elf.y -= 2
  6050. if keyboard.DOWN:
  6051. elf.y += 2
  6052. if keyboard.Q:
  6053. sys.exit(0)
  6054. if keyboard.SPACE and color != None:
  6055. pixels.append([
  6056. color,
  6057. Rect(elf.x,elf.y,40,40)
  6058. ])
  6059. if keyboard.C:
  6060. pixels = []
  6061. color = None
  6062. if keyboard.D:
  6063. drop = Rect(elf.x,elf.y,40,40)
  6064. for p in list(pixels):
  6065. if drop.colliderect(p[1]):
  6066. pixels.remove(p)
  6067. for c in colors:
  6068. if elf.colliderect(c[1]):
  6069. color = c[0]
  6070. </code></pre>
  6071. <p>def draw():
  6072. screen.fill('black')</p>
  6073. <pre><code>for c in colors:
  6074. screen.draw.filled_rect(c[1], c[0])
  6075. for p in pixels:
  6076. screen.draw.filled_rect(p[1], p[0])
  6077. if color != None:
  6078. screen.draw.rect(Rect(elf.x,elf.y,40,40), color)
  6079. elf.draw()
  6080. screen.draw.text(str(len(pixels)), topleft=(10,10))
  6081. </code></pre>
  6082. <p>pgzrun.go()
  6083. ```</p>
  6084. <p>Simple catch the flower game</p>
  6085. <p><img alt="game-98-b.png" src="./screenshots/game-98-b.png" title="game 98-b screenshot" /></p>
  6086. <p>```
  6087. import pgzrun
  6088. import sys # for sys.exit()</p>
  6089. <p>HEIGHT = 300
  6090. WIDTH = 300</p>
  6091. <p>elf = Actor("c1")
  6092. flower = Actor("flower")</p>
  6093. <p>def update():
  6094. if keyboard.LEFT:
  6095. elf.x -= 5
  6096. # add RIGHT/UP/DONW</p>
  6097. <pre><code>if keyboard.Q:
  6098. sys.exit(0)
  6099. # check if the elf collides the flower
  6100. # and if it does, increment the score
  6101. # and place the flower on some random place
  6102. # ...
  6103. </code></pre>
  6104. <p>def draw():
  6105. screen.fill('black')
  6106. elf.draw()
  6107. flower.draw()</p>
  6108. <pre><code># show the score
  6109. # ...
  6110. </code></pre>
  6111. <p>pgzrun.go()
  6112. ```</p>
  6113. <p>Example implementation:</p>
  6114. <p>```
  6115. import pgzrun
  6116. import random
  6117. import sys # for sys.exit()</p>
  6118. <p>HEIGHT = 300
  6119. WIDTH = 300</p>
  6120. <p>elf = Actor("c1")
  6121. elf.x = WIDTH/2
  6122. elf.y = HEIGHT/2</p>
  6123. <p>flower = Actor("flower")
  6124. flower.x = 10
  6125. flower.y = 10
  6126. score = 0
  6127. def update():
  6128. global score
  6129. if keyboard.LEFT:
  6130. elf.x -= 5
  6131. if keyboard.RIGHT:
  6132. elf.x += 5
  6133. if keyboard.UP:
  6134. elf.y -= 5
  6135. if keyboard.DOWN:
  6136. elf.y += 5</p>
  6137. <pre><code>if keyboard.Q:
  6138. sys.exit(0)
  6139. if elf.colliderect(flower):
  6140. flower.x = random.randint(10,WIDTH-10)
  6141. flower.y = random.randint(10,HEIGHT-10)
  6142. score += 1
  6143. </code></pre>
  6144. <p>def draw():
  6145. screen.fill('black')
  6146. elf.draw()
  6147. flower.draw()
  6148. screen.draw.text(str(score), topleft=(10,10))</p>
  6149. <p>pgzrun.go()
  6150. ```</p>
  6151. <p>Same program but with Load and Save</p>
  6152. <p>```
  6153. import pgzrun
  6154. import sys # for sys.exit()</p>
  6155. <p>HEIGHT = 300
  6156. WIDTH = 300</p>
  6157. <p>elf = Actor("c1")
  6158. colors = [
  6159. [(255,0,0), Rect(0,0,40,40)],
  6160. [(0,255,0), Rect(60,0,40,40)],
  6161. [(0,0,255), Rect(120,0,40,40)],
  6162. ]
  6163. color = None
  6164. pixels = []</p>
  6165. <p>def make_rect_around_actor(a):
  6166. return Rect(a.x,a.y,40,40)
  6167. def update():
  6168. global color, pixels</p>
  6169. <pre><code>if keyboard.LEFT:
  6170. elf.x -= 2
  6171. if keyboard.RIGHT:
  6172. elf.x += 2
  6173. if keyboard.UP:
  6174. elf.y -= 2
  6175. if keyboard.DOWN:
  6176. elf.y += 2
  6177. if keyboard.Q:
  6178. sys.exit(0)
  6179. if keyboard.SPACE and color != None:
  6180. pixels.append([
  6181. color,
  6182. make_rect_around_actor(elf),
  6183. ])
  6184. if keyboard.C:
  6185. pixels = []
  6186. color = None
  6187. if keyboard.S:
  6188. f = open("save.txt", "w")
  6189. for p in pixels:
  6190. (red,green,blue) = p[0]
  6191. f.write(str(red))
  6192. f.write(",")
  6193. f.write(str(green))
  6194. f.write(",")
  6195. f.write(str(blue))
  6196. f.write(",")
  6197. f.write(str(p[1].x))
  6198. f.write(",")
  6199. f.write(str(p[1].y))
  6200. f.write(",")
  6201. f.write(str(p[1].width))
  6202. f.write(",")
  6203. f.write(str(p[1].height))
  6204. f.write("\n")
  6205. f.close()
  6206. if keyboard.L:
  6207. pixels = []
  6208. f = open("save.txt", "r")
  6209. lines = f.readlines()
  6210. for l in lines:
  6211. (red,green,blue,x,y,w,h) = l.split(",")
  6212. pixels.append([
  6213. (float(red),float(green),float(blue)),
  6214. Rect(float(x),float(y), float(w), float(h))
  6215. ])
  6216. f.close()
  6217. if keyboard.D:
  6218. drop = make_rect_around_actor(elf)
  6219. for p in list(pixels):
  6220. if drop.colliderect(p[1]):
  6221. pixels.remove(p)
  6222. for c in colors:
  6223. if elf.colliderect(c[1]):
  6224. color = c[0]
  6225. </code></pre>
  6226. <p>def draw():
  6227. screen.fill('black')</p>
  6228. <pre><code>for c in colors:
  6229. screen.draw.filled_rect(c[1], c[0])
  6230. for p in pixels:
  6231. screen.draw.filled_rect(p[1], p[0])
  6232. if color != None:
  6233. screen.draw.rect(make_rect_around_actor(elf), color)
  6234. elf.draw()
  6235. screen.draw.text(str(len(pixels)), topleft=(10,10))
  6236. </code></pre>
  6237. <p>pgzrun.go()
  6238. ```</p>
  6239. <h2>[DAY-99] Classes; Lists; Functions; Cartesian Coordinates</h2>
  6240. <p>Today we talk about classes and instances.</p>
  6241. <p>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.</p>
  6242. <p>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.</p>
  6243. <p>The blueprint or recipe we call 'class' and the real thing that comes out of it we call 'instance'.</p>
  6244. <p>The class can define functions, and those functions will take a magic <code>self</code> parameter, where <code>self</code> will be the instance. For example in roblox, the house probably has a function 'lock()' that does something like <code>self.is_locked = True</code>.</p>
  6245. <p>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, <code>p.colliderect(r)</code> for example you can look at sending the message <code>colliderect</code> to the object <code>p</code> with parameter <code>r</code>. Or you can look at it just as a function with hidden <code>self</code> parameter. In the following example you can see a method <code>def colliderect(self,r)</code> in the Point class, and also a standalone function <code>def collidepoint(rect, point)</code> that just expects a rect and a point objects.</p>
  6246. <p>```
  6247. class Point:
  6248. x = 0
  6249. y = 0
  6250. def <strong>init</strong>(self, name):
  6251. self.name = name</p>
  6252. <pre><code>def print(self):
  6253. print('point',self.x,self.y,self.name)
  6254. def colliderect(self,r):
  6255. return self.x &gt; r.x and self.x &lt; r.x + r.w and self.y &gt; r.y and self.y &lt; r.y + r.h
  6256. </code></pre>
  6257. <p>class Rect:
  6258. x = 0
  6259. y = 0
  6260. w = 0
  6261. h = 0
  6262. def print(self):
  6263. print('rect',self.x,self.y,self.w,self.h)</p>
  6264. <h1></h1>
  6265. <h1>|-----------------------+</h1>
  6266. <h1>| |</h1>
  6267. <h1>6 +-------+ |</h1>
  6268. <h1>| | | |</h1>
  6269. <h1>4--|---x | |</h1>
  6270. <h1>| | | | |</h1>
  6271. <h1>2--+-------+ |</h1>
  6272. <h1>| | | | |</h1>
  6273. <h1>+--2---6---9------------+</h1>
  6274. <h1>0,0</h1>
  6275. <p>def collidepoint(rect, point):
  6276. if point.x &gt; rect.x and point.x &lt; rect.x + rect.w and point.y &gt; rect.y and point.y &lt; rect.y + rect.h:
  6277. return True
  6278. else:
  6279. return False</p>
  6280. <p>p = Point("blue") # instance
  6281. p.x = 6
  6282. p.y = 4</p>
  6283. <p>r = Rect() # instance
  6284. r.x = 2
  6285. r.y = 2
  6286. r.w = 7
  6287. r.h = 4</p>
  6288. <p>if collidepoint(r,p):
  6289. print("COLLIDES")
  6290. r.print()
  6291. p.print()</p>
  6292. <p>p2 = Point("red")
  6293. p2.x = 10
  6294. p2.y = 10
  6295. if not collidepoint(r,p2):
  6296. print("NO COLLISION")
  6297. r.print()
  6298. p.print()</p>
  6299. <p>if p.colliderect(r):
  6300. print("p collides")
  6301. ```</p>
  6302. <p>```
  6303. import pgzrun
  6304. import sys # for sys.exit()
  6305. import random</p>
  6306. <p>HEIGHT = 600
  6307. WIDTH = 600</p>
  6308. <p>elf = Actor("c1")
  6309. speed = 3
  6310. back = []
  6311. def update():
  6312. global score
  6313. if keyboard.A:
  6314. elf.x -= speed
  6315. if keyboard.D:
  6316. elf.x += speed
  6317. if keyboard.W:
  6318. elf.y -= speed
  6319. if keyboard.S:
  6320. elf.y += speed
  6321. if keyboard.J:
  6322. f = Actor('flower')
  6323. f.x = elf.x
  6324. f.y = elf.y
  6325. back.append(f)</p>
  6326. <pre><code>if keyboard.M:
  6327. f = open("save.txt", "w")
  6328. for x in back:
  6329. f.write(str(x.x))
  6330. f.write(",")
  6331. f.write(str(x.y))
  6332. f.write("\n")
  6333. f.close()
  6334. if keyboard.L:
  6335. f = open("save.txt", "r")
  6336. for line in f.readlines():
  6337. (x,y) = line.split(",") # 30,20
  6338. a = Actor('flower')
  6339. a.x = float(x)
  6340. a.y = float(y)
  6341. back.append(a)
  6342. f.close()
  6343. if keyboard.Q:
  6344. sys.exit(0)
  6345. </code></pre>
  6346. <p>def draw():
  6347. screen.fill('black')</p>
  6348. <pre><code>for i in back:
  6349. i.draw()
  6350. elf.draw()
  6351. </code></pre>
  6352. <p>pgzrun.go()
  6353. ```</p>
  6354. <p><img alt="game-99.png" src="./screenshots/game-99.png" title="game 99 screenshot" /></p>
  6355. <p>simpler painting game:</p>
  6356. <p>```
  6357. import pgzrun
  6358. import sys # for sys.exit()
  6359. import random</p>
  6360. <p>HEIGHT = 600
  6361. WIDTH = 600</p>
  6362. <p>elf = Actor("c1")
  6363. speed = 3
  6364. back = []
  6365. def update():
  6366. global score
  6367. if keyboard.A:
  6368. elf.x -= speed
  6369. if keyboard.D:
  6370. elf.x += speed
  6371. if keyboard.W:
  6372. elf.y -= speed
  6373. if keyboard.S:
  6374. elf.y += speed
  6375. if keyboard.J:
  6376. f = Actor('flower')
  6377. f.x = elf.x
  6378. f.y = elf.y
  6379. back.append(f)</p>
  6380. <pre><code>if keyboard.M:
  6381. f = open("save.txt", "w")
  6382. for x in back:
  6383. f.write(str(x.x))
  6384. f.write(",")
  6385. f.write(str(x.y))
  6386. f.write("\n")
  6387. f.close()
  6388. if keyboard.L:
  6389. f = open("save.txt", "r")
  6390. for line in f.readlines():
  6391. (x,y) = line.split(",") # 30,20
  6392. a = Actor('flower')
  6393. a.x = float(x)
  6394. a.y = float(y)
  6395. back.append(a)
  6396. f.close()
  6397. if keyboard.Q:
  6398. sys.exit(0)
  6399. </code></pre>
  6400. <p>def draw():
  6401. screen.fill('black')</p>
  6402. <pre><code>for i in back:
  6403. i.draw()
  6404. elf.draw()
  6405. </code></pre>
  6406. <p>pgzrun.go()
  6407. ```</p>
  6408. <h2>[DAY-100] Touch Typing; Lists</h2>
  6409. <p>Day 100 party!</p>
  6410. <p>We will make another touch typing game</p>
  6411. <p><img alt="game-100.png" src="./screenshots/game-100.png" title="game 100 screenshot" /></p>
  6412. <p>```
  6413. import pgzrun
  6414. import random</p>
  6415. <p>HEIGHT = 400
  6416. WIDTH = 600</p>
  6417. <p>words = []
  6418. text = ''
  6419. game_over = False
  6420. beep = tone.create('A3', 0.5)</p>
  6421. <p>def move():
  6422. global game_over
  6423. for w in words:
  6424. w[1]+= random.randint(10,15)
  6425. if w[1] &gt; HEIGHT:
  6426. game_over = True</p>
  6427. <p>def add_word():
  6428. common = ['a','about','all','also','and','as','at','be','because','but','by','can','come','could','day',
  6429. 'do','even','find','first','for','from','get','give','go','have','he','her','here','him','his',
  6430. 'how','i','if','in','into','it','its','just','know','like','look','make','man','many','me',
  6431. 'more','my','new','no','not','now','of','on','one','only','or','other','our','out','people',
  6432. 'say','see','she','so','some','take','tell','than','that','the','their','them','then','there',
  6433. 'these','they','thing','think','this','those','time','to','two','up','use','very','want','way',
  6434. 'we','well','what','when','which','who','will','with','would','year','you','your',
  6435. ]
  6436. words.append([random.randint(10,WIDTH-50), random.randint(10,HEIGHT/2), random.choice(common)])</p>
  6437. <p>def on_key_down(key, mod, unicode):
  6438. global text
  6439. if key == keys.BACKSPACE:
  6440. if len(text) &gt; 0:
  6441. text = text[:-1]
  6442. elif len(unicode) &gt; 0 and ord(unicode) &gt;= 65 and ord(unicode) &lt;= 125:
  6443. text += unicode
  6444. for w in list(words):
  6445. if w[2] == text:
  6446. words.remove(w)
  6447. text = ''
  6448. beep.play()</p>
  6449. <p>def draw():
  6450. if game_over:
  6451. screen.fill('pink')
  6452. else:
  6453. screen.fill('black')</p>
  6454. <pre><code> for w in words:
  6455. screen.draw.text(w[2], (w[0],w[1]), fontsize=20,fontname="437-win")
  6456. screen.draw.text(text, (WIDTH/2,HEIGHT - 40), color=(255,0,0), fontsize=40,fontname="437-win")
  6457. </code></pre>
  6458. <p>for i in range(5):
  6459. add_word()</p>
  6460. <p>clock.schedule_interval(add_word, 2)
  6461. clock.schedule_interval(move, 1)
  6462. pgzrun.go()
  6463. ```</p>
  6464. <p>ghost!</p>
  6465. <p>```
  6466. import random
  6467. score = 0
  6468. while True:
  6469. ghost = random.randint(1,3)
  6470. choice = input('Pick a door from 1,2, or 3: ')
  6471. if choice == str(ghost):
  6472. print ('there is a ghost :O GAME OVER !!!')
  6473. break
  6474. else:
  6475. score += 1
  6476. print('lucky no gosht')
  6477. print('your score is ' + str(score))</p>
  6478. <p>```</p>
  6479. <h2>[DAY-101] Functions; Strings</h2>
  6480. <p>invert a list</p>
  6481. <p>```
  6482. def invert(l):
  6483. #...</p>
  6484. <p>print(invert([1,2,3]))
  6485. ```</p>
  6486. <p>invert a string</p>
  6487. <p>```
  6488. def invert(s):
  6489. #...</p>
  6490. <p>print(invert("hello"))
  6491. ```</p>
  6492. <p>invert a number</p>
  6493. <p>```
  6494. def invert(n):
  6495. #...</p>
  6496. <p>print(invert(123456))
  6497. ```</p>
  6498. <p>Check if a string is a palindrome, a palindrome is a string that you can read backwards and it sounds the same.</p>
  6499. <p><code>Anna
  6500. civic
  6501. kayak
  6502. level
  6503. madam
  6504. mom
  6505. noon
  6506. racecar
  6507. radar
  6508. redder
  6509. refer
  6510. repaper
  6511. rotator
  6512. rotor
  6513. sagas
  6514. solos
  6515. stats
  6516. tenet
  6517. wow
  6518. Never odd or even.
  6519. We panic in a pew.
  6520. Won’t lovers revolt now?
  6521. Don’t nod.
  6522. Sir, I demand, I am a maid named Iris.
  6523. Don't nod.
  6524. I did, did I?
  6525. Step on no pets.
  6526. Eva, can I see bees in a cave?
  6527. Was it a cat I saw?</code></p>
  6528. <p>example:</p>
  6529. <p><code>while True:
  6530. n = input("which string you want to check: )
  6531. if is_palindrome(n):
  6532. print(n + " is a palindrome")
  6533. else:
  6534. print(n + " is not a palindrome")</code></p>
  6535. <h1>Chapter 14 - Week 14</h1>
  6536. <p><code>day0: Basics of Basics
  6537. day1: Basics of Basics
  6538. day2: Basics of Basics
  6539. day3: Basics of Basics
  6540. day4: Basics of Basics
  6541. day5: Basics of Basics
  6542. day6: Basics of Basics</code></p>
  6543. <h2>[DAY-102] Touch Typing day</h2>
  6544. <p>Whole day touch typing!</p>
  6545. <p>Modify the program to print some score and words per minute, and try to improve your score.</p>
  6546. <p>```
  6547. import pgzrun
  6548. import random
  6549. import time</p>
  6550. <p>HEIGHT = 800
  6551. WIDTH = 600</p>
  6552. <p>words = []
  6553. text = ''
  6554. game_over = False
  6555. beep = tone.create('A3', 0.5)
  6556. pause = False
  6557. score = 0
  6558. times = []
  6559. def words_per_minute():
  6560. if len(times) &lt; 2:
  6561. return 0</p>
  6562. <pre><code>return int(len(times) / ((times[-1] - times[0]) / 60.0))
  6563. </code></pre>
  6564. <p>def move():
  6565. global game_over
  6566. if pause:
  6567. return
  6568. for w in words:
  6569. w[1]+= random.randint(10,15)
  6570. if w[1] &gt; HEIGHT:
  6571. game_over = True</p>
  6572. <p>def add_word():
  6573. if pause:
  6574. return
  6575. common = ['a','about','all','also','and','as','at','be','because','but','by','can','come','could','day',
  6576. 'do','even','find','first','for','from','get','give','go','have','he','her','here','him','his',
  6577. 'how','i','if','in','into','it','its','just','know','like','look','make','man','many','me',
  6578. 'more','my','new','no','not','now','of','on','one','only','or','other','our','out','people',
  6579. 'say','see','she','so','some','take','tell','than','that','the','their','them','then','there',
  6580. 'these','they','thing','think','this','those','time','to','two','up','use','very','want','way',
  6581. 'we','well','what','when','which','who','will','with','would','year','you','your',
  6582. 'paper','game','remember','person','english','dutch','amsterdam','nothing','sleep','product','natural',
  6583. 'juice','orange','blue','green','together','friends','between','music','book','bookstore','fish','complete',
  6584. 'width','weight','height','length','string','python','unicode','backspace','random','choice','string','integer',
  6585. 'function','print','print','print','for','range','range',
  6586. ]
  6587. w = random.choice(common)
  6588. words.append([random.randint(10,WIDTH-(len(w) * 15)), random.randint(10,int(HEIGHT/3)), w])</p>
  6589. <p>def on_key_down(key, mod, unicode):
  6590. global text, pause, score_words, score
  6591. if key == keys.BACKSPACE:
  6592. if len(text) &gt; 0:
  6593. text = text[:-1]
  6594. elif key == keys.SPACE:
  6595. pause = not pause
  6596. elif len(unicode) &gt; 0 and ord(unicode) &gt;= 65 and ord(unicode) &lt;= 125:
  6597. text += unicode
  6598. for w in list(words):
  6599. if w[2] == text:
  6600. score += 1
  6601. words.remove(w)
  6602. if len(words) &lt; 4:
  6603. add_word()</p>
  6604. <pre><code> text = ''
  6605. beep.play()
  6606. times.append(time.time())
  6607. </code></pre>
  6608. <p>def draw():
  6609. if game_over:
  6610. screen.fill('pink')
  6611. elif pause:
  6612. screen.fill('magenta')
  6613. else:
  6614. screen.fill('black')</p>
  6615. <pre><code> screen.draw.text("score: " + str(score) + " wpm: " + str(words_per_minute()), (10,10), color=(0,255,0), fontsize=15,fontname="437-win")
  6616. for w in words:
  6617. screen.draw.text(w[2], (w[0],w[1]), fontsize=20,fontname="437-win")
  6618. screen.draw.text(text, (WIDTH/2,HEIGHT - 40), color=(255,0,0), fontsize=40,fontname="437-win")
  6619. </code></pre>
  6620. <p>for i in range(5):
  6621. add_word()</p>
  6622. <p>clock.schedule_interval(add_word, 5)
  6623. clock.schedule_interval(move, 5)
  6624. pgzrun.go()
  6625. ```</p>
  6626. <p>get more words with the characters you need to train from your dictionary file</p>
  6627. <p>use a simple program like this:</p>
  6628. <p>```
  6629. import sys
  6630. need = ['k','l','i','o']
  6631. for line in sys.stdin:
  6632. missing = False
  6633. s = line.rstrip()</p>
  6634. <pre><code>for n in need:
  6635. if n not in s:
  6636. missing = True
  6637. if not missing and len(s) &lt;= 7:
  6638. </code></pre>
  6639. <p>print(s)
  6640. ```</p>
  6641. <p>and then get the list:</p>
  6642. <p><code>cat /usr/share/dict/words | python3 words.py | tr "[A-Z]" "[a-z]" | sort | uniq | sed -e "s/^/'/g" -e "s/$/',/g" | pbcopy</code></p>
  6643. <h2>[DAY-103] Read File; Command Line Arguments</h2>
  6644. <p>Search all the books!</p>
  6645. <p>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.</p>
  6646. <p>Oh! the gutenberg project is absolutely amazing, they have more than 60000 books that have expired copyright.</p>
  6647. <p>```
  6648. import csv
  6649. import sys
  6650. import argparse
  6651. parser = argparse.ArgumentParser()
  6652. parser.add_argument('--author', help='match author name')
  6653. parser.add_argument('--title', help='match title')
  6654. parser.add_argument('--subject', help='match subject')
  6655. args = parser.parse_args()</p>
  6656. <p>def show(id, title, authors, subjects, issued, language):
  6657. print("&gt;&gt;&gt; " + title + " &lt;&lt;&lt;")
  6658. print(" " + issued)
  6659. print(" https://www.gutenberg.org/ebooks/" + id)</p>
  6660. <pre><code>print('')
  6661. for a in authors:
  6662. print(" Author: " + a)
  6663. print('')
  6664. for s in subjects:
  6665. print(" Subject: " + s)
  6666. print(" Language: " + language)
  6667. print("-" * 40)
  6668. </code></pre>
  6669. <p>file = open('pg_catalog.csv')
  6670. reader = csv.reader(file)
  6671. for row in reader:
  6672. # ['Text#', 'Type', 'Issued', 'Title', 'Language', 'Authors', 'Subjects', 'LoCC', 'Bookshelves']
  6673. id = row[0]
  6674. if id == "Text#":
  6675. # skip the first row (header)
  6676. continue</p>
  6677. <pre><code>issued = row[2]
  6678. title = row[3].replace("\n","; ")
  6679. language = row[4]
  6680. authors = row[5].split("; ")
  6681. subjects = row[6].split("; ")
  6682. match = 0
  6683. need = 0
  6684. if args.title != None:
  6685. need += 1
  6686. if args.title in title:
  6687. match += 1
  6688. if args.subject != None:
  6689. need += 1
  6690. for s in subjects:
  6691. if args.subject in s:
  6692. match += 1
  6693. break
  6694. if args.author != None:
  6695. need += 1
  6696. for a in authors:
  6697. if args.author in a:
  6698. match += 1
  6699. break
  6700. if match == need:
  6701. show(id,title,authors,subjects,issued,language)
  6702. </code></pre>
  6703. <p>file.close()
  6704. ```</p>
  6705. <p>now try this:</p>
  6706. <p><code>python3 search.py --title Alice --author Carroll | less</code></p>
  6707. <p>CSV stands for comma separated value, its a neat way to encode a table, each column is separated by a <code>,</code>. Python has csv module in its standard library, and its very easy to load and parse csv files.</p>
  6708. <h2>[DAY-104] Read File; Command Line Arguments; Dictionary</h2>
  6709. <p>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.</p>
  6710. <p>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.</p>
  6711. <p>First just copy paste the program, and try to read it, we will go over it step by step later.</p>
  6712. <p>```
  6713. import sys
  6714. import re
  6715. import json</p>
  6716. <p>def show(book):
  6717. id = book["id"]
  6718. title = book["title"]
  6719. authors = book["authors"]
  6720. subjects = book["subjects"]
  6721. issued = book["issued"]
  6722. language = book["language"]</p>
  6723. <pre><code>print("&gt;&gt;&gt; " + title + " &lt;&lt;&lt;")
  6724. print(" " + issued)
  6725. print(" https://www.gutenberg.org/ebooks/" + str(id))
  6726. print('')
  6727. for a in authors:
  6728. print(" Author: " + a)
  6729. print('')
  6730. for s in subjects:
  6731. print(" Subject: " + s)
  6732. print(" Language: " + language)
  6733. print("-" * 40)
  6734. </code></pre>
  6735. <p>def parse(filename):
  6736. file = open(filename)
  6737. reader = csv.reader(file)
  6738. books = []
  6739. for row in reader:
  6740. # ['Text#', 'Type', 'Issued', 'Title', 'Language', 'Authors', 'Subjects', 'LoCC', 'Bookshelves']
  6741. if row[0] == "Text#":
  6742. # skip the first row (header)
  6743. continue</p>
  6744. <pre><code> id = int(row[0])
  6745. issued = row[2]
  6746. title = row[3].replace("\n","; ")
  6747. language = row[4]
  6748. authors = row[5].split("; ")
  6749. subjects = row[6].split("; ")
  6750. book = {
  6751. "title": title,
  6752. "language": language,
  6753. "authors": authors,
  6754. "subjects": subjects,
  6755. "issued": issued,
  6756. "id": id
  6757. }
  6758. books.append(book)
  6759. file.close()
  6760. return books
  6761. </code></pre>
  6762. <p>def normalize(s):
  6763. # 'Alice's Adventures in Wonderland' -&gt; 'alice's adventures in wonderland'
  6764. return s.lower()</p>
  6765. <p>def tokenize(s):
  6766. # 'alice's adventures in wonderland' -&gt; ['alice','s','adventures','in','wonderland']
  6767. return re.split("[^\w+]",s)</p>
  6768. <p>def build_search_index(books):
  6769. index = {}</p>
  6770. <pre><code>for i,book in enumerate(books):
  6771. tokens = set()
  6772. for token in tokenize(normalize(book["title"])):
  6773. k = "title:" + token
  6774. tokens.add(k)
  6775. for token in tokenize(normalize(book["language"])):
  6776. k = "language:" + token
  6777. tokens.add(k)
  6778. for author in book["authors"]:
  6779. for token in tokenize(normalize(author)):
  6780. k = "author:" + token
  6781. tokens.add(k)
  6782. for subject in book["subjects"]:
  6783. for token in tokenize(normalize(subject)):
  6784. k = "subject:" + token
  6785. tokens.add(k)
  6786. for t in tokens:
  6787. if not t in index:
  6788. index[t] = []
  6789. index[t].append(i)
  6790. return index
  6791. </code></pre>
  6792. <p>def search(books, index, query):
  6793. matching = None
  6794. for q in query:
  6795. if q in index:
  6796. if matching == None:
  6797. matching = set(index[q])
  6798. else:
  6799. matching.intersection_update(index[q])
  6800. else:
  6801. matching = set() # if one of the terms is not matching, return empty</p>
  6802. <pre><code>result = []
  6803. if matching == None:
  6804. return result
  6805. for book_index in matching:
  6806. book = books[book_index]
  6807. result.append(book)
  6808. return result
  6809. </code></pre>
  6810. <p>if len(sys.argv) == 1:
  6811. print("usage:\n\t" + sys.argv[0] + " title:alice author:lewis")
  6812. sys.exit(1)</p>
  6813. <p>data = None</p>
  6814. <p>try:
  6815. f = open("search.json", mode="r")
  6816. data = json.load(f)
  6817. f.close()
  6818. except IOError:
  6819. books = parse("pg_catalog.csv")
  6820. search_index = build_search_index(books)</p>
  6821. <pre><code>data = {}
  6822. data["search"] = search_index
  6823. data["books"] = books
  6824. f = open("search.json", mode="w")
  6825. json.dump(data,f)
  6826. f.close()
  6827. </code></pre>
  6828. <p>query = []
  6829. for arg in sys.argv[1:]:
  6830. query.append(normalize(arg))</p>
  6831. <p>for book in search(data["books"], data["search"], query):
  6832. show(book)
  6833. ```</p>
  6834. <p>lets try it:</p>
  6835. <p>```
  6836. % python3 search.py title:Alice author:carroll author:lewis subject:children</p>
  6837. <blockquote>
  6838. <blockquote>
  6839. <blockquote>
  6840. <p>Alice's Adventures in Wonderland &lt;&lt;&lt;
  6841. 2008-06-27
  6842. https://www.gutenberg.org/ebooks/11</p>
  6843. </blockquote>
  6844. </blockquote>
  6845. </blockquote>
  6846. <pre><code>Author: Carroll, Lewis, 1832-1898
  6847. Subject: Fantasy fiction
  6848. Subject: Children's stories
  6849. Subject: Imaginary places -- Juvenile fiction
  6850. Subject: Alice (Fictitious character from Carroll) -- Juvenile fiction
  6851. Language: en
  6852. </code></pre>
  6853. <p>...
  6854. ```</p>
  6855. <p>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.</p>
  6856. <p>So many new concepts here, but the biggest one are maps and sets.</p>
  6857. <p>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.</p>
  6858. <p>```
  6859. episodes = {}</p>
  6860. <p>episodes["naruto"] = 220
  6861. episodes["naruto shippuuden"] = 500
  6862. episodes["boruto"] = 215</p>
  6863. <p>print(episodes)
  6864. print(episodes["naruto"])</p>
  6865. <p>if "naruto" in episodes:
  6866. print("naruto is in the map")</p>
  6867. <p>for k in episodes:
  6868. print(k)</p>
  6869. <p>for k in episodes:
  6870. print(k, episodes[k])
  6871. ```</p>
  6872. <p>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.</p>
  6873. <p>```
  6874. flowers = set()
  6875. flowers.add("rose")
  6876. flowers.add("camomile")
  6877. flowers.add("tulip")</p>
  6878. <p>if "tulip" in flowers:
  6879. print("tulip is in the set")</p>
  6880. <p>for f in flowers:
  6881. print(f)
  6882. ```</p>
  6883. <p>You can <code>union</code> two sets of yoys by placing them into a new bag and this will contain both sets of toys, or you can <code>intersect</code> them by only taking toys that exist in both bags.</p>
  6884. <p>Both maps and sets are somewhat related, imagine a map that only contains keys.</p>
  6885. <p>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.</p>
  6886. <h2>[DAY-105] Basics of Basics</h2>
  6887. <p>make the simple flower/rock drawing game by yourself</p>
  6888. <p>```
  6889. import pgzrun
  6890. import sys # for sys.exit()</p>
  6891. <p>HEIGHT = 300
  6892. WIDTH = 300</p>
  6893. <p>elf = Actor("c1")
  6894. flowers = []
  6895. def update():
  6896. if keyboard.A:
  6897. elf.x -= 5
  6898. if keyboard.D:
  6899. elf.x += 5
  6900. if keyboard.W:
  6901. elf.y -= 5
  6902. if keyboard.S:
  6903. elf.y += 5
  6904. if keyboard.F:
  6905. flower = Actor("flower")
  6906. flower.x = elf.x
  6907. flower.y = elf.y
  6908. flowers.append(flower)
  6909. if keyboard.R:
  6910. flower = Actor("rock")
  6911. flower.x = elf.x
  6912. flower.y = elf.y
  6913. flowers.append(flower)
  6914. if keyboard.Q:
  6915. sys.exit(0)</p>
  6916. <pre><code>if elf.x &lt; 0:
  6917. elf.x = 10
  6918. if elf.y &lt; 0:
  6919. elf.y = 10
  6920. if elf.x &gt; WIDTH:
  6921. elf.x = WIDTH - 10
  6922. if elf.y &gt; HEIGHT:
  6923. elf.y = HEIGHT - 10
  6924. </code></pre>
  6925. <p>def draw():
  6926. screen.fill('black')
  6927. elf.draw()
  6928. for flower in flowers:
  6929. flower.draw()
  6930. pgzrun.go()
  6931. ```</p>
  6932. <h2>[DAY-106] Read/Write File; Lists</h2>
  6933. <p>Have some fun drawing, add more colors, change the size, enjoy!</p>
  6934. <p><img alt="game-106.png" src="./screenshots/game-106.png" title="game 106 screenshot" /></p>
  6935. <p>```
  6936. import pgzrun
  6937. import sys # for sys.exit()</p>
  6938. <p>HEIGHT = 800
  6939. WIDTH = 1000</p>
  6940. <p>elf = Actor("c1")
  6941. colors = [
  6942. [(255,0,0), Rect(0,0,40,40)],
  6943. [(0,255,0), Rect(60,0,40,40)],
  6944. [(0,0,255), Rect(120,0,40,40)],
  6945. [(0,128,128), Rect(180,0,40,40)],
  6946. [(0,191,255), Rect(240,0,40,40)],
  6947. [(255,215,0), Rect(300,0,40,40)],
  6948. ]
  6949. color = None
  6950. pixels = []</p>
  6951. <p>size = 40</p>
  6952. <p>def make_rect_around_actor(a):
  6953. return Rect(a.x,a.y,size,size)
  6954. def update():
  6955. global color, pixels,size</p>
  6956. <pre><code>if keyboard.LEFT:
  6957. elf.x -= 2
  6958. if keyboard.RIGHT:
  6959. elf.x += 2
  6960. if keyboard.UP:
  6961. elf.y -= 2
  6962. if keyboard.DOWN:
  6963. elf.y += 2
  6964. if keyboard.MINUS:
  6965. size -= 1
  6966. if size &lt; 1:
  6967. size = 1
  6968. if keyboard.EQUALS:
  6969. size += 1
  6970. if keyboard.Q:
  6971. sys.exit(0)
  6972. if keyboard.SPACE and color != None:
  6973. pixels.append([
  6974. color,
  6975. make_rect_around_actor(elf),
  6976. ])
  6977. if keyboard.C:
  6978. pixels = []
  6979. color = None
  6980. if keyboard.S:
  6981. f = open("save.txt", "w")
  6982. for p in pixels:
  6983. (red,green,blue) = p[0]
  6984. f.write(str(red))
  6985. f.write(",")
  6986. f.write(str(green))
  6987. f.write(",")
  6988. f.write(str(blue))
  6989. f.write(",")
  6990. f.write(str(p[1].x))
  6991. f.write(",")
  6992. f.write(str(p[1].y))
  6993. f.write(",")
  6994. f.write(str(p[1].width))
  6995. f.write(",")
  6996. f.write(str(p[1].height))
  6997. f.write("\n")
  6998. f.close()
  6999. if keyboard.L:
  7000. pixels = []
  7001. f = open("save.txt", "r")
  7002. lines = f.readlines()
  7003. for l in lines:
  7004. (red,green,blue,x,y,w,h) = l.split(",")
  7005. pixels.append([
  7006. (float(red),float(green),float(blue)),
  7007. Rect(float(x),float(y), float(w), float(h))
  7008. ])
  7009. f.close()
  7010. if keyboard.k_1:
  7011. color = colors[0][0]
  7012. if keyboard.k_2:
  7013. color = colors[1][0]
  7014. if keyboard.k_3:
  7015. color = colors[2][0]
  7016. if keyboard.k_4:
  7017. color = colors[3][0]
  7018. if keyboard.k_5:
  7019. color = colors[4][0]
  7020. if keyboard.k_6:
  7021. color = colors[5][0]
  7022. if keyboard.D:
  7023. drop = make_rect_around_actor(elf)
  7024. for p in list(pixels):
  7025. if drop.colliderect(p[1]):
  7026. pixels.remove(p)
  7027. for c in colors:
  7028. if elf.colliderect(c[1]):
  7029. color = c[0]
  7030. </code></pre>
  7031. <p>def draw():
  7032. screen.fill('black')</p>
  7033. <pre><code>for c in colors:
  7034. screen.draw.filled_rect(c[1], c[0])
  7035. for p in pixels:
  7036. screen.draw.filled_rect(p[1], p[0])
  7037. if color != None:
  7038. screen.draw.rect(make_rect_around_actor(elf), color)
  7039. elf.draw()
  7040. screen.draw.text(str(len(pixels)), topleft=(10,10))
  7041. </code></pre>
  7042. <p>pgzrun.go()
  7043. ```</p>
  7044. <h2>[DAY-107] Lists; Dictionaries</h2>
  7045. <p>count the words in a file</p>
  7046. <p>```
  7047. f = open("week-015.md","r")
  7048. count = []</p>
  7049. <p>for line in f.readlines():
  7050. for word in line.rstrip().split(" "):
  7051. found = False
  7052. for counted in count:
  7053. if counted[0] == word:
  7054. counted[1]+= 1
  7055. found = True
  7056. break
  7057. if not found:
  7058. count.append([word, 1])</p>
  7059. <p>f.close()</p>
  7060. <p>print(count)
  7061. ```</p>
  7062. <p>use a dictionary</p>
  7063. <p>```
  7064. f = open("week-015.md","r")
  7065. count = {}</p>
  7066. <p>for line in f.readlines():
  7067. for word in line.rstrip().split(" "):
  7068. if word in count:
  7069. count[word] += 1
  7070. else:
  7071. count[word] = 1</p>
  7072. <p>f.close()</p>
  7073. <p>for k in count:
  7074. print(count[k], k)
  7075. ```</p>
  7076. <p>get the unique words in a file</p>
  7077. <p>```</p>
  7078. <p>f = open("week-015.md","r")
  7079. unique = set()</p>
  7080. <p>for line in f.readlines():
  7081. for word in line.rstrip().split(" "):
  7082. unique.add(word)</p>
  7083. <p>f.close()</p>
  7084. <p>print(unique)</p>
  7085. <p>```</p>
  7086. <p>lets read the file 1 byte at a time:</p>
  7087. <p>```
  7088. f = open("week-015.md","r")
  7089. word = ''
  7090. count = {}
  7091. while True:
  7092. byte = f.read(1)
  7093. if not byte:
  7094. break
  7095. if byte == ' ' or byte == '\n':
  7096. if word in count:
  7097. count[word] += 1
  7098. else:
  7099. count[word] = 1
  7100. word = ''
  7101. else:
  7102. word += byte
  7103. f.close()</p>
  7104. <p>for k in count:
  7105. print(count[k], k)
  7106. ```</p>
  7107. <p>use sys.stdin to read the standard input</p>
  7108. <p>```
  7109. import sys
  7110. count = {}</p>
  7111. <p>for line in sys.stdin.readlines():
  7112. for word in line.rstrip().split(" "):
  7113. if word in count:
  7114. count[word] += 1
  7115. else:
  7116. count[word] = 1</p>
  7117. <p>for k in count:
  7118. print(count[k], k)
  7119. <code>``
  7120. then try use the output of</code>cat<code>to print the contents of week-015.md and then</code>|` pipe it to your word counting program</p>
  7121. <p><code>$ cat week-015.md | python3 count.py</code></p>
  7122. <p>if you want to sort by most common words:</p>
  7123. <p><code>cat week-015.md | python3 count.py | sort -n</code></p>
  7124. <h2>[DAY-108] Dictionaries</h2>
  7125. <p>count how many times each character appears in a string</p>
  7126. <p>```
  7127. line = "A quick brown fox jumps over the lazy dog"
  7128. count = {}
  7129. for s in line:
  7130. if s not in count:
  7131. count[s] = 1
  7132. else:
  7133. count[s] += 1</p>
  7134. <p>for s in count:
  7135. print(count[s], s)
  7136. ```</p>
  7137. <p>check if all characters from an alphabet are in a string</p>
  7138. <p>```
  7139. alphabet = {
  7140. 'a': True,
  7141. 'b': True,
  7142. 'c': True,
  7143. 'd': True,
  7144. 'e': True,
  7145. 'f': True,
  7146. 'g': True,
  7147. 'h': True,
  7148. 'i': True,
  7149. 'j': True,
  7150. 'k': True,
  7151. 'l': True,
  7152. 'm': True,
  7153. 'n': True,
  7154. 'o': True,
  7155. 'p': True,
  7156. 'q': True,
  7157. 'r': True,
  7158. 's': True,
  7159. 't': True,
  7160. 'u': True,
  7161. 'v': True,
  7162. 'w': True,
  7163. 'x': True,
  7164. 'y': True,
  7165. 'z': True,
  7166. ' ': True,
  7167. }
  7168. line = "A quick brown fox jumps over the lazy dog"</p>
  7169. <p>for s in line:
  7170. lower_case = s.lower()
  7171. if lower_case not in alphabet:
  7172. print(lower_case + " is not in the alphabet")
  7173. break
  7174. ```</p>
  7175. <p>are two strings equal</p>
  7176. <p>```
  7177. def equal(a,b):
  7178. if len(a) != len(b):
  7179. return False
  7180. for i in range(len(a)):
  7181. if a[i] != b[i]:
  7182. return False
  7183. return True</p>
  7184. <p>print(equal("hello","world"))
  7185. print(equal("hello","hello"))
  7186. print(equal("hello","roblox"))
  7187. ```</p>
  7188. <p>are two lists of integers equal:</p>
  7189. <p>```
  7190. def equal(a,b):
  7191. if len(a) != len(b):
  7192. return False
  7193. for i in range(len(a)):
  7194. if a[i] != b[i]:
  7195. return False
  7196. return True</p>
  7197. <p>print(equal([1,2,3],[1,2,3,4]))
  7198. print(equal([1,2,3],[1,2,3]))
  7199. ```</p>
  7200. <p>are two dictionaries equal</p>
  7201. <p>```
  7202. def equal(a,b):</p>
  7203. <pre><code>for k in a:
  7204. if k not in b:
  7205. return False
  7206. if a[k] != b[k]:
  7207. return False
  7208. for k in b:
  7209. if k not in a:
  7210. return False
  7211. if b[k] != a[k]:
  7212. return False
  7213. return True
  7214. </code></pre>
  7215. <p>print(equal({'a':'hello','b':'world'},{'a':'hello','b':'world'}))
  7216. print(equal({'a':'hello','b':'world'},{'a':'hello','b':'earth'}))
  7217. print(equal({'a':'hello','roblox': True},{'a':'hello', 'roblox': False}))
  7218. print(equal({'a':'hello','b':'world','roblox': True},{'a':'hello','b':'world'}))
  7219. ```</p>
  7220. <h2>[DAY-109] Touch Typing Day</h2>
  7221. <p>Touchtyping day!</p>
  7222. <h2>[DAY-110] Find Code on TikTok</h2>
  7223. <p><img alt="game-109.png" src="./screenshots/game-109.png" title="game 109 screenshot" /></p>
  7224. <p>follow zippycode on tiktok https://www.tiktok.com/@zippycode
  7225. try some of their ideas, like:</p>
  7226. <p><code>from turtle import *
  7227. bgcolor('black')
  7228. n = 0
  7229. colormode(255)
  7230. while n &lt; 200:
  7231. right(n)
  7232. forward(n*3)
  7233. color(n,255-n,n%30*8)
  7234. n+=1</code></p>
  7235. <p><code>from turtle import *
  7236. color('green')
  7237. speed(11)
  7238. i = 0
  7239. while True:
  7240. circle(i*1.5)
  7241. right(4)
  7242. i+=1</code></p>
  7243. <h2>[DAY-111] Lists; Random</h2>
  7244. <p><img alt="game-110.png" src="./screenshots/game-110.png" title="game 110 screenshot" /></p>
  7245. <p>```
  7246. import pgzrun
  7247. import random</p>
  7248. <p>WIDTH = 400
  7249. HEIGHT = 400
  7250. fox = Actor("c1")
  7251. fox.x = WIDTH/2
  7252. fox.y =HEIGHT/2</p>
  7253. <p>other = [
  7254. Actor("c2", pos=(100,100)),
  7255. Actor("c2", pos=(100,300)),
  7256. Actor("c2",pos=(300,300)),
  7257. Actor("c2",pos=(300,100))
  7258. ]</p>
  7259. <p>def update():
  7260. if keyboard.left:
  7261. for o in other:
  7262. o.x += 5
  7263. if keyboard.right:
  7264. for o in other:
  7265. o.x -= 5
  7266. if keyboard.up:
  7267. for o in other:
  7268. o.y += 5
  7269. if keyboard.down:
  7270. for o in other:
  7271. o.y -= 5</p>
  7272. <pre><code>for o in list(other):
  7273. if o.colliderect(fox):
  7274. other.remove(o)
  7275. if len(other) &lt; 4:
  7276. other.append(Actor("c2",pos=(random.randint(10,WIDTH-10), random.randint(10,HEIGHT-10))))
  7277. for o in other:
  7278. o.y -=1
  7279. </code></pre>
  7280. <p>def draw():
  7281. screen.clear()
  7282. screen.fill("deepskyblue")
  7283. fox.draw()
  7284. for o in other:
  7285. o.draw()
  7286. pgzrun.go()
  7287. ```</p>
  7288. <h2>[DAY-112] Use Simple Dictionary</h2>
  7289. <p>Count the words in a song</p>
  7290. <p>```
  7291. song = """There once was a ship that put to sea
  7292. The name of the ship was the Billy of Tea
  7293. The winds blew up, her bow dipped down
  7294. O blow, my bully boys, blow (huh)
  7295. She had not been two weeks from shore
  7296. When down on her a right whale bore
  7297. The captain called all hands and swore
  7298. He'd take that whale in tow (huh)
  7299. Soon may the Wellerman come
  7300. To bring us sugar and tea and rum (hey)
  7301. One day, when the tonguin' is done
  7302. We'll take our leave and go
  7303. Take our leave and go
  7304. Soon may the Wellerman come
  7305. To bring us sugar and tea and rum
  7306. One day, when the tonguin' is done
  7307. We'll take our leave and go
  7308. Before the boat had hit the water
  7309. The whale's tail came up and caught her
  7310. All hands to the side harpooned and fought her
  7311. When she dived down below (huh)
  7312. She had not been two weeks from shore
  7313. When down on her a right whale bore
  7314. The captain called all hands and swore
  7315. He'd take that whale in tow (huh)
  7316. Soon may the Wellerman come
  7317. To bring us sugar and tea and rum (hey)
  7318. One day, when the tonguin' is done
  7319. We'll take our leave and go
  7320. Take our leave and go
  7321. Soon may the Wellerman come
  7322. To bring us sugar and tea and rum
  7323. One day, when the tonguin' is done
  7324. We'll take our leave and go
  7325. Soon may the Wellerman come
  7326. To bring us sugar and tea and rum (hey)
  7327. One day, when the tonguin' is done
  7328. We'll take our leave and go
  7329. Take our leave and go
  7330. Take our leave and go
  7331. """</p>
  7332. <p>words = {}
  7333. word = ''
  7334. for c in song:
  7335. if c == ' ' or c == '\n':
  7336. if word not in words:
  7337. words[word] = 1
  7338. else:
  7339. words[word] += 1
  7340. word = ''
  7341. else:
  7342. word += c</p>
  7343. <p>for word in words:
  7344. print(words[word],word)
  7345. ```</p>
  7346. <p>This program has a bug, if the file does not end with empty line, it wont count the last word.</p>
  7347. <p>Print the length:</p>
  7348. <p><code>...
  7349. l = 0
  7350. for c in song:
  7351. l += 1
  7352. print(l)
  7353. print(len(song))</code></p>
  7354. <h2>[DAY-113] Discover Pythontutor</h2>
  7355. <p>use https://pythontutor.com/visualize.html with the folloowing code:</p>
  7356. <p>```
  7357. song = """Soon may the Wellerman come
  7358. To bring us sugar and tea and rum (hey)
  7359. One day, when the tonguin' is done
  7360. We'll take our leave and go
  7361. Take our leave and go
  7362. Soon may the Wellerman come
  7363. To bring us sugar and tea and rum (hey)
  7364. One day, when the tonguin' is done
  7365. """</p>
  7366. <p>words = {}
  7367. word = ''
  7368. for c in song:
  7369. if c == ' ' or c == '\n':
  7370. if word not in words:
  7371. words[word] = 1
  7372. else:
  7373. words[word] += 1
  7374. word = ''
  7375. else:
  7376. word += c</p>
  7377. <p>for word in words:
  7378. print(words[word],word)</p>
  7379. <p>```</p>
  7380. <p><img alt="game-113-a.png" src="./screenshots/game-113-a.png" title="game 113-a screenshot" />
  7381. <img alt="game-113-b.png" src="./screenshots/game-113-b.png" title="game 113-b screenshot" /></p>
  7382. <p>try it with other programs as well.</p>
  7383. <h2>[DAY-114] Simple Turtle</h2>
  7384. <p><img alt="game-114.png" src="./screenshots/game-114.png" title="game 114 screenshot" /></p>
  7385. <p>random walk</p>
  7386. <p>```
  7387. from turtle import *
  7388. from random import randint,choice</p>
  7389. <p>colors = ['red','deepskyblue','lawngreen']</p>
  7390. <p>screen = Screen()
  7391. width, height = screen.window_width(), screen.window_height()</p>
  7392. <p>pensize(5)
  7393. speed(20)</p>
  7394. <p>while True:
  7395. pencolor(choice(colors))
  7396. setheading(randint(0,360))
  7397. forward(randint(1,100))
  7398. (x,y) = pos()
  7399. if x &gt; width/2 or y &gt; height/2 or x &lt; -width/2 or y &lt; -height/2:
  7400. setpos(0,0)</p>
  7401. <p>```</p>
  7402. <h2>[DAY-115] Practical Coding, Control Roblox with python</h2>
  7403. <p><img alt="game-115.png" src="./screenshots/game-115.jpg" title="game 115 screenshot" /></p>
  7404. <p>Control Roblox with python</p>
  7405. <p>NB: That might be considered cheating, even though its just for fun, so be ready to get your account banned.</p>
  7406. <p>First <code>pip install pyautogui</code> and <code>pip install pydirectinput</code>.</p>
  7407. <p>```
  7408. import pyautogui
  7409. import pydirectinput
  7410. import time</p>
  7411. <p>time.sleep(2)</p>
  7412. <p>while True:
  7413. for key in ['w','a','s','d']:
  7414. print('executing',key)
  7415. pydirectinput.keyDown(key)
  7416. time.sleep(1.6)
  7417. pydirectinput.keyUp(key)
  7418. time.sleep(0.5)
  7419. ```</p>
  7420. <p>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.</p>
  7421. <p>After you start the program, you have 2 seconds to click on Roblox otherwise the sequence will be wrong</p>
  7422. <h2>[DAY-116] Many Turtles</h2>
  7423. <p>Many Turtles.</p>
  7424. <p>The ideas are borrowed from <a href="https://notes.ayushsharma.in/2019/06/rediscovering-logo-with-bob-the-turtle">Redisovering Logo with Bob the Turtle</a>, Ayush Sharma's amazing blog post!</p>
  7425. <p><img alt="game-116-a.png" src="./screenshots/game-116-a.png" title="game 116-a screenshot" /></p>
  7426. <p>```
  7427. import turtle</p>
  7428. <p>turtle.setup(width=800, height=800)</p>
  7429. <p>bob = turtle.Turtle(shape='turtle')
  7430. bob.color('orange')
  7431. bob.speed(3000)</p>
  7432. <p>alice = turtle.Turtle(shape='turtle')
  7433. alice.color('lawngreen')
  7434. alice.speed(3000)</p>
  7435. <p>for i in range(500):</p>
  7436. <pre><code>bob.forward(i)
  7437. bob.left(91)
  7438. alice.backward(i)
  7439. alice.right(91)
  7440. </code></pre>
  7441. <p>turtle.exitonclick()
  7442. ```</p>
  7443. <p>even more turtles</p>
  7444. <p><img alt="game-116-b.png" src="./screenshots/game-116-b.png" title="game 116-b screenshot" /></p>
  7445. <p>```
  7446. import turtle</p>
  7447. <p>turtle.setup(width=800, height=800)</p>
  7448. <p>bob = turtle.Turtle(shape='turtle')
  7449. bob.color('orange')
  7450. bob.speed(3000)</p>
  7451. <p>alice = turtle.Turtle(shape='turtle')
  7452. alice.color('lawngreen')
  7453. alice.speed(3000)</p>
  7454. <p>charlie = turtle.Turtle(shape='turtle')
  7455. charlie.color('deepskyblue')
  7456. charlie.speed(3000)</p>
  7457. <p>for i in range(500):</p>
  7458. <pre><code>bob.forward(i)
  7459. bob.left(91)
  7460. alice.backward(i)
  7461. alice.right(91)
  7462. charlie.forward(i)
  7463. charlie.right(101)
  7464. </code></pre>
  7465. <p>turtle.exitonclick()
  7466. ```</p>
  7467. <p>```
  7468. import turtle
  7469. turtle.setup(width=800, height=800)</p>
  7470. <p>bob = turtle.Turtle(shape='turtle')
  7471. bob.color('orange')</p>
  7472. <p>alice = turtle.Turtle(shape='turtle')
  7473. alice.color('lawngreen')
  7474. angle = 10
  7475. while True:
  7476. alice.backward(20)
  7477. bob.forward(20)
  7478. alice.right(angle)
  7479. bob.left(angle)
  7480. angle += 1
  7481. ```</p>
  7482. <p>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 <code>turtle.Turtle()</code> 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 <code>forward</code> <code>up</code> and etc coming from the blueprint and each of those methods work on the instance itself.</p>
  7483. <h2>[DAY-117] Another Text Editor</h2>
  7484. <p><img alt="game-117.png" src="./screenshots/game-117.png" title="game 117 screenshot" /></p>
  7485. <p>And lets discuss another text editor.</p>
  7486. <p>(if you are on windows make sure you <code>pip3 install windows-curses</code>)</p>
  7487. <p>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.</p>
  7488. <p>First show some text:</p>
  7489. <p>```
  7490. import curses
  7491. import time</p>
  7492. <p>screen = curses.initscr()
  7493. screen.addstr(0, 0, "hello world",curses.A_NORMAL)
  7494. screen.refresh()</p>
  7495. <p>time.sleep(2)
  7496. ```</p>
  7497. <p>Capture input and modify the text:</p>
  7498. <p>```
  7499. import curses</p>
  7500. <p>screen = curses.initscr()
  7501. text = ''
  7502. while True:
  7503. screen.addstr(0, 0, text,curses.A_NORMAL)
  7504. screen.refresh()</p>
  7505. <pre><code>c = screen.getch()
  7506. text += chr(c)
  7507. </code></pre>
  7508. <p>```</p>
  7509. <p>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.</p>
  7510. <p>Hint: use <code>text += str(c)</code> to actually see the codes you need.</p>
  7511. <p>```
  7512. import curses
  7513. import sys</p>
  7514. <p>screen = curses.initscr()
  7515. curses.curs_set(2)</p>
  7516. <p>if len(sys.argv) != 2:
  7517. print("usage:")
  7518. print(sys.argv[0] + " filename")
  7519. sys.exit(1)</p>
  7520. <p>text = ''
  7521. try:
  7522. file = open(sys.argv[1],"r")
  7523. text = file.read()
  7524. file.close()
  7525. except:
  7526. pass</p>
  7527. <p>status = 'file: ' + sys.argv[1]
  7528. while True:
  7529. screen.clear()
  7530. screen.addstr(0, 0, status + ' (len: ' + str(len(text)) + ')',curses.A_NORMAL)
  7531. screen.addstr(2, 0, text,curses.A_NORMAL)
  7532. screen.refresh()</p>
  7533. <pre><code>c = screen.getch()
  7534. if c == 3:
  7535. # quit Ctrl+C
  7536. break
  7537. if c == 19:
  7538. # save Ctrl+S
  7539. file = open(sys.argv[1],"w")
  7540. file.write(text)
  7541. file.close()
  7542. status = 'file: ' + sys.argv[1]
  7543. screen.addstr(0, 0, text,curses.A_NORMAL)
  7544. continue
  7545. if c == 8:
  7546. # backspace
  7547. if len(text) &gt; 0:
  7548. text = text[:len(text)-1]
  7549. continue
  7550. if (c &lt; 127 and c &gt; 30) or c == 10:
  7551. text += chr(c)
  7552. status = 'file: ' + sys.argv[1] + " (modified)"
  7553. </code></pre>
  7554. <p>```</p>
  7555. <h2>[DAY-118] Search Lyrics</h2>
  7556. <p>Search for your favorite lyrics, dont forget to <code>pip3 install lyricsgenius</code></p>
  7557. <p><code>import lyricsgenius
  7558. genius = lyricsgenius.Genius('get api key from genius.com')
  7559. genius.verbose = False
  7560. while True:
  7561. artist = input("🔥 Artist: ")
  7562. song_name = input("🔥 Song: ")
  7563. song = genius.search_song(song_name, artist)
  7564. if song == None:
  7565. print(song_name + " / " + artist + " not found")
  7566. else:
  7567. print('-' * 40)
  7568. print(song.lyrics)
  7569. print('-' * 40)</code></p>
  7570. <h2>[DAY-119] Facial Recognition; Move 78</h2>
  7571. <p><img alt="game-119.png" src="./screenshots/game-119.png" title="game 119 screenshot" /></p>
  7572. <p>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.</p>
  7573. <p>Recognize that if it is cheap and easy, it is done to you.</p>
  7574. <p>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.</p>
  7575. <p>They only need 1 picture.</p>
  7576. <p>If you are not paying, you are the product.</p>
  7577. <p>It is also not very easy to be tricked with mascara.</p>
  7578. <p><img alt="game-119-a.png" src="./screenshots/game-119-a.png" title="game 119a screenshot" />
  7579. <img alt="game-119-b.png" src="./screenshots/game-119-b.png" title="game 119b screenshot" />
  7580. <img alt="game-119-c.png" src="./screenshots/game-119-c.png" title="game 119c screenshot" /></p>
  7581. <p>even thought it was easy in 2014, https://www.theatlantic.com/technology/archive/2014/07/makeup/374929/</p>
  7582. <h2>[DAY-120] Program on your own form a book</h2>
  7583. <p>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.</p>
  7584. <p>Write down your experience and what you struggle with.</p>
  7585. <p>Simple ping pong game</p>
  7586. <p>```
  7587. import pgzrun
  7588. import random</p>
  7589. <p>HEIGHT = 600
  7590. WIDTH = 600</p>
  7591. <p>elf = Actor('c1')
  7592. king = Actor('c2')
  7593. ball = Actor('bullet')</p>
  7594. <p>king.y = HEIGHT/2
  7595. elf.y = HEIGHT/2
  7596. elf.x = WIDTH-10
  7597. ball.x = WIDTH/2
  7598. ball.y = HEIGHT/2
  7599. d = 1
  7600. game_over = False
  7601. speed = 1
  7602. def update():
  7603. global d,game_over,speed
  7604. if keyboard.up:
  7605. elf.y -= 5
  7606. if keyboard.down:
  7607. elf.y += 5
  7608. if keyboard.S:
  7609. king.y += 5
  7610. if keyboard.W:
  7611. king.y -= 5</p>
  7612. <pre><code>if ball.x &lt; 0 or ball.x &gt; WIDTH:
  7613. game_over = True
  7614. if d == 1:
  7615. ball.x += speed
  7616. else:
  7617. ball.x -= speed
  7618. if elf.colliderect(ball):
  7619. d = 0
  7620. ball.y = random.randint(10,HEIGHT-10)
  7621. speed += 1
  7622. if king.colliderect(ball):
  7623. d = 1
  7624. ball.y = random.randint(10,HEIGHT-10)
  7625. speed += 1
  7626. </code></pre>
  7627. <p>def draw():
  7628. screen.clear()
  7629. screen.fill("deepskyblue")</p>
  7630. <pre><code>elf.draw()
  7631. king.draw()
  7632. ball.draw()
  7633. if game_over:
  7634. screen.fill('red')
  7635. </code></pre>
  7636. <p>pgzrun.go()
  7637. ```</p>
  7638. <h2>[DAY-121] Scam Check List</h2>
  7639. <p>Scams.. Scams everywhere.</p>
  7640. <p>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.</p>
  7641. <p>Follow this list:</p>
  7642. <ul>
  7643. <li>Always Think Sus</li>
  7644. <li>Call your parents</li>
  7645. <li>If you cant reach your parents, call adult you know</li>
  7646. <li>If you cant reach adult you know, go and find a mother with a child, they are the safest to talk to.</li>
  7647. <li>If you can not find any adult to help hang up.</li>
  7648. <li>If you think it is serious and you must act, hang up, and <em>you</em> 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 <em>you</em> call them and ask what is going on.</li>
  7649. </ul>
  7650. <p>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.</p>
  7651. <h2>[DAY-122] Lists; Random; Mutate</h2>
  7652. <p>Hide and Seek</p>
  7653. <p>Ask someone to count to 10, then you hide, and ask him to find you</p>
  7654. <p><img alt="game-122-a.png" src="./screenshots/game-122-a.png" title="game 122a screenshot" /></p>
  7655. <p>```
  7656. import pgzrun
  7657. import random
  7658. HEIGHT = 600
  7659. WIDTH = 600</p>
  7660. <p>elf = Actor('c1')
  7661. elf.x = 20
  7662. elf.y = random.randint(0,HEIGHT)</p>
  7663. <p>def update():
  7664. if keyboard.UP:
  7665. elf.y -= 5
  7666. if keyboard.DOWN:
  7667. elf.y += 5
  7668. if keyboard.RIGHT:
  7669. elf.x += 5
  7670. if keyboard.LEFT:
  7671. elf.x -= 5</p>
  7672. <p>def draw():
  7673. elf.draw()</p>
  7674. <p>pgzrun.go()</p>
  7675. <p>```</p>
  7676. <p><img alt="game-122-b.png" src="./screenshots/game-122-b.png" title="game 122b screenshot" /></p>
  7677. <p>Practice walking over a list with <code>for i in range(len(x))</code> and <code>for item in x</code>.</p>
  7678. <p>```
  7679. import pgzrun
  7680. import random
  7681. HEIGHT = 600
  7682. WIDTH = 600</p>
  7683. <p>elf = Actor('c1')
  7684. king = Actor('c2')
  7685. elf.x = 20
  7686. elf.y = random.randint(0,HEIGHT)
  7687. king.y = random.randint(0,HEIGHT)
  7688. king.x = WIDTH-20</p>
  7689. <p>things = []</p>
  7690. <p>def add_new_obsticle(l):
  7691. image = random.choice(["snake","bullet","flower","rock"])
  7692. x = Actor(image)
  7693. x.x = random.randint(0,WIDTH)
  7694. x.y = random.randint(0,HEIGHT)
  7695. l.append(x)</p>
  7696. <p>for i in range(10):
  7697. add_new_obsticle(things)</p>
  7698. <p>def update():
  7699. if keyboard.UP:
  7700. elf.y -= 5
  7701. if keyboard.DOWN:
  7702. elf.y += 5
  7703. if keyboard.RIGHT:
  7704. elf.x += 5
  7705. if keyboard.LEFT:
  7706. elf.x -= 5</p>
  7707. <pre><code>if keyboard.W:
  7708. king.y -= 5
  7709. if keyboard.S:
  7710. king.y += 5
  7711. if keyboard.D:
  7712. king.x += 5
  7713. if keyboard.A:
  7714. king.x -= 5
  7715. for s in range(len(things)):
  7716. if things[s].colliderect(elf):
  7717. elf.image = things[s].image
  7718. if king.colliderect(elf):
  7719. king.image = "c3"
  7720. </code></pre>
  7721. <p>def draw():
  7722. screen.fill('azure')
  7723. king.draw()
  7724. elf.draw()
  7725. for thing in things:
  7726. thing.draw()</p>
  7727. <p>pgzrun.go()
  7728. ```</p>
  7729. <h2>[DAY-123] Lists; Callbacks</h2>
  7730. <p><img alt="game-123.png" src="./screenshots/game-123.png" title="game 123 screenshot" /></p>
  7731. <p>a bit more complicated game</p>
  7732. <p>```
  7733. import pgzrun
  7734. import random
  7735. from itertools import cycle
  7736. WIDTH = 300
  7737. HEIGHT = 300
  7738. game_over = False
  7739. player = Actor("c1", pos=((WIDTH/2), (HEIGHT-16)), anchor=("center","bottom"))
  7740. obsticles = []</p>
  7741. <p>def jump_up(jumper):
  7742. sounds.jump.play()
  7743. animate(jumper, tween='decelerate', duration=0.3, pos=(jumper.x, jumper.y - 16),on_finished=lambda: jump_down(jumper))</p>
  7744. <p>def jump_down(jumper):
  7745. animate(jumper, tween='accelerate', duration=0.3, pos=(jumper.x, HEIGHT-16))</p>
  7746. <p>def on_key_down(key):
  7747. if key == keys.SPACE:
  7748. jump_up(player)</p>
  7749. <p>def make_obsticles():
  7750. for i in range(0, 5 - len(obsticles)):
  7751. # check if colliding, add random + 20 to it
  7752. actor = Actor(random.choice(["o1","o2","o3","o4","o5","o6","o7","o8","o9","o10","o11"]), anchor=("center","bottom"))
  7753. actor.x = WIDTH + 40 + random.randint(10, WIDTH*2)
  7754. actor.y = HEIGHT - 16
  7755. while True:
  7756. actor.x += random.randint(30, 50)
  7757. conflict = False
  7758. for o in obsticles:
  7759. if o.colliderect(actor):
  7760. conflict = True
  7761. if not conflict:
  7762. break</p>
  7763. <pre><code> obsticles.append(actor)
  7764. </code></pre>
  7765. <p>def update():
  7766. global game_over</p>
  7767. <pre><code>if len(obsticles) &lt; 5:
  7768. make_obsticles()
  7769. for o in list(obsticles):
  7770. # shrink the collision rects so the game is more fun to play
  7771. if o.inflate(-4,-4).colliderect(player.inflate(-16,-16)):
  7772. game_over = True
  7773. # remove the obsticles out of screen
  7774. o.x -= 2
  7775. if o.x &lt; -10:
  7776. obsticles.remove(o)
  7777. </code></pre>
  7778. <h1>player animation</h1>
  7779. <h1>we just change the image of the actor every 0.4 seconds</h1>
  7780. <p>poses = cycle(["player/tiles-46","player/tiles-47","player/tiles-48","player/tiles-49","player/tiles-50","player/tiles-51"])
  7781. def make_actor_move():
  7782. player.image = next(poses)
  7783. clock.schedule_interval(make_actor_move, 0.4)</p>
  7784. <p>def draw():
  7785. screen.fill("black")
  7786. player.draw()
  7787. for o in obsticles:
  7788. o.draw()</p>
  7789. <pre><code>for i in range(100):
  7790. screen.blit('floor',(i * 16, HEIGHT - 16))
  7791. if game_over:
  7792. screen.fill("red")
  7793. </code></pre>
  7794. <p>pgzrun.go()</p>
  7795. <p>```</p>
  7796. <h2>[DAY-124] BMP format, Images; Encoding/Decoding</h2>
  7797. <p>Images</p>
  7798. <p>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.</p>
  7799. <p>Open images/joshi-100.bmp and you will see: </p>
  7800. <p><img alt="joshi-100.bmp" src="./images/joshi-100.bmp" title="joshi" /> </p>
  7801. <p>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.</p>
  7802. <p>first just print the bytes:</p>
  7803. <p>```
  7804. file = open("images/joshi-100.bmp","rb")
  7805. data = file.read()
  7806. file.close()</p>
  7807. <p>for b in data:
  7808. print("%3d" % b,end='')
  7809. ```</p>
  7810. <p>now lets print them in specific order:</p>
  7811. <p>```
  7812. file = open("images/joshi-100.bmp","rb")
  7813. data = file.read()
  7814. file.close()</p>
  7815. <p>width = 100
  7816. height = 106
  7817. offset = 54</p>
  7818. <p>for y in range(width):
  7819. for x in range(height):
  7820. off = offset + ((y * width + x) * 4)
  7821. print("%3d" % data[off+2],end='')
  7822. print()
  7823. ```</p>
  7824. <p><img alt="game-124.png" src="./screenshots/game-124.png" title="game 124 screenshot" /></p>
  7825. <p>looks familiar!</p>
  7826. <p>The image itself actually contains information about how big it is, and where the data starts, it is specified in the bitmap format itself.</p>
  7827. <p>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</p>
  7828. <p>| Name | Size | Offset | Description |
  7829. | - | - | - | - |
  7830. | <strong>Header</strong> | 14 bytes | | Windows Structure: BITMAPFILEHEADER |
  7831. | Signature | 2 bytes | 0000h | 'BM' |
  7832. | FileSize | 4 bytes | 0002h | File size in bytes |
  7833. | reserved | 4 bytes | 0006h | unused (=0) |
  7834. | DataOffset | 4 bytes | 000Ah | Offset from beginning of file to the beginning of the bitmap data |
  7835. | <strong>InfoHeader</strong> | 40 bytes | | Windows Structure: BITMAPINFOHEADER |
  7836. | Size | 4 bytes | 000Eh | Size of InfoHeader =40 |
  7837. | Width | 4 bytes | 0012h | Horizontal width of bitmap in pixels |
  7838. | Height | 4 bytes | 0016h | Vertical height of bitmap in pixels |
  7839. | Planes | 2 bytes | 001Ah | Number of Planes (=1) |
  7840. | 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 |
  7841. | 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 |
  7842. | ImageSize | 4 bytes | 0022h | (compressed) Size of Image <br>It is valid to set this =0 if Compression = 0 |
  7843. | XpixelsPerM | 4 bytes | 0026h | horizontal resolution: Pixels/meter |
  7844. | YpixelsPerM | 4 bytes | 002Ah | vertical resolution: Pixels/meter |
  7845. | Colors Used | 4 bytes | 002Eh | Number of actually used colors. For a 8-bit / pixel bitmap this will be 100h or 256. |
  7846. | Important Colors | 4 bytes | 0032h | Number of important colors <br>0 = all |
  7847. | <strong>ColorTable</strong> | 4 * NumColors bytes | 0036h | present only if Info.BitsPerPixel less than 8 <br>colors should be ordered by importance |
  7848. | Red | 1 byte | | Red intensity |
  7849. | Green | 1 byte | | Green intensity |
  7850. | Blue | 1 byte | | Blue intensity |
  7851. | reserved | 1 byte | | unused (=0) |
  7852. | repeated NumColors times |
  7853. | <strong>Pixel Data</strong> | InfoHeader.ImageSize bytes | | The image data</p>
  7854. <p>Now using the header information, we can get the width, height and data offset directly from there:</p>
  7855. <p>```
  7856. file = open("images/joshi-100.bmp","rb")
  7857. data = file.read()
  7858. file.close()</p>
  7859. <p>offset = int.from_bytes(data[10:14], byteorder='little')
  7860. width = int.from_bytes(data[18:22], byteorder='little')
  7861. height = int.from_bytes(data[22:26], byteorder='little')</p>
  7862. <p>for y in range(width):
  7863. for x in range(height):
  7864. off = offset + ((y * width + x) * 4)
  7865. print("%3d" % data[off+2],end='')
  7866. print()
  7867. ```</p>
  7868. <p>You see when we read <code>data[10:14]</code> we want to skip <code>signature</code> (2 bytes), <code>file size</code> (4 bytes) and <code>reserved</code> (4 bytes) and read exactly 4 bytes after that.
  7869. And we can make 4 bytes into a integer with <code>int.from_bytes</code>. We will get into that later. For now the important thing to focus on is the format itself.</p>
  7870. <p>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.</p>
  7871. <h2>[DAY-125] Lists; Dictionaries</h2>
  7872. <p><img alt="game-125-a.png" src="./screenshots/game-125-a.png" title="game 125 a screenshot" />
  7873. <img alt="game-125-b.png" src="./screenshots/game-125-b.png" title="game 125 b screenshot" />
  7874. <img alt="game-125-c.png" src="./screenshots/game-125-c.png" title="game 125 c screenshot" />
  7875. <img alt="game-125-d.png" src="./screenshots/game-125-d.png" title="game 125 d screenshot" /></p>
  7876. <p>Write code to destroy your enemies!</p>
  7877. <p>You have access to your <code>heroes</code> and <code>enemies</code> positions. When you collide you destroy each other.</p>
  7878. <p>```
  7879. import pgzrun
  7880. import random
  7881. from itertools import cycle</p>
  7882. <p>WIDTH=600
  7883. HEIGHT=600</p>
  7884. <p>enemies = []
  7885. heroes = []</p>
  7886. <p>text = """
  7887. for h in heroes:
  7888. h.x += random.randint(-10,10)
  7889. h.y += random.randint(-10,10)
  7890. """</p>
  7891. <p>enemy_programs = cycle([
  7892. """
  7893. i = 0
  7894. for e in enemies:
  7895. e.x = i * 10
  7896. e.y = i * 10
  7897. i += 1
  7898. """,
  7899. """
  7900. for e in enemies:
  7901. e.x += random.randint(-10,10)
  7902. e.y += random.randint(-10,10)
  7903. """,
  7904. """
  7905. for e in enemies:
  7906. (x,y) = random.choice(heroes)
  7907. e.x = x
  7908. e.y = y
  7909. """
  7910. ])</p>
  7911. <p>enemy_code = None</p>
  7912. <p>def reset():
  7913. global heroes, enemies, enemy_code
  7914. enemy_code = next(enemy_programs)
  7915. enemies = []
  7916. heroes = []
  7917. for i in range(20):
  7918. enemies.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))
  7919. heroes.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))</p>
  7920. <p>def on_key_down(key, mod, unicode):
  7921. global text, pause, score_words, score
  7922. if key == keys.BACKSPACE:
  7923. if mod == 1024 or mod == 256:
  7924. text = ''
  7925. if len(text) &gt; 0:
  7926. text = text[:-1]
  7927. elif key == keys.SPACE:
  7928. text += ' '
  7929. elif key == keys.TAB:
  7930. text += ' ' <br />
  7931. elif key == keys.RETURN:
  7932. text += '\n' <br />
  7933. elif len(unicode) &gt; 0 and ord(unicode) &gt;= 34 and ord(unicode) &lt;= 126:
  7934. text += unicode</p>
  7935. <p>def run_code():
  7936. try:
  7937. enemy_positions = []
  7938. for e in enemies:
  7939. enemy_positions.append((e.x, e.y))
  7940. hero_positions = []
  7941. for h in heroes:
  7942. hero_positions.append((e.x, e.y)) <br />
  7943. exec(text, {"heroes": heroes,"random":random, "enemies": enemy_positions})
  7944. exec(enemy_code, {"enemies": enemies, "random":random, "heroes": hero_positions})</p>
  7945. <pre><code> for h in list(heroes):
  7946. collided = False
  7947. for e in list(enemies):
  7948. if e.colliderect(h):
  7949. enemies.remove(e)
  7950. if collided:
  7951. heroes.remove(h)
  7952. if len(enemies) &lt; 50:
  7953. enemies.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))
  7954. heroes.append(Rect(random.randint(0,WIDTH),random.randint(0,HEIGHT), 10, 10))
  7955. if len(enemies) &lt; 5:
  7956. reset()
  7957. except Exception as err:
  7958. print(err)
  7959. pass
  7960. </code></pre>
  7961. <p>reset()</p>
  7962. <p>clock.schedule_interval(run_code, 1)
  7963. def draw():
  7964. screen.fill("black")</p>
  7965. <pre><code>screen.draw.text("heroes: " + str(len(heroes)) + " enemies: " + str(len(enemies)), (0, 0), align='left',fontname="437-win", fontsize=20)
  7966. for (i,l) in enumerate(enemy_code.split('\n')):
  7967. screen.draw.text(l, (0, (20 + (i * 16))), align='left',fontname="437-win", fontsize=14)
  7968. for (i,l) in enumerate(text.split('\n')):
  7969. screen.draw.text(l, (0, (HEIGHT - 200 + (i * 16))), align='left',fontname="437-win", fontsize=14)
  7970. for e in enemies:
  7971. screen.draw.rect(e, (255,0,0))
  7972. for h in heroes:
  7973. screen.draw.rect(h, (0,255,255))
  7974. </code></pre>
  7975. <p>pgzrun.go()
  7976. ```</p>
  7977. <h2>[DAY-126] Read/Write File</h2>
  7978. <p><img alt="game-126.png" src="./screenshots/game-126.png" title="game 126 screenshot" /></p>
  7979. <p>Save and load the position of the elf</p>
  7980. <p>Play hide and seek after that!</p>
  7981. <p>```
  7982. import pgzrun</p>
  7983. <p>HEIGHT = 600
  7984. WIDTH = 600</p>
  7985. <p>elf = Actor('c1')
  7986. elf.x = WIDTH/2
  7987. elf.y = HEIGHT/2</p>
  7988. <p>def update():
  7989. if keyboard.UP:
  7990. elf.y -= 5
  7991. if keyboard.LEFT:
  7992. elf.x -= 5
  7993. if keyboard.RIGHT:
  7994. elf.x += 5
  7995. if keyboard.DOWN:
  7996. elf.y += 5
  7997. if keyboard.S:
  7998. f = open('save','w')
  7999. f.write('MAGIC HEADER\n' + str(elf.x) + '\n' + str(elf.y) + '\n')
  8000. f.close()
  8001. if keyboard.B:
  8002. f = open("save","r")
  8003. lines = f.readlines()
  8004. if (lines[0].startswith('MAGIC HEADER')):
  8005. elf.x = float(lines[1])
  8006. elf.y = float(lines[2])
  8007. f.close()</p>
  8008. <p>def draw():
  8009. elf.draw()
  8010. pgzrun.go()
  8011. ```</p>
  8012. <h2>[DAY-127] Callbacks; Schedule Interval</h2>
  8013. <p>super short, make the actor walk</p>
  8014. <p>```
  8015. from itertools import cycle
  8016. import pgzrun</p>
  8017. <p>WIDTH=200
  8018. HEIGHT=200</p>
  8019. <p>elf = Actor("c1")
  8020. elf.x = WIDTH/2
  8021. elf.y = HEIGHT/2</p>
  8022. <p>poses = cycle(["player/tiles-46","player/tiles-47","player/tiles-48","player/tiles-49","player/tiles-50","player/tiles-51"])</p>
  8023. <p>def make_actor_move():
  8024. elf.image = next(poses)
  8025. clock.schedule_interval(make_actor_move, 0.4)</p>
  8026. <p>def draw():
  8027. screen.fill("black")
  8028. elf.draw()</p>
  8029. <p>pgzrun.go()</p>
  8030. <p>```</p>
  8031. <h2>[DAY-128] Lists; CPU usage; Resources</h2>
  8032. <p><img alt="game-128.png" src="./screenshots/game-128.png" title="game 128 screenshot" /></p>
  8033. <p>See how slow you can make your computer, by making it draw 100 000 actors 60 times per second.</p>
  8034. <p>See how slow it moves, open the activity monitor or the task manager to see how it eats all your resources.</p>
  8035. <p>After that chabnge it to 100 actors and see the difference.</p>
  8036. <p>```
  8037. import random
  8038. import pgzrun</p>
  8039. <p>WIDTH = 800
  8040. HEIGHT = 800</p>
  8041. <p>actors = []
  8042. for i in range(0, 100000):
  8043. elf = Actor("c1")
  8044. elf.x = WIDTH/2
  8045. elf.y = HEIGHT/2
  8046. actors.append(elf)</p>
  8047. <p>def update():
  8048. if keyboard.UP:
  8049. for i in range(0, len(actors)):
  8050. a = actors[i]
  8051. a.y -= i
  8052. if keyboard.DOWN:
  8053. for i in range(0, len(actors)):
  8054. a = actors[i]
  8055. a.y += i
  8056. if keyboard.LEFT:
  8057. for i in range(0, len(actors)):
  8058. a = actors[i]
  8059. a.x -= i
  8060. if keyboard.RIGHT:
  8061. for i in range(0, len(actors)):
  8062. a = actors[i]
  8063. a.x += i</p>
  8064. <p>def draw():
  8065. screen.fill("black")
  8066. for a in actors:
  8067. a.draw()</p>
  8068. <p>pgzrun.go()
  8069. ```</p>
  8070. <h2>[DAY-129] Eat your computer; Memory; CPU</h2>
  8071. <p>consume one CPU on your computer</p>
  8072. <p><code>while True:
  8073. x = 1</code></p>
  8074. <p>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.</p>
  8075. <p>It might seem like <code>x = 1</code> is doing nothing, but it actually has to go to the memory address of the variable x and set it to value 1</p>
  8076. <p>Now, lets consume all the memory.</p>
  8077. <p><code>a = []
  8078. for i in range(10000000000):
  8079. a.append(i)</code></p>
  8080. <p>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.</p>
  8081. <p>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.</p>
  8082. <h2>[DAY-130] turtle; lists; classes</h2>
  8083. <p><img alt="game-130.png" src="./screenshots/game-130.png" title="game 130 screenshot" /></p>
  8084. <p>many turtles</p>
  8085. <p>```
  8086. import turtle
  8087. import random
  8088. colors = ['violet', 'turquoise', 'black',
  8089. 'deepskyblue','lawngreen', 'seagreen ',
  8090. 'royalblue', 'purple', 'red','orange']</p>
  8091. <p>turtles = []
  8092. for i in range(10):
  8093. t = turtle.Turtle()
  8094. t.color(random.choice(colors))
  8095. t.speed(9000)
  8096. turtles.append(t)</p>
  8097. <p>while True:
  8098. for i in range(len(turtles)):
  8099. t = turtles[i]
  8100. t.setheading(random.randint(0,360))
  8101. t.forward(10)
  8102. ```</p>
  8103. <p>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</p>
  8104. <p>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, <code>x</code> and <code>y</code></p>
  8105. <p>```
  8106. class Point:
  8107. x = 0
  8108. y = 0</p>
  8109. <p>points = []
  8110. for i in range(10):
  8111. p = Point()
  8112. p.x = i * 20
  8113. p.y = i * 20
  8114. points.append(p)</p>
  8115. <p>for p in points:
  8116. print(p, p.x, p.y)
  8117. ```</p>
  8118. <p>When you define a function in a class, you have access to special parameter, <code>self</code> which is the instance on which this function is called:</p>
  8119. <p>```
  8120. class Dog:
  8121. name = ''
  8122. def bark(self):
  8123. print(self.name+' woof woof woof')</p>
  8124. <p>max = Dog()
  8125. max.name = 'Maxie'
  8126. max.bark()</p>
  8127. <p>rocky = Dog()
  8128. rocky.name = "Rocky"
  8129. rocky.bark()</p>
  8130. <p>```</p>
  8131. <p>There is also a special <code>__init__</code> function, called constructor that lets you pass parameters directly when you create the instance.</p>
  8132. <p>```
  8133. class Point:
  8134. x = 0
  8135. y = 0</p>
  8136. <pre><code>def __init__(self, x,y):
  8137. self.x = x
  8138. self.y = y
  8139. </code></pre>
  8140. <p>points = []
  8141. for i in range(10):
  8142. p = Point(i * 10, i * 20)
  8143. points.append(p)</p>
  8144. <p>for p in points:
  8145. print(p, p.x, p.y)</p>
  8146. <p>```</p>
  8147. <h2>[DAY-131] Lists; Files; Dictionaries</h2>
  8148. <p>Example dictionary, List and String</p>
  8149. <p>```
  8150. words = {}</p>
  8151. <p>words["some long key"] = True
  8152. words["x"] = 10</p>
  8153. <p>for k in words:
  8154. print(k)
  8155. print(words[k])</p>
  8156. <p>list_of_characters = ['a','b','c']</p>
  8157. <p>for i in range(len(list_of_characters)):
  8158. print(i)
  8159. print(list_of_characters[i])</p>
  8160. <p>s = "hello"
  8161. for i in range(len(s)):
  8162. print(i)
  8163. print(s[i])</p>
  8164. <p>```</p>
  8165. <p>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 <code>some long key</code> I do <code>print(words["some long key"])</code>.</p>
  8166. <p>Now unrelated, but lets practice printing the first 100 numbers from a list.</p>
  8167. <p>```
  8168. a = []</p>
  8169. <p>for i in range(100):
  8170. a.append(i)</p>
  8171. <p>for i in range(100):
  8172. print(a[i])
  8173. ```</p>
  8174. <p>Append to file, whatever command line agurments 1 and 2 are</p>
  8175. <p>```
  8176. import sys
  8177. f = open("account.txt", "a")</p>
  8178. <p>f.write(sys.argv[1] + " " + sys.argv[2] + "\n")</p>
  8179. <p>f.close()
  8180. ```</p>
  8181. <h2>[DAY-132] Lists; Classes</h2>
  8182. <p><img alt="game-132.png" src="./screenshots/game-132.png" title="game 132 screenshot" /></p>
  8183. <p>a tower defense game</p>
  8184. <p>```
  8185. import pgzrun
  8186. import random</p>
  8187. <p>WIDTH=1024
  8188. HEIGHT=576</p>
  8189. <p>towers = []
  8190. enemies = []
  8191. bullets = []
  8192. game_over = False
  8193. background = Actor("grass_template2", pos=(0,0), anchor=(0,0))</p>
  8194. <p>player = Actor("c1", pos=(WIDTH/2, HEIGHT/2), anchor=('center','bottom'))
  8195. lives = 100
  8196. cash = 100
  8197. current_wave = 1</p>
  8198. <p>class Tower:
  8199. def <strong>init</strong>(self, image, x,y, size):
  8200. self.actor = Actor(image, pos=(x,y), )
  8201. self.rect = Rect((x-size/2,y-size/2), (size,size))
  8202. self.color = (random.randint(100,250),random.randint(100,250),random.randint(100,250))
  8203. def shoot(self):
  8204. for e in enemies:
  8205. if e.colliderect(self.rect):
  8206. b = Actor("bullet3")
  8207. b.x = self.actor.x
  8208. b.y = self.actor.y
  8209. b.hit = False
  8210. animate(b, pos=(e.x,e.y), tween='accelerate', on_finished=lambda: bullets.remove(b))
  8211. bullets.append(b)
  8212. break</p>
  8213. <pre><code>def colliderect(self,other):
  8214. return self.actor.colliderect(other)
  8215. def draw(self):
  8216. self.actor.draw()
  8217. #screen.draw.rect(self.rect,self.color)
  8218. </code></pre>
  8219. <p>def shoot():
  8220. global cash
  8221. for t in towers:
  8222. t.shoot()
  8223. for e in list(enemies):
  8224. if e.image == 'exploded':
  8225. enemies.remove(e)
  8226. cash+=1</p>
  8227. <p>def new_wave():
  8228. global current_wave
  8229. for i in range(current_wave * 10):
  8230. e = Actor("c3")
  8231. e.y = HEIGHT
  8232. e.x = random.randint(int(WIDTH/3), int(WIDTH-WIDTH/3))
  8233. enemies.append(e)
  8234. current_wave += 1</p>
  8235. <p>def on_key_down(key):
  8236. global cash
  8237. if key == keys.K_1:
  8238. if cash &gt;= 10:
  8239. conflict = False
  8240. for t in towers:
  8241. if t.colliderect(player):
  8242. conflict = True</p>
  8243. <pre><code> if not conflict:
  8244. t = Tower("tower_grass",player.x, player.y, 150)
  8245. towers.append(t)
  8246. cash -= 10
  8247. </code></pre>
  8248. <p>def update():
  8249. global game_over
  8250. if keyboard.UP:
  8251. player.y -= 5
  8252. if keyboard.DOWN:
  8253. player.y += 5
  8254. if keyboard.LEFT:
  8255. player.x -= 5
  8256. if keyboard.RIGHT:
  8257. player.x += 5</p>
  8258. <pre><code>for e in enemies:
  8259. if e.image != 'exploded':
  8260. e.y -= random.randint(-1,2)
  8261. for b in bullets:
  8262. if b.colliderect(e):
  8263. e.image = 'exploded'
  8264. b.hit = True
  8265. break
  8266. if not background.colliderect(e):
  8267. game_over = True
  8268. pass
  8269. </code></pre>
  8270. <p>clock.schedule_interval(shoot, 1)
  8271. clock.schedule_interval(new_wave, 10)</p>
  8272. <p>new_wave()</p>
  8273. <p>def draw():
  8274. screen.clear()
  8275. if game_over:
  8276. screen.fill('blue')
  8277. else:
  8278. background.draw()
  8279. screen.draw.text("current_wave: " + str(current_wave) + ", cash: " + str(cash) + ", lives: " + str(lives), (5,0),fontname="437-win") </p>
  8280. <pre><code> for b in bullets:
  8281. if not b.hit:
  8282. b.draw()
  8283. for e in enemies:
  8284. e.draw()
  8285. for t in towers:
  8286. t.draw()
  8287. player.draw()
  8288. </code></pre>
  8289. <p>pgzrun.go()
  8290. ```</p>
  8291. <h2>[DAY-133] Touch Typing; Lists</h2>
  8292. <p><img alt="game-133.png" src="./screenshots/game-133.png" title="game 133 screenshot" /></p>
  8293. <p>Spend 15 minutes touch typing.</p>
  8294. <p>Add a path for the enemies to walk on.</p>
  8295. <p>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.</p>
  8296. <p>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: <strong>find the current square you are colliding it, find which square is next in the list, start walking towards it</strong>. Now lets write it down:</p>
  8297. <p>```</p>
  8298. <p>[...]</p>
  8299. <p>path = [
  8300. Rect(0, HEIGHT/2, 50, 50),
  8301. Rect(50, HEIGHT/2, 50, 50),</p>
  8302. <p>[...]</p>
  8303. <p>def update():</p>
  8304. <p>[...]</p>
  8305. <pre><code>for e in enemies:
  8306. if e.image != 'exploded':
  8307. destination = None
  8308. for (i, p) in enumerate(path):
  8309. if e.colliderect(p) and i &lt; len(path) - 1:
  8310. destination = path[i+1]
  8311. break
  8312. if destination != None:
  8313. center_x = destination.x + 25
  8314. center_y = destination.y + 25
  8315. if e.x &lt; center_x:
  8316. e.x += random.randint(0, 2)
  8317. if e.x &gt; center_x:
  8318. e.x -= random.randint(0, 2)
  8319. if e.y &gt; center_y:
  8320. e.y -= random.randint(0, 2)
  8321. if e.y &lt; center_y:
  8322. e.y += random.randint(0, 2)
  8323. </code></pre>
  8324. <p>[...]</p>
  8325. <p>```</p>
  8326. <p>```
  8327. import pgzrun
  8328. import random</p>
  8329. <p>WIDTH = 1024
  8330. HEIGHT = 576</p>
  8331. <p>towers = []
  8332. enemies = []
  8333. bullets = []
  8334. game_over = False
  8335. background = Actor("grass_template2", pos=(0, 0), anchor=(0, 0))</p>
  8336. <p>path_size = 50
  8337. path = [
  8338. Rect(0, HEIGHT/2, 50, 50),
  8339. Rect(50, HEIGHT/2, 50, 50),
  8340. Rect(50, HEIGHT/2 + 50, 50, 50),
  8341. Rect(100, HEIGHT/2 + 50, 50, 50),
  8342. Rect(150, HEIGHT/2 + 50, 50, 50),
  8343. Rect(200, HEIGHT/2 + 50, 50, 50),
  8344. Rect(250, HEIGHT/2 + 50, 50, 50),
  8345. Rect(250, HEIGHT/2 + 100, 50, 50),
  8346. Rect(300, HEIGHT/2 + 100, 50, 50),
  8347. Rect(350, HEIGHT/2 + 100, 50, 50),
  8348. Rect(400, HEIGHT/2 + 100, 50, 50),
  8349. Rect(450, HEIGHT/2 + 100, 50, 50),
  8350. Rect(500, HEIGHT/2 + 100, 50, 50),
  8351. Rect(500, HEIGHT/2 + 150, 50, 50),
  8352. Rect(550, HEIGHT/2 + 150, 50, 50),
  8353. Rect(600, HEIGHT/2 + 150, 50, 50),
  8354. Rect(650, HEIGHT/2 + 150, 50, 50),
  8355. Rect(650, HEIGHT/2 + 200, 50, 50),
  8356. Rect(700, HEIGHT/2 + 200, 50, 50),
  8357. Rect(750, HEIGHT/2 + 200, 50, 50),
  8358. Rect(800, HEIGHT/2 + 200, 50, 50),
  8359. Rect(850, HEIGHT/2 + 200, 50, 50),
  8360. Rect(850, HEIGHT/2 + 150, 50, 50),
  8361. Rect(850, HEIGHT/2 + 100, 50, 50),
  8362. Rect(850, HEIGHT/2 + 50, 50, 50),
  8363. Rect(850, HEIGHT/2 + 0, 50, 50),
  8364. Rect(850, HEIGHT/2 - 50, 50, 50),
  8365. Rect(850, HEIGHT/2 - 100, 50, 50),
  8366. Rect(900, HEIGHT/2 - 100, 50, 50),
  8367. Rect(950, HEIGHT/2 - 100, 50, 50),
  8368. Rect(1000, HEIGHT/2 - 100, 50, 50),
  8369. Rect(1050, HEIGHT/2 - 100, 50, 50),
  8370. Rect(1100, HEIGHT/2 - 100, 50, 50),
  8371. ]</p>
  8372. <p>player = Actor("c1", pos=(WIDTH/2, HEIGHT/2), anchor=('center', 'bottom'))
  8373. lives = 100
  8374. cash = 100
  8375. current_wave = 1</p>
  8376. <p>class Tower:
  8377. def <strong>init</strong>(self, image, x, y, size):
  8378. self.actor = Actor(image, pos=(x, y), )
  8379. self.rect = Rect((x-size/2, y-size/2), (size, size))
  8380. self.color = (random.randint(100, 250), random.randint(
  8381. 100, 250), random.randint(100, 250))</p>
  8382. <pre><code>def shoot(self):
  8383. for e in enemies:
  8384. if e.colliderect(self.rect):
  8385. b = Actor("bullet3")
  8386. b.x = self.actor.x
  8387. b.y = self.actor.y
  8388. b.hit = False
  8389. animate(b, pos=(e.x, e.y), tween='accelerate',
  8390. on_finished=lambda: bullets.remove(b))
  8391. bullets.append(b)
  8392. break
  8393. def colliderect(self, other):
  8394. return self.actor.colliderect(other)
  8395. def draw(self):
  8396. self.actor.draw()
  8397. screen.draw.rect(self.rect,self.color)
  8398. </code></pre>
  8399. <p>def shoot():
  8400. global cash
  8401. for t in towers:
  8402. t.shoot()
  8403. for e in list(enemies):
  8404. if e.image == 'exploded':
  8405. enemies.remove(e)
  8406. cash += 1</p>
  8407. <p>def new_wave():
  8408. global current_wave
  8409. for i in range(10 + (current_wave * 2)):
  8410. e = Actor("c3")
  8411. e.y = HEIGHT/2+10
  8412. e.x = 0
  8413. enemies.append(e)
  8414. current_wave += 1</p>
  8415. <p>def on_key_down(key):
  8416. global cash
  8417. if key == keys.K_1:
  8418. if cash &gt;= 10:
  8419. conflict = False
  8420. for t in towers:
  8421. if t.colliderect(player):
  8422. conflict = True</p>
  8423. <pre><code> for p in path:
  8424. if player.colliderect(p):
  8425. conflict = True
  8426. if not conflict:
  8427. t = Tower("tower_grass", player.x, player.y, 150)
  8428. towers.append(t)
  8429. cash -= 10
  8430. </code></pre>
  8431. <p>def update():
  8432. global game_over
  8433. if keyboard.UP:
  8434. player.y -= 5
  8435. if keyboard.DOWN:
  8436. player.y += 5
  8437. if keyboard.LEFT:
  8438. player.x -= 5
  8439. if keyboard.RIGHT:
  8440. player.x += 5</p>
  8441. <pre><code>for e in enemies:
  8442. if e.image != 'exploded':
  8443. destination = None
  8444. for (i, p) in enumerate(path):
  8445. if e.colliderect(p) and i &lt; len(path) - 1:
  8446. destination = path[i+1]
  8447. break
  8448. if destination != None:
  8449. center_x = destination.x + 25
  8450. center_y = destination.y + 25
  8451. if e.x &lt; center_x:
  8452. e.x += random.randint(0, 2)
  8453. if e.x &gt; center_x:
  8454. e.x -= random.randint(0, 2)
  8455. if e.y &gt; center_y:
  8456. e.y -= random.randint(0, 2)
  8457. if e.y &lt; center_y:
  8458. e.y += random.randint(0, 2)
  8459. for b in bullets:
  8460. if b.colliderect(e):
  8461. e.image = 'exploded'
  8462. b.hit = True
  8463. break
  8464. if not background.colliderect(e):
  8465. game_over = True
  8466. pass
  8467. </code></pre>
  8468. <p>clock.schedule_interval(shoot, 1)
  8469. clock.schedule_interval(new_wave, 10)</p>
  8470. <p>new_wave()</p>
  8471. <p>def draw():
  8472. screen.clear()
  8473. if game_over:
  8474. screen.fill('blue')
  8475. else:
  8476. background.draw()</p>
  8477. <pre><code> screen.draw.text("current_wave: " + str(current_wave) + ", cash: " +
  8478. str(cash) + ", lives: " + str(lives), (5, 0), fontname="437-win")
  8479. for i in range(len(path)):
  8480. p = path[i]
  8481. screen.draw.filled_rect(p,(255,0,0))
  8482. screen.draw.text(str(p.x), (p.x,p.y))
  8483. for b in bullets:
  8484. if not b.hit:
  8485. b.draw()
  8486. for e in enemies:
  8487. e.draw()
  8488. for t in towers:
  8489. t.draw()
  8490. player.draw()
  8491. </code></pre>
  8492. <p>pgzrun.go()
  8493. ```</p>
  8494. <h2>[DAY-134] Lists; Methods</h2>
  8495. <p>Upgrade our tower game, make it possible to:</p>
  8496. <ul>
  8497. <li>delete towers and get some money back</li>
  8498. <li>be able to upgrade the tower's range</li>
  8499. </ul>
  8500. <p>First we will store original <code>x</code>,<code>y</code> and <code>size</code> in the tower's instance, and then use it to increase its range.</p>
  8501. <p>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.</p>
  8502. <p>```
  8503. [...]</p>
  8504. <p>class Tower:
  8505. [...]
  8506. def <strong>init</strong>(self, image, x, y, size):
  8507. self.size = size
  8508. self.x = x
  8509. self.y = y
  8510. self.actor = Actor(image, pos=(x, y))
  8511. self.rect = Rect((x-size/2, y-size/2), (size, size))
  8512. self.color = (random.randint(100, 250), random.randint(100, 250), random.randint(100, 250))</p>
  8513. <pre><code>def resize(self, bump):
  8514. new_size = self.size + bump
  8515. self.size = new_size
  8516. self.rect = Rect((self.x-new_size/2, self.y-new_size/2), (new_size, new_size))
  8517. </code></pre>
  8518. <p>[...]</p>
  8519. <p>def on_key_down(key):
  8520. global cash
  8521. if key == keys.K_2:
  8522. for t in towers:
  8523. if t.colliderect(player):
  8524. t.resize(5)
  8525. cash -= 10</p>
  8526. <pre><code>if key == keys.D:
  8527. for t in list(towers):
  8528. if t.colliderect(player):
  8529. cash += 15
  8530. towers.remove(t)
  8531. </code></pre>
  8532. <p>[...]</p>
  8533. <p>```</p>
  8534. <h2>[DAY-134] If</h2>
  8535. <p><img alt="game-134.png" src="./screenshots/game-134.png" title="game 134 screenshot" /></p>
  8536. <p>Relax day.</p>
  8537. <p>Make super simple game to draw with two players, because we dont clear the screen.</p>
  8538. <p>```
  8539. import pgzrun</p>
  8540. <p>HEIGHT = 800
  8541. WIDTH = 800</p>
  8542. <p>elf = Actor('c1')
  8543. king = Actor('c2')</p>
  8544. <p>def update():
  8545. if keyboard.W:
  8546. elf.y -= 5
  8547. if keyboard.S:
  8548. elf.y += 5
  8549. if keyboard.A:
  8550. elf.x -= 5
  8551. if keyboard.D:
  8552. elf.x += 5
  8553. if keyboard.UP:
  8554. king.y -= 5
  8555. if keyboard.DOWN:
  8556. king.y += 5
  8557. if keyboard.LEFT:
  8558. king.x -= 5
  8559. if keyboard.RIGHT:
  8560. king.x += 5</p>
  8561. <p>def draw():
  8562. elf.draw()
  8563. king.draw()</p>
  8564. <p>pgzrun.go()
  8565. ```</p>
  8566. <h2>[DAY-135] Dictionary; For</h2>
  8567. <p><a href="screenshots/game-135.mp3">game-135</a></p>
  8568. <p>Make a morse code machine!</p>
  8569. <p>```
  8570. import pgzrun
  8571. import time</p>
  8572. <p>short = tone.create('A3', 0.3)
  8573. long = tone.create('D3', 0.7)</p>
  8574. <p>morse = {
  8575. 'a': [short, long],
  8576. 'b': [long, short, short, short],
  8577. 'c': [long, short, long, short],
  8578. 'd': [long, short, short],
  8579. 'e': [short],
  8580. 'f': [short, short, long, short],
  8581. 'g': [long, long, short],
  8582. 'h': [short, short, short, short],
  8583. 'i': [short, short],
  8584. 'j': [short, long, long, long],
  8585. 'k': [long, short, long],
  8586. 'l': [short, long, short, short],
  8587. 'm': [long, long],
  8588. 'n': [long, short],
  8589. 'o': [long, long, long],
  8590. 'p': [short, long, long, short],
  8591. 'q': [long, long, short, long],
  8592. 'r': [short, long, short],
  8593. 's': [short, short, short],
  8594. 't': [long],
  8595. 'u': [short, short, long],
  8596. 'v': [short, short, short, long],
  8597. 'w': [short, long, long],
  8598. 'x': [long, short, short, long],
  8599. 'y': [long, short, long, long],
  8600. 'z': [long, long, short, short]
  8601. }</p>
  8602. <p>def play(key):
  8603. for t in morse[key]:
  8604. t.play()
  8605. time.sleep(1)
  8606. time.sleep(1)</p>
  8607. <p>def on_key_down(key):
  8608. if key == keys.A:
  8609. play('a')
  8610. if key == keys.B:
  8611. play('b')
  8612. if key == keys.C:
  8613. play('c')
  8614. if key == keys.D:
  8615. play('d')
  8616. if key == keys.E:
  8617. play('e')
  8618. if key == keys.F:
  8619. play('f')
  8620. if key == keys.G:
  8621. play('g')
  8622. if key == keys.H:
  8623. play('h')
  8624. if key == keys.I:
  8625. play('i')
  8626. if key == keys.J:
  8627. play('j')
  8628. if key == keys.K:
  8629. play('k')
  8630. if key == keys.L:
  8631. play('l')
  8632. if key == keys.M:
  8633. play('m')
  8634. if key == keys.N:
  8635. play('n')
  8636. if key == keys.O:
  8637. play('o')
  8638. if key == keys.P:
  8639. play('p')
  8640. if key == keys.Q:
  8641. play('q')
  8642. if key == keys.R:
  8643. play('r')
  8644. if key == keys.S:
  8645. play('s')
  8646. if key == keys.T:
  8647. play('t')
  8648. if key == keys.U:
  8649. play('u')
  8650. if key == keys.V:
  8651. play('v')
  8652. if key == keys.W:
  8653. play('w')
  8654. if key == keys.X:
  8655. play('x')
  8656. if key == keys.Y:
  8657. play('y')
  8658. if key == keys.Z:
  8659. play('z')</p>
  8660. <p>def update():
  8661. pass</p>
  8662. <p>def draw():
  8663. pass</p>
  8664. <p>pgzrun.go()
  8665. ```</p>
  8666. <h2>[DAY-136] For; Arrays; Memory</h2>
  8667. <p>Lets make a super simple C program</p>
  8668. <p>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 <code>i</code> is of type <code>int</code> which on our computer is exactly 4 bytes long.</p>
  8669. <p>```</p>
  8670. <h1>include <stdio.h></h1>
  8671. <p>int main() {
  8672. int sum = 0;
  8673. for (int i = 0; i &lt; 100; i++) {
  8674. sum += 10;
  8675. }</p>
  8676. <pre><code>printf("%d\n", sum);
  8677. </code></pre>
  8678. <p>}
  8679. ```</p>
  8680. <p>When you execute <code>gcc -o foo foo.c</code> (if you save the program in foo.c), it will make the binary <code>foo</code>, do <code>cat foo</code> to see the actual binary made from the compiler. If you run <code>objdump -D foo</code> you will see the assembly code and the machine code corresponding to it.</p>
  8681. <p><code>cat foo</code>:
  8682. ```
  8683. ????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
  8684. P??
  8685. /usr/lib/dyld9??
  8686. f:^?[c?υ02 </p>
  8687. <pre><code> ?*(?0?
  8688. 8d
  8689. /usr/lib/libSystem.B.dylib&amp;`)h?UH??H???E??E??E??}?d??E???
  8690. </code></pre>
  8691. <p>?E??E???E???????u?H?=2?? ?E?H??]??%r@L?q@AS?%a?h?????%d
  8692. 0?44??4
  8693. ??#Q@dyld_stub_binderQr?s@_printf?__mh_execute_header!main%?~??0?$ __mh_execute_header_main_printfdyld_stub_binder__dyld_privat
  8694. ```</p>
  8695. <p>Because its a binary file, most of the bytes are not actually printable ASCII characters, you can use <code>hexdump</code> to see the byte's values:</p>
  8696. <p><code>hexdump -C foo</code></p>
  8697. <p>```
  8698. 00000000 cf fa ed fe 07 00 00 01 03 00 00 00 02 00 00 00 |................|
  8699. 00000010 10 00 00 00 58 05 00 00 85 00 20 00 00 00 00 00 |....X..... .....|
  8700. 00000020 19 00 00 00 48 00 00 00 5f 5f 50 41 47 45 5a 45 |....H...__PAGEZE|
  8701. 00000030 52 4f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |RO..............|
  8702. 00000040 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
  8703. 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  8704. 00000060 00 00 00 00 00 00 00 00 19 00 00 00 d8 01 00 00 |................|
  8705. 00000070 5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 |__TEXT..........|
  8706. 00000080 00 00 00 00 01 00 00 00 00 40 00 00 00 00 00 00 |.........@......|
  8707. 00000090 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 |.........@......|
  8708. 000000a0 05 00 00 00 05 00 00 00 05 00 00 00 00 00 00 00 |................|
  8709. 000000b0 5f 5f 74 65 78 74 00 00 00 00 00 00 00 00 00 00 |__text..........|
  8710. 000000c0 5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 |__TEXT..........|
  8711. 000000d0 30 3f 00 00 01 00 00 00 58 00 00 00 00 00 00 00 |0?......X.......|
  8712. 000000e0 30 3f 00 00 04 00 00 00 00 00 00 00 00 00 00 00 |0?..............|
  8713. 000000f0 00 04 00 80 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  8714. 00000100 5f 5f 73 74 75 62 73 00 00 00 00 00 00 00 00 00 |__stubs.........|
  8715. 00000110 5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 |__TEXT..........|
  8716. 00000120 88 3f 00 00 01 00 00 00 06 00 00 00 00 00 00 00 |.?..............|
  8717. 00000130 88 3f 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |.?..............|
  8718. 00000140 08 04 00 80 00 00 00 00 06 00 00 00 00 00 00 00 |................|</p>
  8719. <p>[...]</p>
  8720. <p>```</p>
  8721. <p><code>objdump -D foo</code>
  8722. <code>[...]
  8723. 100003f30: 55 pushq %rbp
  8724. 100003f31: 48 89 e5 movq %rsp, %rbp
  8725. 100003f34: 48 83 ec 10 subq $16, %rsp
  8726. 100003f38: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
  8727. 100003f3f: c7 45 f8 00 00 00 00 movl $0, -8(%rbp)
  8728. 100003f46: c7 45 f4 00 00 00 00 movl $0, -12(%rbp)
  8729. 100003f4d: 83 7d f4 64 cmpl $100, -12(%rbp)
  8730. 100003f51: 0f 8d 17 00 00 00 jge 0x100003f6e &lt;_main+0x3e&gt;
  8731. 100003f57: 8b 45 f8 movl -8(%rbp), %eax
  8732. 100003f5a: 83 c0 0a addl $10, %eax
  8733. 100003f5d: 89 45 f8 movl %eax, -8(%rbp)
  8734. 100003f60: 8b 45 f4 movl -12(%rbp), %eax
  8735. 100003f63: 83 c0 01 addl $1, %eax
  8736. 100003f66: 89 45 f4 movl %eax, -12(%rbp)
  8737. 100003f69: e9 df ff ff ff jmp 0x100003f4d &lt;_main+0x1d&gt;
  8738. [...]</code></p>
  8739. <p><code>addl</code> meand <code>add</code>, <code>jmp</code> means jump and so forth. This is not important for now, the point is that <code>gcc</code> which is a popular C compiler, will take your code and make it into machine code.</p>
  8740. <p>Lets have another example:</p>
  8741. <p>FizzBuzz</p>
  8742. <p>```</p>
  8743. <h1>include <stdio.h></h1>
  8744. <p>int main() {
  8745. for (int i = 0; i &lt; 100; i++) {
  8746. if (i % 15 == 0) {
  8747. printf("fizzbuzz\n");
  8748. } else if (i % 5 == 0) {
  8749. printf("buzz\n");
  8750. } else if (i % 3 == 0) {
  8751. printf("fizz\n");
  8752. } else {
  8753. printf("%d\n",i);
  8754. }
  8755. }
  8756. }
  8757. ```</p>
  8758. <p>What is your name?</p>
  8759. <p>```</p>
  8760. <h1>include <stdio.h></h1>
  8761. <p>int main() {
  8762. char input[20] = {0};
  8763. while(1) {
  8764. printf("What is your name: ");
  8765. scanf("%s",input);
  8766. printf("\nHello %s\n",input);
  8767. }
  8768. }
  8769. ```</p>
  8770. <p>You see how we say <code>char input[20]</code> which means we habe 20 elements of type <code>char</code> pointed by the input variable, it is literally just a pointer to some memory, and we can use <code>input[1]</code> to go to the address <code>input</code> plus 1 byte. Same with <code>int x[10]</code>, if we do x[3], it will go to the address pointed by <code>x</code> and add 3 * 4 to it.</p>
  8771. <p>We can make interesting bugs like that, because nobody will check if we go and read somewhere outside of the defined array:</p>
  8772. <p>```</p>
  8773. <h1>include <stdio.h></h1>
  8774. <p>int main() {
  8775. char input[20] = {0};
  8776. int b = 5;
  8777. while(1) {
  8778. printf("What is your name: ");
  8779. scanf("%s",input);
  8780. printf("\nHello %s\n",input);</p>
  8781. <pre><code> for (int i = 0; i &lt; 40; i++) {
  8782. printf(" %d -&gt; %d -&gt; %c\n", i, input[i],input[i]);
  8783. }
  8784. }
  8785. </code></pre>
  8786. <p>}</p>
  8787. <p>```</p>
  8788. <p>You will see some garbage from element 20 to 39, because it will actually go and read beyond the input bounderioes.</p>
  8789. <h2>[DAY-137] For; File; If</h2>
  8790. <p>Play with <a href="words.txt">words.txt</a></p>
  8791. <p>Open the file and print all the lines:</p>
  8792. <p><code>f = open("words.txt")
  8793. for line in f:
  8794. print(line)</code></p>
  8795. <p>Remove the newline:</p>
  8796. <p><code>f = open("words.txt")
  8797. for line in f:
  8798. word = line.strip()
  8799. print(word)</code></p>
  8800. <p>Print only words with more than 10 characters:</p>
  8801. <p><code>f = open("words.txt")
  8802. for line in f:
  8803. word = line.strip()
  8804. if len(word) &gt; 10:
  8805. print(word)</code></p>
  8806. <p>Print only words starting with 'ab':</p>
  8807. <p><code>f = open("words.txt")
  8808. for line in f:
  8809. word = line.strip()
  8810. if word[0] == 'a' and word[1] == 'b':
  8811. print(word)</code></p>
  8812. <p>Print words not containing a character</p>
  8813. <p><code>f = open("words.txt")
  8814. for line in f:
  8815. word = line.strip()
  8816. if 'e' not in word:
  8817. print(word)</code></p>
  8818. <p>Avoid words containing multiple characters</p>
  8819. <p>```
  8820. f = open("words.txt")
  8821. def avoid(word, characters):
  8822. for c in characters:
  8823. for w in word:
  8824. if w == c:
  8825. return False
  8826. return True</p>
  8827. <p>for line in f:
  8828. word = line.strip()
  8829. if avoid(word, ['a','b','c']):
  8830. print(word)
  8831. ```</p>
  8832. <p>Another implementation using 'char' in 'string':</p>
  8833. <p>```
  8834. f = open("words.txt")</p>
  8835. <p>def avoid(word, characters):
  8836. for c in characters:
  8837. for c in word:
  8838. return False
  8839. return True</p>
  8840. <p>for line in f:
  8841. word = line.strip()
  8842. if avoid(word, ['a','b','c']):
  8843. print(word)
  8844. ```</p>
  8845. <p>Spinning turtle</p>
  8846. <p><img alt="game-137.png" src="./screenshots/game-137.png" title="game 137 screenshot" /></p>
  8847. <p><code>import turtle as t
  8848. size = 10
  8849. t.speed(10000)
  8850. while True:
  8851. t.right(150)
  8852. t.forward(size)
  8853. size += 1</code></p>
  8854. <p><img alt="game-137-3.png" src="./screenshots/game-137-3.png" title="game 137-3 screenshot" /></p>
  8855. <p>```
  8856. import turtle as t
  8857. size = 10
  8858. t.speed(10000)
  8859. while True:
  8860. t.right(150)
  8861. t.forward(size)
  8862. if size % 2 == 0:
  8863. t.color('cyan')
  8864. else:
  8865. t.color('magenta')
  8866. size += 1</p>
  8867. <p>```</p>
  8868. <p><img alt="game-137-4.png" src="./screenshots/game-137-4.png" title="game 137-4 screenshot" /></p>
  8869. <p><code>import turtle as t
  8870. size = 1
  8871. t.speed(100000)
  8872. t.bgcolor('black')
  8873. t.hideturtle()
  8874. i = 0
  8875. while True:
  8876. if i % 2 == 0:
  8877. t.color('cyan')
  8878. else:
  8879. t.color('magenta')
  8880. t.forward(i*3)
  8881. t.left(91)
  8882. i+=1</code>
  8883. <img alt="game-137-2.png" src="./screenshots/game-137-2.png" title="game 137-2 screenshot" /></p>
  8884. <p><code>from turtle import *
  8885. begin_fill()
  8886. color('red')
  8887. pensize(3)
  8888. left(48)
  8889. forward(133)
  8890. circle(50,200)
  8891. right(140)
  8892. circle(50,200)
  8893. forward(133)
  8894. end_fill()
  8895. done()</code></p>
  8896. <p><img alt="game-137-1.png" src="./screenshots/game-137-1.png" title="game 137-1 screenshot" /></p>
  8897. <p>```
  8898. from turtle import *
  8899. size = 1
  8900. speed(10000)
  8901. while True:
  8902. if size % 2 == 0:
  8903. color('blue')
  8904. else:
  8905. color('red')</p>
  8906. <pre><code>circle(size, size * 5)
  8907. size += 1
  8908. </code></pre>
  8909. <p>```</p>
  8910. <h2>[DAY-138] For; File; If</h2>
  8911. <p>Take it easy.</p>
  8912. <p>Count how many lines have exactly 5 characters</p>
  8913. <p><code>fi = open('words.txt')
  8914. n = 0
  8915. for line in fi:
  8916. w = line.strip()
  8917. if len(w) == 5:
  8918. n += 1
  8919. print(n)</code></p>
  8920. <p>How many words have 7 and how many 5 characters?</p>
  8921. <p><code>fi = open('words.txt')
  8922. n = 0
  8923. x = 0
  8924. for line in fi:
  8925. w = line.strip()
  8926. if len(w) == 5:
  8927. n += 1
  8928. if len(w) == 7:
  8929. x += 1
  8930. print(n)
  8931. print(x)</code></p>
  8932. <h2>[DAY-139] While; List; Counter</h2>
  8933. <p>First touchtype for 20 minutes.</p>
  8934. <p>Then do some chill turtle shapes.</p>
  8935. <p><img alt="game-139-2.png" src="./screenshots/game-139-2.png" title="game 139-2 screenshot" /></p>
  8936. <p>```
  8937. from turtle import *</p>
  8938. <p>speed(100000)
  8939. pencolor('cyan')
  8940. size = 66
  8941. while True:
  8942. forward(size)
  8943. left(size)
  8944. size += 1
  8945. ```</p>
  8946. <p><img alt="game-139-1.png" src="./screenshots/game-139-1.png" title="game 139-1 screenshot" /></p>
  8947. <p>```
  8948. from turtle import *</p>
  8949. <p>c = ['cyan','magenta']
  8950. dist = 20</p>
  8951. <p>hideturtle()
  8952. speed(11)</p>
  8953. <p>while True:
  8954. color(c[dist%2])
  8955. forward(dist)
  8956. left(90)
  8957. dist = dist-3
  8958. ```</p>
  8959. <h2>[DAY-140] While; Turtle; Strings</h2>
  8960. <p>Read the strings chapter in the Thinking Python book.</p>
  8961. <p>Then do some chill turtle shapes.</p>
  8962. <p><img alt="game-140-1.png" src="./screenshots/game-140-1.png" title="game 140-1 screenshot" /></p>
  8963. <p>```
  8964. import turtle
  8965. import random
  8966. turtles = []
  8967. for i in range(5):
  8968. a = turtle.Turtle()
  8969. a.speed(10000)
  8970. a.hideturtle()
  8971. turtles.append(a)</p>
  8972. <p>while True:
  8973. for x in turtles:
  8974. size = random.randint(10,300)
  8975. extent = random.randint(0, 360)
  8976. x.circle(size, extent=extent)</p>
  8977. <p>```</p>
  8978. <p><img alt="game-140-2.png" src="./screenshots/game-140-2.png" title="game 140-2 screenshot" /></p>
  8979. <p>```
  8980. import turtle
  8981. import random
  8982. turtles = []
  8983. for i in range(5):
  8984. a = turtle.Turtle()
  8985. a.speed(10000)
  8986. a.hideturtle()
  8987. turtles.append(a)</p>
  8988. <p>while True:
  8989. for x in turtles:
  8990. size = random.randint(10,300)
  8991. for i in range(4):
  8992. x.forward(size)
  8993. x.right(90)</p>
  8994. <pre><code> x.circle(size)
  8995. </code></pre>
  8996. <p>```</p>
  8997. <p><img alt="game-140-3.png" src="./screenshots/game-140-3.png" title="game 140-3 screenshot" /></p>
  8998. <p>```
  8999. import turtle
  9000. import random
  9001. turtles = []
  9002. for i in range(5):
  9003. a = turtle.Turtle()
  9004. a.speed(10000)
  9005. a.hideturtle()
  9006. turtles.append(a)</p>
  9007. <p>while True:
  9008. for x in turtles:
  9009. size = random.randint(10,300)
  9010. for i in range(4):
  9011. x.forward(size)
  9012. x.right(90)
  9013. ```</p>
  9014. <p><img alt="game-140-4.png" src="./screenshots/game-140-4.png" title="game 140-4 screenshot" /></p>
  9015. <p>```
  9016. import turtle
  9017. import random
  9018. turtles = []
  9019. for i in range(5):
  9020. a = turtle.Turtle()
  9021. a.speed(10000)
  9022. a.hideturtle()
  9023. turtles.append(a)</p>
  9024. <p>while True:
  9025. for x in turtles:
  9026. size = random.randint(10,300)
  9027. x.circle(size)
  9028. ```</p>
  9029. <h2>[DAY-141] Wiki; API</h2>
  9030. <p>Today we are going to make a small app that uses wikipedia. First install the wikipedia package:
  9031. <code>pip3 install wikipedia</code></p>
  9032. <p>```
  9033. import wikipedia as wiki</p>
  9034. <p>while True:
  9035. what = input("search&gt; ")
  9036. summary = wiki.summary(what)
  9037. print(summary)
  9038. print('*' * 40)
  9039. ```</p>
  9040. <p>Will search wikipeadia the string you input, like this:</p>
  9041. <p><code>search&gt; leonadro da vinci
  9042. Leonardo da Vinci (15 April 1452 – 2 May 1519) was an Italian polymath of...
  9043. [...]
  9044. search&gt;</code></p>
  9045. <p>Lets do the same but with pygame:</p>
  9046. <p><img alt="game-141.png" src="./screenshots/game-141.png" title="game 141 screenshot" /></p>
  9047. <p>```
  9048. import wikipedia as wiki
  9049. import pgzrun</p>
  9050. <p>HEIGHT = 800
  9051. WIDTH = 800
  9052. text = ''
  9053. info = ''
  9054. def on_key_down(key, mod, unicode):
  9055. global text, info
  9056. if key == keys.BACKSPACE:
  9057. if len(text) &gt; 0:
  9058. text = text[:-1]
  9059. elif key == keys.RETURN:
  9060. info = wiki.summary(text)
  9061. text = ''</p>
  9062. <pre><code>elif len(unicode) &gt; 0 and ord(unicode) &gt;= 32 and ord(unicode) &lt;= 126:
  9063. text += unicode
  9064. </code></pre>
  9065. <p>def draw():
  9066. screen.clear()
  9067. screen.draw.text(info, (10,10), fontsize=18,fontname="437-win", width=WIDTH-20)
  9068. screen.draw.text(text, (WIDTH/2,HEIGHT - 40), color=(255,0,0), fontsize=30,fontname="437-win")</p>
  9069. <p>pgzrun.go()
  9070. ```</p>
  9071. <p>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</p>
  9072. <p>Next you would like to think, how would this python module download the data from wikipedia.</p>
  9073. <p>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&amp;prop=extracts&amp;format=json&amp;explaintext=&amp;titles=Dog which will be the page for <code>Dog</code>, you will see:</p>
  9074. <p><code>{"batchcomplete":"","query":{"pages":{"4269567":{"pageid":4269567,"ns":0,"title":"Dog","extract":"The dog or domestic dog
  9075. [...]
  9076. an end to the dinosaurs and the appearance of the first carnivoran...
  9077. [...]
  9078. Their personality traits include hypersocial behavior, boldnes
  9079. [...]</code></p>
  9080. <p>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.</p>
  9081. <p>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.</p>
  9082. <p>```</p>
  9083. <blockquote>
  9084. <blockquote>
  9085. <blockquote>
  9086. <p>import json
  9087. a = {"a":"b","c":3}</p>
  9088. <p>print(json.dumps([1,2,a]))
  9089. [1, 2, {"a": "b", "c": 3}]</p>
  9090. <p>d = json.loads('[1, 2, {"a": "b", "c": 3}]')
  9091. d
  9092. [1, 2, {'a': 'b', 'c': 3}]
  9093. ```</p>
  9094. </blockquote>
  9095. </blockquote>
  9096. </blockquote>
  9097. <p>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.</p>
  9098. <h2>[DAY-142] While</h2>
  9099. <p>today is again, chill turtle art</p>
  9100. <p>ever growing circle</p>
  9101. <p><img alt="game-142-1.png" src="./screenshots/game-142-1.png" title="game 142-1 screenshot" /></p>
  9102. <p><code>from turtle import *
  9103. speed(0)
  9104. size = 0
  9105. hideturtle()
  9106. while True:
  9107. size += 1
  9108. circle(size)</code></p>
  9109. <p>evergrowing circle and also go into negative radius</p>
  9110. <p><img alt="game-142-2.png" src="./screenshots/game-142-2.png" title="game 142-2 screenshot" /></p>
  9111. <p><code>from turtle import *
  9112. speed(0)
  9113. size = 300
  9114. hideturtle()
  9115. while True:
  9116. size -= 1
  9117. circle(size)</code></p>
  9118. <p>stop when the bottom circle is the same as the top one</p>
  9119. <p><img alt="game-142-3.png" src="./screenshots/game-142-3.png" title="game 142-3 screenshot" /></p>
  9120. <p><code>from turtle import *
  9121. speed(0)
  9122. size = 300
  9123. hideturtle()
  9124. while True:
  9125. size -= 1
  9126. circle(size)
  9127. if size &lt; -300:
  9128. break
  9129. done()</code></p>
  9130. <p>make the circles more edgy</p>
  9131. <p><img alt="game-142-4.png" src="./screenshots/game-142-4.png" title="game 142-4 screenshot" /></p>
  9132. <p><code>from turtle import *
  9133. import random
  9134. speed(0)
  9135. size = 300
  9136. hideturtle()
  9137. while True:
  9138. #size -= 1
  9139. circle(size, steps=random.randint(10,20))
  9140. if size &lt; -300:
  9141. break
  9142. done()</code></p>
  9143. <h2>[DAY-143] Strings</h2>
  9144. <p>Print the characters of a string one by one:</p>
  9145. <p><code>a = 'hello'
  9146. for i in a:
  9147. print(i)</code></p>
  9148. <p>Print the characters and their index:</p>
  9149. <p><code>a = 'hello'
  9150. for i in range(0,len(a)):
  9151. print(i, a[i])</code></p>
  9152. <p>Reverse the characters:</p>
  9153. <p><code>a = 'hey'
  9154. rev = ''
  9155. for i in range(0,len(a)):
  9156. # i = 0
  9157. # a[2 - 0] -&gt; a[2] -&gt; y
  9158. # i = 1
  9159. # a[2 - 1] -&gt; a[1] -&gt; e
  9160. # i = 2
  9161. # a[2 - 2] -&gt; a[0] -&gt; h
  9162. print(i,a[len(a)-1-i])
  9163. rev +=a[len(a)-1-i]
  9164. print(rev)</code></p>
  9165. <p>Google 'how to reverse a string in python'</p>
  9166. <p><code>a = 'hello'
  9167. b = a[len(a)::-1]
  9168. print(b)</code></p>
  9169. <p>check out the stackoverflow explanation at https://stackoverflow.com/questions/509211</p>
  9170. <p>Answer by Greg Hewgill, https://stackoverflow.com/users/893/greg-hewgill
  9171. ```</p>
  9172. <p>It's pretty simple really:</p>
  9173. <p>a[start:stop] # items start through stop-1
  9174. a[start:] # items start through the rest of the array
  9175. a[:stop] # items from the beginning through stop-1
  9176. a[:] # a copy of the whole array
  9177. There is also the step value, which can be used with any of the above:</p>
  9178. <p>a[start:stop:step] # start through not past stop, by step
  9179. The key point to remember is that the :stop value represents the first value that
  9180. is not in the selected slice. So, the difference between stop and start is the
  9181. number of elements selected (if step is 1, the default).</p>
  9182. <p>The other feature is that start or stop may be a negative number, which means it
  9183. counts from the end of the array instead of the beginning. So:</p>
  9184. <p>a[-1] # last item in the array
  9185. a[-2:] # last two items in the array
  9186. a[:-2] # everything except the last two items
  9187. Similarly, step may be a negative number:</p>
  9188. <p>a[::-1] # all items in the array, reversed
  9189. a[1::-1] # the first two items, reversed
  9190. a[:-3:-1] # the last two items, reversed
  9191. a[-3::-1] # everything except the last two items, reversed</p>
  9192. <p>Python is kind to the programmer if there are fewer items than you ask for. For example,
  9193. if you ask for a[:-2] and a only contains one element, you get an empty list instead of
  9194. an error. Sometimes you would prefer the error, so you have to be aware that this may happen.</p>
  9195. <p>Relation to slice() object
  9196. The slicing operator [] is actually being used in the above code with a slice() object
  9197. using the : notation (which is only valid within []), i.e.:</p>
  9198. <p>a[start:stop:step]
  9199. is equivalent to:</p>
  9200. <p>a[slice(start, stop, step)]</p>
  9201. <p>Slice objects also behave slightly differently depending on the number of arguments,
  9202. similarly to range(), i.e. both slice(stop) and slice(start, stop[, step]) are
  9203. supported. To skip specifying a given argument, one might use None, so that e.g.
  9204. a[start:] is equivalent to a[slice(start, None)] or a[::-1] is equivalent to
  9205. a[slice(None, None, -1)].</p>
  9206. <p>While the :-based notation is very helpful for simple slicing, the explicit use of
  9207. slice() objects simplifies the programmatic generation of slicing.
  9208. ```</p>
  9209. <h2>[DAY-144] Strings; Lists</h2>
  9210. <p>Sum the ascii of the elements of a list.</p>
  9211. <p>```
  9212. a = ['h','e','l','l','o']
  9213. sum = 0
  9214. for i in a:
  9215. sum += ord(a)</p>
  9216. <p>print(sum)
  9217. ```</p>
  9218. <p>Print its index, and the letter with the corresponding ascii</p>
  9219. <p>```
  9220. a = ['h','e','l','l','o']
  9221. sum = 0
  9222. for i in range(len(a)):
  9223. m = ord(a[i])
  9224. print('index: ', i, a[i], '=', m)
  9225. sum += m</p>
  9226. <p>print(sum)
  9227. ```</p>
  9228. <p>Now do the same with a string</p>
  9229. <p>```
  9230. a = 'hello'
  9231. sum = 0
  9232. for i in range(len(a)):
  9233. m = ord(a[i])
  9234. print('index: ', i, a[i], '=', m)
  9235. sum += m</p>
  9236. <p>print(sum)
  9237. ```</p>
  9238. <p>See how lists and strings both have len() and are indexable, meaning you can go to a specific index a[i] and do something.</p>
  9239. <p>You can mutate (change) the list, meaning you can change its content</p>
  9240. <p><code>a = ['h','e','l','o']
  9241. a[2] = 'b'
  9242. print(a)</code></p>
  9243. <p>But you can not change a string inplace:</p>
  9244. <p><code>a = 'hello'
  9245. a[2] = 'b'
  9246. print(a)</code></p>
  9247. <p>You will get <code>TypeError: 'str' object does not support item assignment</code>. If you want to change a string, you have to make a new one and reasign the variable to point to the new string.</p>
  9248. <p>```
  9249. a = 'hello'</p>
  9250. <p>a = a[0:2] + 'b' + a[3:5]
  9251. ```</p>
  9252. <p>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 <code>a</code> point to the new string.</p>
  9253. <h2>[DAY-145] While</h2>
  9254. <p>More turtle</p>
  9255. <p><img alt="game-145.png" src="./screenshots/game-145.png" title="game 145 screenshot" /></p>
  9256. <p>```
  9257. import turtle as t
  9258. import random</p>
  9259. <p>t.bgcolor('black')
  9260. t.pensize(6)
  9261. t.speed(0)</p>
  9262. <p>size = 20
  9263. colors =['cyan','royalblue','lawngreen','red','purple','white','yellow']</p>
  9264. <p>while True:
  9265. t.pencolor(random.choice(colors))
  9266. t.circle(size)
  9267. t.left(12)</p>
  9268. <pre><code>size += 1
  9269. </code></pre>
  9270. <p>```</p>
  9271. <p><img alt="game-145-2.png" src="./screenshots/game-145-2.png" title="game 145-2 screenshot" /></p>
  9272. <p>```
  9273. from turtle import *</p>
  9274. <p>size = 20
  9275. speed(0)
  9276. hideturtle()</p>
  9277. <p>while True:
  9278. size += 5</p>
  9279. <pre><code>circle(size)
  9280. </code></pre>
  9281. <p>```</p>
  9282. <p><img alt="game-145-3.png" src="./screenshots/game-145-3.png" title="game 145-3 screenshot" /></p>
  9283. <p>```
  9284. import turtle as t </p>
  9285. <p>size = 0
  9286. t.speed(0)</p>
  9287. <p>while True:
  9288. t.forward(size)
  9289. t.left(90)</p>
  9290. <pre><code>size += 1
  9291. </code></pre>
  9292. <p>```</p>
  9293. <p>Lets talk again about Memory.</p>
  9294. <p><code>a = 'hello'
  9295. print(len(a))
  9296. a += 'b'
  9297. print(len(a))
  9298. print(a[2])</code></p>
  9299. <p>First lets imagine a simplified representation of the string 'hello' in memory. </p>
  9300. <p>Lets imagine the computer memory as a long line of numbered boxes, so we can go directly to specific box</p>
  9301. <p><code>[-------------------------------------------------------------------------]
  9302. 0 1024</code></p>
  9303. <p>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 <code>h</code> which is 104 and, <code>e</code> which is 101, etc</p>
  9304. <p>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 <code>0</code>, 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.</p>
  9305. <p><code>[--------------5 104 101 108 108 111----------------------------------------------]
  9306. 0 ^ 1024
  9307. 555</code></p>
  9308. <p>Now the variable <code>a</code> just points to box 555, when we do <code>len(a)</code> we can just read the number stored at this address, and when we do <code>a[1]</code> we can read the value at address <code>555 + 1 + 1</code> which will give us (101)</p>
  9309. <p>What happens now when we do <code>a += 'b'</code>, this is the same as <code>a = a + 'b'</code>, which means ok, lets make a new string, with size <code>6</code> copy the original string there, and then add <code>b</code> (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.</p>
  9310. <p><code>[--------------5 104 101 108 108 111------6 104 101 108 108 111 98----------------]
  9311. 0 ^ ^ 1024
  9312. 555 763</code></p>
  9313. <p>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 <code>98</code> on address 770 and of course it will place the number <code>7</code> (the length of the new string), on address 763. And now we have a new string, it will just re-assign the variable <code>a</code> 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.</p>
  9314. <p>Lets talk about this code:</p>
  9315. <p><code>a = 'he'
  9316. b = 'lo'
  9317. c = 6
  9318. d = [a,b,c]
  9319. print(d[1])</code></p>
  9320. <p>One way python could represent a list is very similar to a string, you have length, and just addressess of the elements</p>
  9321. <p><code>[---3 555 763 847-----------2 104 101 ----------------2 108 111 ------6-----------]
  9322. 0 ^ ^ ^ ^ 1024
  9323. 125 555 763 847</code></p>
  9324. <p>The variable d will point to address <code>125</code>, from there you have first element on address 555, second on 763 and third on 847, to do <code>print(d[1]</code>) means go to 125 + 1 + 1, and follow the pointer, so go to 555 ... and so on.</p>
  9325. <p>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.</p>
  9326. <p><code>[---3 2 555 763 847-------2 2 104 101 --------------2 2 108 111 -----1 6----------]
  9327. 0 ^ ^ ^ ^ 1024
  9328. 125 555 763 847</code></p>
  9329. <p>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. </p>
  9330. <h2>[DAY-146] While; Classes</h2>
  9331. <p>Circles And Squares.</p>
  9332. <p><img alt="game-146.png" src="./screenshots/game-146.png" title="game 146 screenshot" /></p>
  9333. <p>```
  9334. import turtle as t</p>
  9335. <p>a = t.Turtle()
  9336. a.speed(0)
  9337. a.pencolor('fuchsia')</p>
  9338. <p>b = t.Turtle()
  9339. b.speed(0)
  9340. b.pencolor('mediumspringgreen')</p>
  9341. <p>c = t.Turtle()
  9342. c.speed(0)
  9343. c.pencolor('deepskyblue')</p>
  9344. <p>size = 30</p>
  9345. <p>while True:
  9346. a.forward(size<em>2)
  9347. a.left(90)
  9348. b.forward(size</em>3)
  9349. b.right(90)
  9350. c.forward(size*4)
  9351. c.right(90)
  9352. c.circle(size+1)</p>
  9353. <pre><code>size += 2
  9354. </code></pre>
  9355. <p>```</p>
  9356. <p><img alt="game-146-1.png" src="./screenshots/game-146-1.png" title="game 146-1 screenshot" /></p>
  9357. <p>```
  9358. import turtle as t
  9359. import random</p>
  9360. <p>a = t.Turtle()
  9361. a.speed(0)</p>
  9362. <p>b = t.Turtle()
  9363. b.speed(0)</p>
  9364. <p>b.hideturtle()
  9365. a.hideturtle()</p>
  9366. <p>b.pensize(5)
  9367. a.pensize(4)</p>
  9368. <p>b.pencolor('chocolate')</p>
  9369. <p>b.right(90)
  9370. b.forward(300)</p>
  9371. <p>size = 0
  9372. for i in range(70):
  9373. a.pencolor(random.choice(['red','orange','yellow','hotpink','magenta','deepskyblue','mediumspringgreen']))
  9374. b.right(180)
  9375. a.circle(size,extent=90)
  9376. a.forward(10)
  9377. a.right(5)
  9378. size += 1
  9379. t.done()
  9380. ```</p>
  9381. <h2>[DAY-147] While</h2>
  9382. <p>Another flower</p>
  9383. <p><img alt="game-147.png" src="./screenshots/game-147.png" title="game 147 screenshot" /></p>
  9384. <p>```
  9385. import turtle as t</p>
  9386. <p>a = t.Turtle()
  9387. a.speed(0)
  9388. a.right(90)
  9389. a.forward(300)
  9390. a.hideturtle()</p>
  9391. <p>b = t.Turtle()
  9392. b.speed(0)
  9393. b.hideturtle()</p>
  9394. <p>def square(charlie, size):
  9395. for i in range(4):
  9396. charlie.forward(size)
  9397. if i == 1:
  9398. charlie.write(str(size))
  9399. charlie.right(90)</p>
  9400. <p>size = 0
  9401. while True:
  9402. square(b,size)
  9403. b.right(9)
  9404. size += 1
  9405. if size &gt; 125:
  9406. break</p>
  9407. <p>t.done()
  9408. ```</p>
  9409. <h2>[DAY-148] Money</h2>
  9410. <p>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.</p>
  9411. <p>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.</p>
  9412. <p>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: <code>1200 revenue - 1000 expense = 200 profit</code>.</p>
  9413. <p>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.</p>
  9414. <p>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 <code>900 revenue - 800 expense = 100 profit</code>, or 90 after tax.</p>
  9415. <p>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.</p>
  9416. <p>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.</p>
  9417. <p>So on the surface it might seem like Sony is making money on the console itself, but this is actually not true.</p>
  9418. <p>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).</p>
  9419. <p>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.</p>
  9420. <p>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.</p>
  9421. <p>Facebook makes about 30 euros per month for each user they are selling.</p>
  9422. <p>Homework:</p>
  9423. <ul>
  9424. <li>Why do you think whatsapp is free?</li>
  9425. <li>Why is primary education free?</li>
  9426. <li>Why is google translate free?</li>
  9427. <li>Why is google maps free?</li>
  9428. <li>Why is google search free?</li>
  9429. <li>Why is fortnite free?</li>
  9430. <li>Why is youtube free?</li>
  9431. <li>How is tocaboca making money?</li>
  9432. <li>How are the youtube content creators making money?</li>
  9433. <li>How does H&amp;M make money?</li>
  9434. <li>How does the government make money?</li>
  9435. </ul>
  9436. <p>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.</p>
  9437. <p>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.</p>
  9438. <p>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.</p>
  9439. <p>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&amp;M or C&amp;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$?</p>
  9440. <p>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&amp;M has to figure out how to make them for 15$ instead of 20$. Maybe H&amp;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.</p>
  9441. <p>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.</p>
  9442. <p>Another thing that H&amp;M can do, is simply talk with C&amp;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.</p>
  9443. <p>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. </p>
  9444. <p>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.</p>
  9445. <p>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: <code>how is something made, who makes it and who profits from it</code>, and profit does not have to be money, could be anything that people value such as: comfort, status, fame, pride, etc.</p>
  9446. <p>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.</p>
  9447. <p>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.</p>
  9448. <h2>[DAY-149] Creators, Consumers and Ideas</h2>
  9449. <p>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.</p>
  9450. <p>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.</p>
  9451. <p>Lets just think outloud about some ideas:</p>
  9452. <ul>
  9453. <li>Ninja Fortnite where you die if you are seen</li>
  9454. <li>Fifa Minecraft where you can build your field</li>
  9455. <li>Neighbourhood Nintendo Switch game exchange library</li>
  9456. <li>1 year photo collage with your friends, one photo per day from 5 people joined in a video</li>
  9457. <li>Dog meeting app, so you know when your dog's best friend is on a walk, so you can go together</li>
  9458. <li>Neighbourhood book exchange platform</li>
  9459. <li>make/write an augmented reality book</li>
  9460. <li>AR minecraft</li>
  9461. <li>AR lasertag</li>
  9462. </ul>
  9463. <p>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 <strong>right now</strong>. 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.</p>
  9464. <p>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:</p>
  9465. <ul>
  9466. <li>have an idea</li>
  9467. <li>build a super duper simple prototype that is totally broken, but good enough to illustrate the idea</li>
  9468. <li>use your prototype for some time</li>
  9469. <li>ask your friends to use your prototype</li>
  9470. <li>delete the prototype and start from scratch</li>
  9471. <li>build MVP - minimum viable product, which is a somewhat polished prototype that you can show to more people</li>
  9472. <li>ask for money as soon as possible, nothing says that people like your product like them paying money for it.</li>
  9473. <li>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</li>
  9474. <li>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</li>
  9475. </ul>
  9476. <p>even more simplified</p>
  9477. <ul>
  9478. <li>step 1: build something [ with feedback ]</li>
  9479. <li>step 2: ask for feedback</li>
  9480. <li>step 3: ask for money if you can</li>
  9481. <li>step 4: goto step 1</li>
  9482. </ul>
  9483. <p>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.</p>
  9484. <p>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.</p>
  9485. <p>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.</p>
  9486. <p>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.</p>
  9487. <h2>[DAY-150] While; Classes</h2>
  9488. <p>Circles And Squares.</p>
  9489. <p><img alt="game-150.png" src="./screenshots/game-150.png" title="game 150 screenshot" /></p>
  9490. <p>```
  9491. from turtle import *</p>
  9492. <p>bgcolor('black')</p>
  9493. <p>a = Turtle()
  9494. a.speed(0)
  9495. a.hideturtle()</p>
  9496. <p>b = Turtle()
  9497. b.speed(0)
  9498. b.hideturtle()</p>
  9499. <p>colorA = textinput('pencolor a',"what is your name?:")
  9500. colorB = textinput('pencolor b',"what is your name?:")</p>
  9501. <p>size = 0
  9502. while True:
  9503. b.pencolor(colorB)
  9504. b.forward(size*3)
  9505. b.left(91)</p>
  9506. <pre><code>a.pencolor(colorA)
  9507. a.forward(size*10)
  9508. a.circle(size, 360)
  9509. a.left(500)
  9510. size += 1
  9511. </code></pre>
  9512. <p>```</p>
  9513. <p>More circles</p>
  9514. <p><img alt="game-150-a.png" src="./screenshots/game-150-a.png" title="game 150-a screenshot" /></p>
  9515. <p>```
  9516. import turtle as t
  9517. t.bgcolor('black')
  9518. t.hideturtle()
  9519. size = -300
  9520. t.speed(0)
  9521. while True:
  9522. if size % 2 == 0:
  9523. t.pencolor('cyan')
  9524. else:
  9525. t.pencolor('magenta')</p>
  9526. <pre><code>t.circle(size*3)
  9527. size += 1
  9528. </code></pre>
  9529. <p>```</p>
  9530. <h2>[DAY-151] Classes; While</h2>
  9531. <p><img alt="game-151.png" src="./screenshots/game-151.png" title="game 151 screenshot" /></p>
  9532. <p>First make a painting program where you can chose colors and draw rectangles</p>
  9533. <p>```
  9534. import pgzrun</p>
  9535. <p>WIDTH = 800
  9536. HEIGHT = 800</p>
  9537. <p>elf = Actor('c1')
  9538. x = 0
  9539. y = 0</p>
  9540. <p>color = None
  9541. drop = []
  9542. size = 40
  9543. def update():
  9544. global color,size</p>
  9545. <pre><code>if keyboard.W:
  9546. elf.y -= 5
  9547. if keyboard.S:
  9548. elf.y += 5
  9549. if keyboard.D:
  9550. elf.x += 5
  9551. if keyboard.A:
  9552. elf.x -= 5
  9553. if keyboard.C:
  9554. screen.clear()
  9555. if keyboard.SPACE and color != None:
  9556. drop.append([color, Rect(elf.x, elf.y, size, size)])
  9557. if keyboard.K_1:
  9558. color = (255,0,0)
  9559. if keyboard.K_2:
  9560. color = (25,41, 88)
  9561. if keyboard.K_8:
  9562. size += 1
  9563. if keyboard.K_9:
  9564. size -= 1
  9565. </code></pre>
  9566. <p>def draw():
  9567. screen.clear()
  9568. elf.draw()</p>
  9569. <pre><code>for pixel in drop:
  9570. screen.draw.rect(pixel[1],pixel[0])
  9571. if color != None:
  9572. screen.draw.rect(Rect(elf.x,elf.y,size,size), color)
  9573. </code></pre>
  9574. <p>pgzrun.go()
  9575. ```</p>
  9576. <p>Same program but making a Pixel class instead of a list with color and rect.</p>
  9577. <p>```
  9578. import pgzrun</p>
  9579. <p>WIDTH = 800
  9580. HEIGHT = 800</p>
  9581. <p>class Pixel:
  9582. def <strong>init</strong>(self, color, x, y, size):
  9583. self.color = color
  9584. self.rect = Rect(x,y,size,size)</p>
  9585. <pre><code>def draw(self):
  9586. screen.draw.rect(self.rect, self.color)
  9587. </code></pre>
  9588. <p>elf = Actor('c1')
  9589. x = 0
  9590. y = 0</p>
  9591. <p>color = None
  9592. drop = []
  9593. size = 40
  9594. def update():
  9595. global color,size</p>
  9596. <pre><code>if keyboard.W:
  9597. elf.y -= 5
  9598. if keyboard.S:
  9599. elf.y += 5
  9600. if keyboard.D:
  9601. elf.x += 5
  9602. if keyboard.A:
  9603. elf.x -= 5
  9604. if keyboard.C:
  9605. screen.clear()
  9606. if keyboard.SPACE and color != None:
  9607. pixel = Pixel(color, elf.x, elf.y, size)
  9608. drop.append(pixel)
  9609. if keyboard.K_1:
  9610. color = (255,0,0)
  9611. if keyboard.K_2:
  9612. color = (25, 41, 88)
  9613. if keyboard.K_8:
  9614. size += 1
  9615. if keyboard.K_9:
  9616. size -= 1
  9617. </code></pre>
  9618. <p>def draw():
  9619. screen.clear()
  9620. elf.draw()</p>
  9621. <pre><code>for pixel in drop:
  9622. pixel.draw()
  9623. if color != None:
  9624. screen.draw.rect(Rect(elf.x,elf.y,size,size), color)
  9625. </code></pre>
  9626. <p>pgzrun.go()
  9627. ```</p>
  9628. <p>Go back in the book and re-read the class chapter.</p>
  9629. <p>Try out some ideas with a class, just to understand better what <code>self</code> is, for example play around with this Point class, try to add <code>move_right</code> or <code>move_up</code> methods.</p>
  9630. <p>```
  9631. class Point:
  9632. def <strong>init</strong>(self, x, y):
  9633. self.x = x
  9634. self.y = y</p>
  9635. <pre><code>def move(self,x,y):
  9636. self.x = x
  9637. self.y = y
  9638. def move_left(self):
  9639. self.x -= 1
  9640. def show(self):
  9641. print(self.x, self.y)
  9642. def equal(self, other_point):
  9643. if self.x == other_point.x and self.y == other_point.y:
  9644. return True
  9645. return False
  9646. </code></pre>
  9647. <p>p1 = Point(10,20)
  9648. p2 = Point(30,40)
  9649. p3 = Point(10,20)</p>
  9650. <p>p3.move(50,60)
  9651. p1.show()</p>
  9652. <p>p2.show()</p>
  9653. <p>p3.move_left()
  9654. p3.show()</p>
  9655. <p>print(p3.equal(p1))
  9656. ```</p>
  9657. <hr />
  9658. <p>Completely unrelated and just for fun, make a triangle like pattern:</p>
  9659. <p><code>while True:
  9660. for i in range(0,10):
  9661. print(':3'* i)
  9662. for i in range(10,0,-1):
  9663. print(':D' * i)</code></p>
  9664. <p>Prints infinite sequence of smilies</p>
  9665. <p>```
  9666. :3
  9667. :3:3
  9668. :3:3:3
  9669. :3:3:3:3
  9670. :3:3:3:3:3
  9671. :3:3:3:3:3:3
  9672. :3:3:3:3:3:3:3
  9673. :3:3:3:3:3:3:3:3
  9674. :3:3:3:3:3:3:3:3:3
  9675. :D:D:D:D:D:D:D:D:D:D
  9676. :D:D:D:D:D:D:D:D:D
  9677. :D:D:D:D:D:D:D:D
  9678. :D:D:D:D:D:D:D
  9679. :D:D:D:D:D:D
  9680. :D:D:D:D:D
  9681. :D:D:D:D
  9682. :D:D:D
  9683. :D:D
  9684. :D</p>
  9685. <p>:3
  9686. :3:3
  9687. :3:3:3
  9688. :3:3:3:3
  9689. :3:3:3:3:3
  9690. :3:3:3:3:3:3
  9691. ...
  9692. ```</p>
  9693. <h2>[DAY-152] Lists</h2>
  9694. <p><img alt="game-152.png" src="./screenshots/game-152.png" title="game 152 screenshot" /></p>
  9695. <p>Make 3 actors you can pick up and drop them wherever you hit SPACE.</p>
  9696. <p>```
  9697. import pgzrun</p>
  9698. <p>WIDTH = 500
  9699. HEIGHT = 500</p>
  9700. <p>king = Actor('c2')
  9701. elf = Actor('c1')
  9702. flower = Actor('flower')
  9703. rock = Actor('rock')</p>
  9704. <p>king.x = 480
  9705. king.y = 125
  9706. flower.y = 380
  9707. flower.x = 480
  9708. rock.x = 480
  9709. rock.y = 250</p>
  9710. <p>drop = []</p>
  9711. <p>speed = 5
  9712. def update():
  9713. global speed
  9714. if keyboard.W:
  9715. elf.y -= speed
  9716. if keyboard.S:
  9717. elf.y += speed
  9718. if keyboard.D:
  9719. elf.x += speed
  9720. if keyboard.A:
  9721. elf.x -= speed
  9722. if keyboard.C:
  9723. screen.clear()</p>
  9724. <pre><code>if elf.colliderect(king):
  9725. elf.image=king.image
  9726. speed = 2
  9727. if elf.colliderect(rock):
  9728. elf.image=rock.image
  9729. speed = 1
  9730. if elf.colliderect(flower):
  9731. elf.image=flower.image
  9732. speed = 10
  9733. if keyboard.SPACE and elf.image != 'c1':
  9734. a = Actor(elf.image)
  9735. a.x = elf.x
  9736. a.y = elf.y
  9737. drop.append(a)
  9738. elf.image='c1'
  9739. speed = 5
  9740. </code></pre>
  9741. <p>def draw():
  9742. screen.clear()
  9743. elf.draw()
  9744. king.draw()
  9745. flower.draw()
  9746. rock.draw()
  9747. for d in drop:
  9748. d.draw()</p>
  9749. <p>pgzrun.go()
  9750. ```</p>
  9751. <h2>[DAY-153] Lists; Dictionaries</h2>
  9752. <p><img alt="game-153.png" src="./screenshots/game-153.png" title="game 153 screenshot" /></p>
  9753. <p>Find Waldo, here are two different implementations of the game, one uses dictionaries and one doesnt.</p>
  9754. <p>In this game, one of the actors has his back turned, and the purpose of the game is to find them.</p>
  9755. <p>We are using this example to practice lists, using <code>for element in list</code> and <code>for i in range(len(list))</code>, and overusing iterating over the list to find a matching element.</p>
  9756. <p>```
  9757. import pgzrun
  9758. import random</p>
  9759. <p>WIDTH = 800
  9760. HEIGHT = 800</p>
  9761. <p>elf = Actor('c1')
  9762. elf.x = 400
  9763. elf.y = 400
  9764. drop = []</p>
  9765. <p>def on_key_down(key):
  9766. if key == keys.SPACE:
  9767. found = False
  9768. for i in drop:
  9769. if i.image == 'c2-back':
  9770. found = True
  9771. if not found:
  9772. a = Actor('c2-back')
  9773. a.x = random.randint(0,1500)
  9774. a.y = random.randint(0,1500)
  9775. drop.append(a)
  9776. for i in range(100):
  9777. a = Actor('c2')
  9778. a.x = random.randint(0,2000)
  9779. a.y = random.randint(0,2000)
  9780. drop.append(a)
  9781. if key == keys.P:
  9782. for i in drop:
  9783. if i.image == 'c2-back':
  9784. i.x = random.randint(elf.x - 200,elf.x + 200)
  9785. i.y = random.randint(elf.y - 200,elf.y + 200)</p>
  9786. <p>waldo_found = False
  9787. def update():
  9788. global waldo_found
  9789. if keyboard.W:
  9790. for x in range(len(drop)):
  9791. i = drop[x]
  9792. i.y += 5
  9793. if keyboard.S:
  9794. for a in range(len(drop)):
  9795. drop[a].y -= 5
  9796. if keyboard.A:
  9797. for i in drop:
  9798. i.x += 5
  9799. if keyboard.D:
  9800. for i in drop:
  9801. i.x -= 5
  9802. for i in drop:
  9803. if i.image == 'c2-back' and elf.colliderect(i):
  9804. waldo_found = True</p>
  9805. <p>def draw():
  9806. screen.fill('black')
  9807. elf.draw()
  9808. for i in drop:
  9809. i.draw()
  9810. if waldo_found == True:
  9811. screen.draw.text(" YOU HAVE FOUND WALDO ", (10,10))</p>
  9812. <p>pgzrun.go()
  9813. ```</p>
  9814. <p>A second implementation where we use a <code>waldo</code> 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.</p>
  9815. <p>```
  9816. import pgzrun
  9817. import random</p>
  9818. <p>WIDTH = 800
  9819. HEIGHT = 800</p>
  9820. <p>elf = Actor('c1')
  9821. elf.x = 400
  9822. elf.y = 400
  9823. drop = []
  9824. waldo = Actor('c2-back')
  9825. seen = {}
  9826. def on_key_down(key):
  9827. if key == keys.SPACE:
  9828. waldo.x = random.randint(0,WIDTH)
  9829. waldo.y = random.randint(0,HEIGHT)
  9830. place = str(int(waldo.x/50)) + "<em>" + str(int(waldo.y/100))
  9831. seen[place] = True
  9832. for i in range(100):
  9833. x = random.randint(0,WIDTH)
  9834. y = random.randint(0,HEIGHT)
  9835. place = str(int(x/50)) + "</em>" + str(int(y/100))
  9836. if place not in seen:
  9837. a = Actor('c2')
  9838. a.x = x
  9839. a.y = y
  9840. drop.append(a)
  9841. seen[place] = True</p>
  9842. <p>waldo_found = False
  9843. def update():
  9844. global waldo_found</p>
  9845. <pre><code>if keyboard.W:
  9846. elf.y -= 5
  9847. if keyboard.S:
  9848. elf.y += 5
  9849. if keyboard.A:
  9850. elf.x -= 5
  9851. if keyboard.D:
  9852. elf.x += 5
  9853. if waldo.colliderect(elf):
  9854. waldo_found = True
  9855. </code></pre>
  9856. <p>def draw():
  9857. screen.fill('black')
  9858. elf.draw()
  9859. for i in drop:
  9860. i.draw()
  9861. waldo.draw()</p>
  9862. <pre><code>if waldo_found == True:
  9863. screen.draw.text(" YOU HAVE FOUND WALDO ", (10,10))
  9864. </code></pre>
  9865. <p>pgzrun.go()
  9866. ```</p>
  9867. <h2>[DAY-154] Classes</h2>
  9868. <p>Pacman, make things move around, stop when they hit something</p>
  9869. <p><img alt="game-154.png" src="./screenshots/game-154.png" title="game 154 screenshot" /></p>
  9870. <p>```
  9871. import random
  9872. import pgzrun</p>
  9873. <p>WIDTH = 600
  9874. HEIGHT = 600
  9875. game_over = False
  9876. lives = 3
  9877. obsticles = [
  9878. Rect(100,100,20,20),
  9879. Rect(200,200,100,200),
  9880. ]</p>
  9881. <p>class Mover:
  9882. def <strong>init</strong>(self, image, x, y, direction):
  9883. self.actor = Actor(image)
  9884. self.direction = direction
  9885. self.actor.x = x
  9886. self.actor.y = y
  9887. self.counter = 0</p>
  9888. <pre><code>def draw(self):
  9889. self.actor.draw()
  9890. def update(self):
  9891. orig_x = self.actor.x
  9892. orig_y = self.actor.y
  9893. self.counter += 1
  9894. if self.counter &gt; 120 and self.actor.image == "c2":
  9895. self.direction = random.choice(['up','down','left','right'])
  9896. self.counter = 0
  9897. if self.direction == 'up':
  9898. self.actor.y -= 1
  9899. if self.direction == 'down':
  9900. self.actor.y += 1
  9901. if self.direction == 'left':
  9902. self.actor.x -= 1
  9903. if self.direction == 'right':
  9904. self.actor.x += 1
  9905. if self.actor.x &gt; WIDTH:
  9906. self.actor.x = 0
  9907. if self.actor.x &lt; 0:
  9908. self.actor.x = WIDTH
  9909. if self.actor.y &gt; HEIGHT:
  9910. self.actor.y = 0
  9911. if self.actor.y &lt; 0:
  9912. self.actor.y = HEIGHT
  9913. hit_wall = False
  9914. for o in obsticles:
  9915. if self.actor.colliderect(o):
  9916. self.actor.x = orig_x
  9917. self.actor.y = orig_y
  9918. hit_wall = True
  9919. break
  9920. if hit_wall and self.actor.image == "c2":
  9921. self.direction = random.choice(['up','down','left','right'])
  9922. </code></pre>
  9923. <p>pacman = Mover("c1", 10, 10, 'up')
  9924. movers = [pacman,
  9925. Mover("c2", 100, 40, 'up'),
  9926. Mover("c2", 100, 50, 'up'),
  9927. Mover("c2", 100, 60, 'up'),
  9928. Mover("c2", 100, 70, 'up')
  9929. ]</p>
  9930. <p>def update():
  9931. global lives,game_over
  9932. if keyboard.W:
  9933. pacman.direction = 'up'
  9934. if keyboard.S:
  9935. pacman.direction = 'down'
  9936. if keyboard.A:
  9937. pacman.direction = 'left'
  9938. if keyboard.D:
  9939. pacman.direction = 'right'</p>
  9940. <pre><code>for m in movers:
  9941. m.update()
  9942. for o in movers:
  9943. if pacman.actor.colliderect(o.actor) and o != pacman:
  9944. lives -= 1
  9945. pacman.actor.x = 0
  9946. pacman.actor.y = 0
  9947. if lives &lt; 0:
  9948. game_over = True
  9949. </code></pre>
  9950. <p>def draw():
  9951. screen.fill('black')
  9952. for o in obsticles:
  9953. screen.draw.filled_rect(o,(255,0,0))
  9954. screen.draw.text('lives: ' + str(lives), (10,10))
  9955. if game_over == True:
  9956. screen.fill('royalblue')
  9957. screen.draw.text('GAME OVER YOU LOST',(10,10))
  9958. for m in movers:
  9959. m.draw()</p>
  9960. <p>pgzrun.go()
  9961. ```</p>
  9962. <h2>[DAY-155] c++</h2>
  9963. <p>First lets discuss a bit about the difference between <code>c++</code> and <code>python</code>. For example, lets examine what happens with the following program:</p>
  9964. <p><code>while True:
  9965. print("hello world")</code>
  9966. If you save it in the file <code>hello.py</code>, and you have to start it with <code>python hello.py</code>. Python is a program on its own, which will load the <code>hello.py</code> file and execute it line by line. The <code>python</code> program is called <code>interpreter</code> 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.</p>
  9967. <p><code>c</code> and <code>c++</code> on the other hand are compiled languages, you need a program <code>gcc</code> for c and <code>g++</code> for c++ to transform your source code to machine code, that your computer will directly run, instruction by instruction, <code>gcc</code> and <code>g++</code> are compilers.</p>
  9968. <p>Lets start where everything starts, print "Hello World". Save the following program in a file <code>hello.cpp</code> (cpp for c plus plus).</p>
  9969. <p>```</p>
  9970. <h1>include <iostream></h1>
  9971. <p>using namespace std;</p>
  9972. <p>int main(void) {
  9973. cout &lt;&lt; "Hello World " &lt;&lt; endl;
  9974. }
  9975. ```</p>
  9976. <p>Now lets compile it, <code>g++ -o hello hello.cpp</code> will make a program <code>hello</code> that you will be able to execute by running <code>./hello</code> you see it is very different, you run directly <code>hello</code> which will make your computer execute its instructions one by one, which is very different than running python to load your <code>hello.py</code>, in the python case your computer is running the python executable which loads your <code>hello.py</code> and interprets it line by line.</p>
  9977. <p><code>int main()</code> declares the <code>main</code> 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.</p>
  9978. <p><code>cout</code> means <code>character output</code> and <code>&lt;&lt;</code> means <code>pour into the cout</code> whatever follows, e.g. <code>cout &lt;&lt; 5</code> will just print 5, <code>cout "hello"</code> will print hello, <code>cout &lt;&lt; 5 &lt;&lt; "hello"</code> will print 5hello, and <code>endl</code> inserts the newline character <code>\n</code>.</p>
  9979. <p><code>using namespace std;</code> is similar to from <code>turtle import *</code>, we will get into it later</p>
  9980. <p>And very importantly you <code>c++</code> does not care about your spaces, the following program compiles just fine</p>
  9981. <p>```</p>
  9982. <h1>include <iostream></h1>
  9983. <p>using namespace std;int main(void) {cout &lt;&lt; "Hello World " &lt;&lt; endl;}
  9984. ```</p>
  9985. <p>Each code block is surrounded by <code>{}</code> and each statement ends with <code>;</code> and thats it</p>
  9986. <p>Try out the following programs, and just experiment with them using your python knowledge. (hint: <code>int</code> means integer)</p>
  9987. <p>```</p>
  9988. <h1>include <iostream></h1>
  9989. <p>using namespace std;</p>
  9990. <p>int main(void) {
  9991. int i = 1000;</p>
  9992. <p>while(i) {
  9993. if (i &lt; 500) {
  9994. cout &lt;&lt; "HIII" &lt;&lt; endl;
  9995. } else {
  9996. cout &lt;&lt; "Hello World " &lt;&lt; i &lt;&lt; endl;
  9997. }
  9998. i--;
  9999. }
  10000. }
  10001. ```</p>
  10002. <p>```</p>
  10003. <h1>include <iostream></h1>
  10004. <p>using namespace std;</p>
  10005. <p>int main(void) {
  10006. for (int i = 1000; i &gt;= 0 ; i--) {
  10007. if (i &lt; 500) {
  10008. cout &lt;&lt; "HIII " &lt;&lt; i &lt;&lt; endl;
  10009. } else {
  10010. cout &lt;&lt; "Hello World " &lt;&lt; i &lt;&lt; endl;
  10011. }
  10012. }
  10013. return 0;
  10014. }
  10015. ```</p>
  10016. <h2>[DAY-156] for; while</h2>
  10017. <p>Write the same code with for and while loops.</p>
  10018. <p>```</p>
  10019. <h1>include <iostream></h1>
  10020. <p>using namespace std;
  10021. int main(void) {
  10022. int x = 3;
  10023. while(x &lt; 3000000){
  10024. cout &lt;&lt; x &lt;&lt; endl;
  10025. x = x+3;
  10026. }
  10027. return 0;
  10028. }
  10029. ```</p>
  10030. <p>```</p>
  10031. <h1>include <iostream></h1>
  10032. <p>using namespace std;
  10033. int main(void) {
  10034. for (int x = 0; x &lt; 3000000; x = x + 3) {
  10035. cout &lt;&lt; x &lt;&lt; endl;
  10036. }
  10037. return 0;
  10038. }
  10039. ```</p>
  10040. <hr>
  10041. <p>```</p>
  10042. <h1>include <iostream></h1>
  10043. <p>using namespace std;
  10044. int main(void) {
  10045. for (int x = 10; x &gt; 0; x = x - 1) {
  10046. cout &lt;&lt; x &lt;&lt; endl;
  10047. }
  10048. return 0;
  10049. }
  10050. ```</p>
  10051. <p>```</p>
  10052. <h1>include <iostream></h1>
  10053. <p>using namespace std;
  10054. int main(void) {
  10055. int x = 10;
  10056. while(x &gt; 0){
  10057. cout &lt;&lt; x &lt;&lt; endl;
  10058. x -= 1;
  10059. }
  10060. return 0;
  10061. }
  10062. ```</p>
  10063. <hr>
  10064. <p>```</p>
  10065. <h1>include <iostream></h1>
  10066. <p>using namespace std;
  10067. int main(void) {
  10068. int x = 0;
  10069. while (x &lt; 10) {
  10070. cout &lt;&lt; x &lt;&lt; endl;
  10071. x+=1;
  10072. }
  10073. return 0;
  10074. }
  10075. ```</p>
  10076. <p>```</p>
  10077. <h1>include <iostream></h1>
  10078. <p>using namespace std;
  10079. int main(void) {
  10080. for(int x = 0; x &lt; 10; x += 1){
  10081. cout &lt;&lt; x &lt;&lt; endl;
  10082. }
  10083. return 0;
  10084. }
  10085. ```</p>
  10086. <h2>[DAY-157] strings; cin</h2>
  10087. <p>Make love tester in python:</p>
  10088. <p>```
  10089. while True:
  10090. sum = 0
  10091. name1 = input('name 1: ')
  10092. name2 = input('name 2: ')</p>
  10093. <pre><code>for i in range(len(name1)):
  10094. sum += ord(name1[i])
  10095. for i in range(len(name2)):
  10096. sum += ord(name2[i])
  10097. match = 1 + (sum % 100)
  10098. print("love test result:")
  10099. print(match)
  10100. </code></pre>
  10101. <p>```</p>
  10102. <p>Write the same program in c++:</p>
  10103. <p>```</p>
  10104. <h1>include <iostream></h1>
  10105. <p>using namespace std;
  10106. int main()
  10107. {
  10108. while(1) {
  10109. string name1;
  10110. string name2;</p>
  10111. <pre><code> cout &lt;&lt; "name1: ";
  10112. cin &gt;&gt; name1;
  10113. cout &lt;&lt; "name2: ";
  10114. cin &gt;&gt; name2;
  10115. int sum = 0;
  10116. for (int i = 0; i &lt; name1.size(); i++) {
  10117. sum += name1[i];
  10118. }
  10119. for (int i = 0; i &lt; name2.size(); i++) {
  10120. sum += name2[i];
  10121. }
  10122. int match = 1 + (sum % 100);
  10123. cout &lt;&lt; "love test result:" &lt;&lt; endl;
  10124. cout &lt;&lt; match &lt;&lt; endl;
  10125. }
  10126. </code></pre>
  10127. <p>}
  10128. ```</p>
  10129. <p><code>cin</code> is <code>character input</code>, you can perform a read operation by geting data out of cin with <code>&gt;&gt;</code>. Both <code>cin</code> and <code>cout</code> are streams. We will talk more about it later. For now just remember <code>cin &gt;&gt; variable</code> will read from the input and put the value in <code>variable</code>, and <code>cout &lt;&lt; variable</code> will print the value of the variable.</p>
  10130. <h2>[DAY-158] if; while</h2>
  10131. <p>rock paper scissors again</p>
  10132. <p>```
  10133. import random
  10134. options = ['rock','paper','scissors']</p>
  10135. <p>while True:
  10136. player = input(' '.join(options) + ': ')
  10137. if player not in options:
  10138. print("i dont know what to do with " + player)
  10139. continue
  10140. computer = random.choice(options)
  10141. print(computer)
  10142. if player == computer:
  10143. print("its a tie!")
  10144. if player == 'rock':
  10145. if computer == 'paper':
  10146. print('U lose the round')
  10147. elif computer == 'scissors':
  10148. print('U win this round')
  10149. if player == 'paper':
  10150. if computer == 'rock':
  10151. print('U win this round')
  10152. elif computer == 'scissors':
  10153. print('U lose the round')
  10154. if player == 'scissors':
  10155. if computer == 'rock':
  10156. print('U lose the round')
  10157. elif computer == 'paper':
  10158. print('U win this round')
  10159. ```</p>
  10160. <p>sum things</p>
  10161. <p>```
  10162. data = ['hello','world','earth']
  10163. r = ''
  10164. for d in data:
  10165. r += d
  10166. print(r)</p>
  10167. <p>data = [1,2,3]
  10168. r = 0
  10169. for d in data:
  10170. r += d
  10171. print(r)</p>
  10172. <p>data = [[1,2],[3,4],[5,6]]
  10173. r = []
  10174. for d in data:
  10175. r += d
  10176. print(r)
  10177. ```</p>
  10178. <p>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</p>
  10179. <h2>[DAY-159] strings; sizeof</h2>
  10180. <p>Back to basics, how are strings layed out in memory, and how many bytes the primitive types occupy in memory:</p>
  10181. <p>```</p>
  10182. <h1>include <iostream></h1>
  10183. <p>using namespace std;
  10184. int main(void) {
  10185. char c = 'a';
  10186. int x = 'a';
  10187. bool b = true;
  10188. int sum = 0;
  10189. long l = 1;
  10190. short s = 1;
  10191. float f = 0.555;
  10192. double d = 0.4123123;
  10193. long double ld = 0.123123;</p>
  10194. <pre><code>cout &lt;&lt; "char" &lt;&lt; sizeof(c) &lt;&lt; endl;
  10195. cout &lt;&lt; "bool" &lt;&lt; sizeof(b) &lt;&lt; endl;
  10196. cout &lt;&lt; "int" &lt;&lt; sizeof(sum) &lt;&lt; endl;
  10197. cout &lt;&lt; "short" &lt;&lt; sizeof(s) &lt;&lt; endl;
  10198. cout &lt;&lt; "long" &lt;&lt; sizeof(l) &lt;&lt; endl;
  10199. cout &lt;&lt; "float" &lt;&lt; sizeof(f) &lt;&lt; endl;
  10200. cout &lt;&lt; "double" &lt;&lt; sizeof(d) &lt;&lt; endl;
  10201. cout &lt;&lt; "long double" &lt;&lt; sizeof(ld) &lt;&lt; endl;
  10202. int ages[10]= {10,12,10,9,10,12,12,2,3,2};
  10203. cout &lt;&lt; sizeof(ages) &lt;&lt; endl;;
  10204. long double z[5] = {0,0,0,0,0};
  10205. cout &lt;&lt; sizeof(z) &lt;&lt; endl;;
  10206. char s1[10] = {'h','e','l','l','o','w','o','r','d','\0'};
  10207. char s2[] = "helloword";
  10208. cout &lt;&lt; s1 &lt;&lt; endl;
  10209. cout &lt;&lt; s2 &lt;&lt; endl;
  10210. </code></pre>
  10211. <p>}
  10212. ```</p>
  10213. <hr>
  10214. <p>argc and argv</p>
  10215. <p>```</p>
  10216. <h1>include <iostream></h1>
  10217. <p>using namespace std;
  10218. int main(int argc, char* argv[]) {
  10219. cout &lt;&lt; "Have " &lt;&lt; argc &lt;&lt; " arguments:" &lt;&lt; endl;
  10220. cout &lt;&lt; "my name is: " &lt;&lt; argv[0] &lt;&lt; endl;
  10221. for (int i = 0; i &lt; argc; ++i) {
  10222. cout &lt;&lt; i &lt;&lt; ": " &lt;&lt; argv[i] &lt;&lt; endl;
  10223. }
  10224. return 0;
  10225. }
  10226. <code>``
  10227. Compile the the program above as</code>g++ -o xyz file.cpp<code>, and run it with</code>./xyz hello world "aaa bbbb cccc" ddd<code>. You see</code>g++<code>has a</code>main<code>function as well, and it has</code>argc<code>and</code>argv` as well.</p>
  10228. <hr>
  10229. <p>Formatting example:</p>
  10230. <p>```</p>
  10231. <h1>include <iostream></h1>
  10232. <h1>include <iomanip></h1>
  10233. <p>using namespace std;
  10234. int main(void) {
  10235. for (int fahr=0; fahr&lt;=100; fahr+=10){
  10236. cout&lt;&lt; endl
  10237. &lt;&lt; setw(6)
  10238. &lt;&lt; setprecision(0)
  10239. &lt;&lt; fahr
  10240. &lt;&lt; setw(10)
  10241. &lt;&lt; setprecision(3)
  10242. &lt;&lt; 5.0/9.0 * (fahr-32.0);</p>
  10243. <pre><code>}
  10244. cout &lt;&lt; endl;
  10245. return(0);
  10246. </code></pre>
  10247. <p>}
  10248. ```</p>
  10249. <h2>[DAY-160] pointers</h2>
  10250. <p>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.</p>
  10251. <p>There are two important operators '*' and '&amp;', <code>int *pa = &amp;a</code> means we have a pointer (<code>*</code>) to a variable of type <code>int</code> equal to the address (<code>&amp;</code>) of variable <code>a</code>. The value of <code>pa</code> is just a number, it is literally the address of the memory where the value of <code>a</code> will be.</p>
  10252. <p>The most important concept is that <code>pa</code> is actually just a number, this is the actual value of <code>pa</code>, and with <code>*pa = 5</code> means, go to this place in memory and put 5 there, we can literally go anywhere in memory and put some value there.</p>
  10253. <p>Arrays are a continuous chunks of memory, <code>char b[10]</code> means <code>b</code> is a pointer to somewhere in memory where you hold <code>10</code> slots of type <code>char</code> which is 10 bytes. so <code>b</code> actually just holds the location of those 10 bytes. Thats right, <code>b</code> is a pointer, we can do <code>b[2] = 'a'</code> or <code>*(b + 2) = 'a'</code> they are the same thing, as <code>b[2]</code> means go to wherever <code>b</code> points to, and add 2 slots of <code>b</code>'s type, same as <code>*(b + 2)</code>.</p>
  10254. <p>Examine the following program:</p>
  10255. <p>```</p>
  10256. <h1>include <iostream></h1>
  10257. <p>using namespace std;
  10258. int main(int argc, char<em> argv[]) {
  10259. int a = 7;
  10260. int </em>pa = &a;</p>
  10261. <pre><code>*pa = 8;
  10262. cout &lt;&lt; a &lt;&lt; endl;
  10263. int b[8] = {10,11,12,13,14,15,16,17};
  10264. cout &lt;&lt; b &lt;&lt; endl;
  10265. cout &lt;&lt; (b + 3) &lt;&lt; endl;
  10266. cout &lt;&lt; *(b + 3) &lt;&lt; endl;
  10267. cout &lt;&lt; b[3] &lt;&lt; endl;
  10268. return 0;
  10269. </code></pre>
  10270. <p>}
  10271. ```</p>
  10272. <h2>[DAY-161] if; while; functions</h2>
  10273. <p>Tic tac toe with 9 variables, one for each position of the grid.</p>
  10274. <p>This is how the gameplay should look:</p>
  10275. <p>```
  10276. a b c
  10277. 0 - - -
  10278. 1 - - -
  10279. 2 - - -
  10280. [x] enter position (row col): 0 a</p>
  10281. <p>a b c
  10282. 0 x - -
  10283. 1 - - -
  10284. 2 - - -
  10285. [0] enter position (row col): 0 b</p>
  10286. <p>a b c
  10287. 0 x 0 -
  10288. 1 - - -
  10289. 2 - - -
  10290. [x] enter position (row col): 1 a</p>
  10291. <p>a b c
  10292. 0 x 0 -
  10293. 1 x - -
  10294. 2 - - -
  10295. [0] enter position (row col): 1 b</p>
  10296. <p>a b c
  10297. 0 x 0 -
  10298. 1 x 0 -
  10299. 2 - - -
  10300. [x] enter position (row col): 2 a</p>
  10301. <p>a b c
  10302. 0 x 0 -
  10303. 1 x 0 -
  10304. 2 x - -
  10305. x wins!
  10306. ```</p>
  10307. <p>And this is the code:</p>
  10308. <p>```</p>
  10309. <h1>include <iostream></h1>
  10310. <p>using namespace std;
  10311. void render(char g0, char g1, char g2, char g3, char g4, char g5, char g6, char g7, char g8) {
  10312. cout &lt;&lt; " a b c" &lt;&lt; endl;
  10313. cout &lt;&lt; "0 " &lt;&lt; g0 &lt;&lt; " " &lt;&lt; g1 &lt;&lt; " " &lt;&lt; g2 &lt;&lt; endl;
  10314. cout &lt;&lt; "1 " &lt;&lt; g3 &lt;&lt; " " &lt;&lt; g4 &lt;&lt; " " &lt;&lt; g5 &lt;&lt; endl;
  10315. cout &lt;&lt; "2 " &lt;&lt; g6 &lt;&lt; " " &lt;&lt; g7 &lt;&lt; " " &lt;&lt; g8 &lt;&lt; endl;
  10316. }</p>
  10317. <p>bool wins(char symbol, char g0, char g1, char g2, char g3, char g4, char g5, char g6, char g7, char g8) {
  10318. if (g0 == symbol &amp;&amp; g1 == symbol &amp;&amp; g2 == symbol) {
  10319. return true;
  10320. }
  10321. if (g0 == symbol &amp;&amp; g3 == symbol &amp;&amp; g6 == symbol) {
  10322. return true;
  10323. }
  10324. if (g0 == symbol &amp;&amp; g4 == symbol &amp;&amp; g8 == symbol) {
  10325. return true;
  10326. }
  10327. if (g1 == symbol &amp;&amp; g4 == symbol &amp;&amp; g7 == symbol) {
  10328. return true;
  10329. } <br />
  10330. if (g2 == symbol &amp;&amp; g5 == symbol &amp;&amp; g8 == symbol) {
  10331. return true;
  10332. }
  10333. if (g3 == symbol &amp;&amp; g4 == symbol &amp;&amp; g5 == symbol) {
  10334. return true;
  10335. } <br />
  10336. if (g6 == symbol &amp;&amp; g7 == symbol &amp;&amp; g8 == symbol) {
  10337. return true;
  10338. } <br />
  10339. if (g6 == symbol &amp;&amp; g4 == symbol &amp;&amp; g2 == symbol) {
  10340. return true;
  10341. }
  10342. return false;
  10343. }</p>
  10344. <p>int main(void) {
  10345. char g0,g1,g2,g3,g4,g5,g6,g7,g8;
  10346. g0 = g1 = g2 = g3 = g4 = g5 = g6 = g7 = g8 = '-';
  10347. char symbol = 'x';
  10348. while(1) {
  10349. render(g0,g1,g2,g3,g4,g5,g6,g7,g8);
  10350. char row,col;
  10351. cout &lt;&lt; "[" &lt;&lt; symbol &lt;&lt; "] enter position (row col): ";
  10352. cin &gt;&gt; row &gt;&gt; col;
  10353. cout &lt;&lt; endl;</p>
  10354. <pre><code> if (row == '0') {
  10355. if (col == 'a') {
  10356. g0 = symbol;
  10357. }
  10358. if (col == 'b') {
  10359. g1 = symbol;
  10360. }
  10361. if (col == 'c') {
  10362. g2 = symbol;
  10363. }
  10364. }
  10365. if (row == '1') {
  10366. if (col == 'a') {
  10367. g3 = symbol;
  10368. }
  10369. if (col == 'b') {
  10370. g4 = symbol;
  10371. }
  10372. if (col == 'c') {
  10373. g5 = symbol;
  10374. }
  10375. }
  10376. if (row == '2') {
  10377. if (col == 'a') {
  10378. g6 = symbol;
  10379. }
  10380. if (col == 'b') {
  10381. g7 = symbol;
  10382. }
  10383. if (col == 'c') {
  10384. g8 = symbol;
  10385. }
  10386. }
  10387. if (wins(symbol,g0,g1,g2,g3,g4,g5,g6,g7,g8)) {
  10388. render(g0,g1,g2,g3,g4,g5,g6,g7,g8);
  10389. cout &lt;&lt; symbol &lt;&lt; " wins!" &lt;&lt; endl;
  10390. break;
  10391. }
  10392. if (symbol == 'x') {
  10393. symbol = '0';
  10394. } else {
  10395. symbol = 'x';
  10396. }
  10397. }
  10398. return 0;
  10399. </code></pre>
  10400. <p>}
  10401. ```</p>
  10402. <h2>[DAY-162] if; while; variables</h2>
  10403. <p>Make Tic Tac Toe in python using 9 variables; Completely on your own.</p>
  10404. <blockquote>
  10405. <p>(this is the code that she wrote)</p>
  10406. </blockquote>
  10407. <p>```
  10408. def board(a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10409. print(' ',1,2,3)
  10410. print('a ',a1,a2,a3)
  10411. print('b ',b1,b2,b3)
  10412. print('c ',c1,c2,c3)</p>
  10413. <p>def game():
  10414. a1 = '-'
  10415. a2 = '-'
  10416. a3 = '-'
  10417. b1 = '-'
  10418. b2 = '-'
  10419. b3 = '-'
  10420. c1 = '-'
  10421. c2 = '-'
  10422. c3 = '-'</p>
  10423. <pre><code>xz = 'x'
  10424. while True:
  10425. board(a1,a2,a3,b1,b2,b3,c1,c2,c3)
  10426. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10427. if ask == 'a1':
  10428. a1 = xz
  10429. if ask == 'a2':
  10430. a2 = xz
  10431. if ask == 'a3':
  10432. a3 = xz
  10433. if ask == 'b1':
  10434. b1 = xz
  10435. if ask == 'b2':
  10436. b2 = xz
  10437. if ask == 'b3':
  10438. b3 = xz
  10439. if ask == 'c1':
  10440. c1 = xz
  10441. if ask == 'c2':
  10442. c2 = xz
  10443. if ask == 'c3':
  10444. c3 = xz
  10445. if a1 == xz and a2 == xz and a3 == xz:
  10446. print(xz+ ' Wins 🥳🥳🥳')
  10447. break
  10448. if a3 == xz and b3 == xz and c3 == xz:
  10449. print(xz+ ' Wins 🥳🥳🥳')
  10450. break
  10451. if a2 == xz and b2 == xz and c2 == xz:
  10452. print(xz+ ' Wins 🥳🥳🥳')
  10453. break
  10454. if a1 == xz and b1 == xz and c1 == xz:
  10455. print(xz+ ' Wins 🥳🥳🥳')
  10456. break
  10457. if c1 == xz and c2 == xz and c3 == xz:
  10458. print(xz+ ' Wins 🥳🥳🥳')
  10459. break
  10460. if b1 == xz and b2 == xz and b3 == xz:
  10461. print(xz+ ' Wins 🥳🥳🥳')
  10462. break
  10463. if c1 == xz and b2 == xz and a3 == xz:
  10464. print(xz+ ' Wins 🥳🥳🥳')
  10465. break
  10466. if a1 == xz and b2 == xz and c3 == xz:
  10467. print(xz+ ' Wins 🥳🥳🥳')
  10468. break
  10469. if xz == 'x':
  10470. xz = '0'
  10471. else:
  10472. xz = 'x'
  10473. </code></pre>
  10474. <p>game()
  10475. ```</p>
  10476. <p>Another way to write the same program, using few function.</p>
  10477. <p>```
  10478. def print_board(a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10479. print(' ',1,2,3)
  10480. print('a ',a1,a2,a3)
  10481. print('b ',b1,b2,b3)
  10482. print('c ',c1,c2,c3)</p>
  10483. <p>def win(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10484. if a1 == xz and a2 == xz and a3 == xz:
  10485. return True
  10486. if a3 == xz and b3 == xz and c3 == xz:
  10487. return True
  10488. if a2 == xz and b2 == xz and c2 == xz:
  10489. return True
  10490. if a1 == xz and b1 == xz and c1 == xz:
  10491. return True
  10492. if c1 == xz and c2 == xz and c3 == xz:
  10493. return True
  10494. if b1 == xz and b2 == xz and b3 == xz:
  10495. return True
  10496. if c1 == xz and b2 == xz and a3 == xz:
  10497. return True
  10498. if a1 == xz and b2 == xz and c3 == xz:
  10499. return True
  10500. return False</p>
  10501. <p>def get_input(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10502. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10503. if ask == 'a1':
  10504. a1 = xz
  10505. if ask == 'a2':
  10506. a2 = xz
  10507. if ask == 'a3':
  10508. a3 = xz
  10509. if ask == 'b1':
  10510. b1 = xz
  10511. if ask == 'b2':
  10512. b2 = xz
  10513. if ask == 'b3':
  10514. b3 = xz
  10515. if ask == 'c1':
  10516. c1 = xz
  10517. if ask == 'c2':
  10518. c2 = xz
  10519. if ask == 'c3':
  10520. c3 = xz <br />
  10521. return a1,a2,a3,b1,b2,b3,c1,c2,c3</p>
  10522. <p>def game():
  10523. a1 = a2 = a3 = b1 = b2 = b3 = c1 = c2 = c3 = '-'
  10524. xz = 'x'
  10525. while True:
  10526. print_board(a1,a2,a3,b1,b2,b3,c1,c2,c3)
  10527. a1,a2,a3,b1,b2,b3,c1,c2,c3 = get_input(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3)</p>
  10528. <pre><code> if win(xz, a1,a2,a3,b1,b2,b3,c1,c2,c3):
  10529. print(xz + " WINS 🥳🥳🥳!!!")
  10530. break
  10531. if xz == 'x':
  10532. xz = '0'
  10533. else:
  10534. xz = 'x'
  10535. </code></pre>
  10536. <p>game()
  10537. ```</p>
  10538. <p>Now the game loop is very obvious:</p>
  10539. <ul>
  10540. <li>print the board</li>
  10541. <li>get the input and modify the variables</li>
  10542. <li>check if there is a winnner</li>
  10543. <li>swap the symbol (from x to 0 and from 0 to x)</li>
  10544. </ul>
  10545. <p>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'.</p>
  10546. <h2>[DAY-163] if; while; lists</h2>
  10547. <p>Do the same tic tac toe but with a list instead of 9 variables</p>
  10548. <p><img alt="game-163.png" src="./screenshots/game-163.png" title="game 163 screenshot" /></p>
  10549. <blockquote>
  10550. <p>(this is the code that she wrote)</p>
  10551. </blockquote>
  10552. <p>```
  10553. def board(g):
  10554. print(' ',1,2,3)
  10555. print('a ',g[0],g[1],g[2])
  10556. print('b ',g[3],g[4],g[5])
  10557. print('c ',g[6],g[7],g[8])</p>
  10558. <p>def game():
  10559. g = ['-','-','-','-','-','-','-','-','-']</p>
  10560. <pre><code>xz = 'x'
  10561. while True:
  10562. board(g)
  10563. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10564. if ask == 'a1':
  10565. g[0] = xz
  10566. if ask == 'a2':
  10567. g[1] = xz
  10568. if ask == 'a3':
  10569. g[2] = xz
  10570. if ask == 'b1':
  10571. g[3] = xz
  10572. if ask == 'b2':
  10573. g[4] = xz
  10574. if ask == 'b3':
  10575. g[5] = xz
  10576. if ask == 'c1':
  10577. g[6] = xz
  10578. if ask == 'c2':
  10579. g[7] = xz
  10580. if ask == 'c3':
  10581. g[8] = xz
  10582. if g[0] == xz and g[1] == xz and g[2] == xz:
  10583. print(xz+ ' Wins 🥳🥳🥳')
  10584. break
  10585. if g[3] == xz and g[4] == xz and g[5] == xz:
  10586. print(xz+ ' Wins 🥳🥳🥳')
  10587. break
  10588. if g[6] == xz and g[7] == xz and g[8] == xz:
  10589. print(xz+ ' Wins 🥳🥳🥳')
  10590. break
  10591. if g[1] == xz and g[4] == xz and g[7] == xz:
  10592. print(xz+ ' Wins 🥳🥳🥳')
  10593. break
  10594. if g[0] == xz and g[3] == xz and g[6] == xz:
  10595. print(xz+ ' Wins 🥳🥳🥳')
  10596. break
  10597. if g[2] == xz and g[5] == xz and g[8] == xz:
  10598. print(xz+ ' Wins 🥳🥳🥳')
  10599. break
  10600. if g[0] == xz and g[4] == xz and g[8] == xz:
  10601. print(xz+ ' Wins 🥳🥳🥳')
  10602. break
  10603. if g[2] == xz and g[4] == xz and g[6] == xz:
  10604. print(xz+ ' Wins 🥳🥳🥳')
  10605. break
  10606. if xz == 'x':
  10607. xz = '0'
  10608. else:
  10609. xz = 'x'
  10610. </code></pre>
  10611. <p>game()
  10612. ```</p>
  10613. <p>alternative way of writing this:</p>
  10614. <p>```
  10615. def board(g):
  10616. print(' ',1,2,3)
  10617. print('a ',g[0],g[1],g[2])
  10618. print('b ',g[3],g[4],g[5])
  10619. print('c ',g[6],g[7],g[8])</p>
  10620. <p>def check(g, xz, i1,i2,i3):
  10621. if g[i1] == xz and g[i2] == xz and g[i3] == xz:
  10622. return True
  10623. return False</p>
  10624. <p>def game():
  10625. g = ['-','-','-','-','-','-','-','-','-']</p>
  10626. <pre><code>xz = 'x'
  10627. while True:
  10628. # print the board
  10629. board(g)
  10630. # get the input and update the game board
  10631. ask = input(xz + ' choose a number from 1,2,3 and a letter from a,b,c: ')
  10632. index = 0
  10633. if ask[0] == 'a':
  10634. index = 0 + int(ask[1]) - 1 # convert a1 to index 0, a3 to index 3
  10635. if ask[0] == 'b':
  10636. index = 3 + int(ask[1]) - 1 # convert b1 to index 3 and b3 to index 5
  10637. if ask[0] == 'c':
  10638. index = 6 + int(ask[1]) - 1 # convert c1 to index 6 and c3 to index 8
  10639. g[index] = xz
  10640. # check if we have a winner
  10641. # horizontal
  10642. if check(g,xz,0,1,2) or check(g,xz,3,4,5) or check(g,xz,6,7,8):
  10643. print(xz+ ' Wins 🥳🥳🥳')
  10644. break
  10645. # vertical
  10646. if check(g,xz,1,4,7) or check(g,xz,0,3,6) or check(g,xz,2,5,8):
  10647. print(xz+ ' Wins 🥳🥳🥳')
  10648. break
  10649. # diagonal
  10650. if check(g,xz,0,4,8) or check(g,xz,2,4,6):
  10651. print(xz+ ' Wins 🥳🥳🥳')
  10652. break
  10653. # swap the synmbol for the next turn
  10654. if xz == 'x':
  10655. xz = '0'
  10656. else:
  10657. xz = 'x'
  10658. </code></pre>
  10659. <p>game()
  10660. ```</p>
  10661. <h2>[DAY-164] pointers</h2>
  10662. <p>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.</p>
  10663. <p><code>t.z.t -&gt; ten zijner tijd
  10664. v.l.n.r -&gt; van links naar rechts
  10665. e.d -&gt; en dergelijk
  10666. nr. -&gt; nummer
  10667. zg. -&gt; zogenaamd
  10668. Gebr. -&gt; gebroeders
  10669. dr. -&gt; doctor
  10670. s.v.p -&gt; s'il vous plait
  10671. t.o.v -&gt; ten opzichte van
  10672. nl. -&gt; namelijk
  10673. N.B. -&gt; Nota Bene
  10674. sr. -&gt; senior
  10675. jr. -&gt; junior
  10676. C -&gt; Celsius
  10677. etc -&gt; etcetra
  10678. t.a.v -&gt; ter attentie van
  10679. P.S. -&gt; postscriptum
  10680. B. en W. -&gt; Burgemeesteren Wethouders
  10681. NL -&gt; Nederland
  10682. v.a -&gt; vanaf
  10683. drs -&gt; doctorandes</code></p>
  10684. <p>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 <code>abbreviations[i]</code> and compare it with <code>meaning[i]</code></p>
  10685. <p>```
  10686. import random
  10687. def test(taal,toets):
  10688. i = random.randint(0,len(taal)-1)
  10689. f = input(taal[i]+ ': ')
  10690. if f == toets[i]:
  10691. print('corect')
  10692. else:
  10693. print("WRONG, one more try!")
  10694. f = input(taal[i]+ ': ')
  10695. if f == toets[i]:
  10696. print('corect')
  10697. else:
  10698. print('better luck next time the correct answer was: '+toets[i])</p>
  10699. <p>short = ['t.z.t','v.l.n.r','e.d','nr.','zg.','Gebr.','dr.',
  10700. 's.v.p','t.o.v','nl.','N.B.','sr.','jr.','C',
  10701. 'etc','t.a.v','P.S.','B. en W.','NL','v.a','drs']</p>
  10702. <p>long = ['ten zijner tijd','van links naar rechts','en dergelijk',
  10703. 'nummer','zogenaamd','gebroeders','doctor',
  10704. "s'il vous plait",'ten opzichte van','namelijk',
  10705. 'Nota Bene','senior','junior','Celsius',
  10706. 'etcetra','ter attentie van','postscriptum',
  10707. 'Burgemeesteren Wethouders','Nederland','vanaf','doctorandes']</p>
  10708. <p>for i in range(len(short)):
  10709. print(short[i] + ' -&gt; ' + long[i])</p>
  10710. <p>while True:
  10711. test(short,long)
  10712. test(long, short)
  10713. ```</p>
  10714. <h2>[DAY-165] if; while</h2>
  10715. <p>Another tic tac toe on your own</p>
  10716. <blockquote>
  10717. <p>(this is the code she wrote)</p>
  10718. </blockquote>
  10719. <p>```
  10720. def board(g):
  10721. print(' ',1,2,3)
  10722. print('a',g[0],g[1],g[2])
  10723. print('b',g[3],g[4],g[5])
  10724. print('c',g[6],g[7],g[8])</p>
  10725. <p>g = ['-']*9
  10726. idk = 'x'
  10727. while True:
  10728. board(g)
  10729. l = input(idk + 'choose a number 1,2,3 and a letter a,b,c: ')</p>
  10730. <pre><code>if l == 'a1':
  10731. g[0] = idk
  10732. if l == 'a2':
  10733. g[1] = idk
  10734. if l == 'a3':
  10735. g[2] = idk
  10736. if l == 'b1':
  10737. g[3] = idk
  10738. if l == 'b2':
  10739. g[4] = idk
  10740. if l == 'b3':
  10741. g[5] = idk
  10742. if l == 'c1':
  10743. g[6] = idk
  10744. if l == 'c2':
  10745. g[7] = idk
  10746. if l == 'c3':
  10747. g[8] = idk
  10748. if g[0] == idk and g[1] == idk and g[2] == idk:
  10749. print(idk+' Won congratulations 🥳🥳🥳')
  10750. break
  10751. if g[3] == idk and g[4] == idk and g[5] == idk:
  10752. print(idk+' Won congratulations 🥳🥳🥳')
  10753. break
  10754. if g[6] == idk and g[7] == idk and g[8] == idk:
  10755. print(idk+' Won congratulations 🥳🥳🥳')
  10756. break
  10757. if g[0] == idk and g[3] == idk and g[6] == idk:
  10758. print(idk+' Won congratulations 🥳🥳🥳')
  10759. break
  10760. if g[1] == idk and g[4] == idk and g[7] == idk:
  10761. print(idk+' Won congratulations 🥳🥳🥳')
  10762. break
  10763. if g[2] == idk and g[5] == idk and g[8] == idk:
  10764. print(idk+ ' Won congratulations 🥳🥳🥳')
  10765. break
  10766. if g[2] == idk and g[4] == idk and g[6] == idk:
  10767. print(idk+ 'Won congratulations 🥳🥳🥳')
  10768. break
  10769. if g[0] == idk and g[4] == idk and g[8] == idk:
  10770. print(idk+' Won congratulations 🥳🥳🥳')
  10771. break
  10772. done = True
  10773. for e in g:
  10774. if e == '-':
  10775. done = False
  10776. if done:
  10777. print('Its a tie')
  10778. break
  10779. if idk == 'x':
  10780. idk = '0'
  10781. else:
  10782. idk = 'x'
  10783. </code></pre>
  10784. <p>board(g)
  10785. ```</p>
  10786. <h2>[DAY-166] if; while</h2>
  10787. <p>Write tic tac toe on your own but 4x4 instead of 3x3.</p>
  10788. <blockquote>
  10789. <p>(this is the code she wrote)</p>
  10790. </blockquote>
  10791. <p>```
  10792. def board(g):
  10793. print(' ',1,2,3,4)
  10794. print('a',g[0],g[1],g[2],g[3])
  10795. print('b',g[4],g[5],g[6],g[7])
  10796. print('c',g[8],g[9],g[10],g[11])
  10797. print('d',g[12],g[13],g[14],g[15])</p>
  10798. <p>g = ['-']*16
  10799. idk = 'x'
  10800. while True:
  10801. board(g)
  10802. l = input(idk + 'choose a number 1,2,3 and a letter a,b,c: ')</p>
  10803. <pre><code>if l == 'a1':
  10804. g[0] = idk
  10805. if l == 'a2':
  10806. g[1] = idk
  10807. if l == 'a3':
  10808. g[2] = idk
  10809. if l == 'a4':
  10810. g[3] = idk
  10811. if g[0] == idk and g[1] == idk and g[2] == idk and g[3] == idk:
  10812. print(idk+' Won congratulations 🥳🥳🥳')
  10813. break
  10814. # ...
  10815. if idk == 'x':
  10816. idk = '0'
  10817. else:
  10818. idk = 'x'
  10819. </code></pre>
  10820. <p>board(g)
  10821. ```</p>
  10822. <h2>[DAY-167] C; printf; scanf</h2>
  10823. <p>We will use <code>printf</code> to display text and <code>scanf</code> to read text input from the user. First compile the following program, save it to a file <code>hello.c</code> and run <code>gcc -o hello hello.c</code> the C compiler we will use is called <code>gcc</code>, just as the C++ compiler we used was called <code>g++</code>, and the options are again <code>-o</code> for 'output file name' and then the source code file <code>hello.c</code>.</p>
  10824. <p>```</p>
  10825. <h1>include <stdio.h></h1>
  10826. <p>int main(void) {
  10827. int age = 0;</p>
  10828. <pre><code>printf("How old are you: ");
  10829. scanf("%d",&amp;age);
  10830. if (age &gt; 10) {
  10831. printf("you are a grownup\n");
  10832. } else {
  10833. printf("are you a little kid, %d %d %c\n", age, 102, 103);
  10834. }
  10835. return 0;
  10836. </code></pre>
  10837. <p>}
  10838. ```</p>
  10839. <p>Now lets read it line by line, first we make a variable <code>age</code> of type <code>integer</code> with initial value of <code>0</code>, then we print "How old are you" using <code>printf</code>, and immidiately after tat we do <code>scanf("%d",&amp;age)</code>, first we say to scanf that we are looking for a integer <code>%d</code> and then once it reads an integer to put it on memory where the variable <code>age</code> is located at. With the <code>&amp;</code> symbol we take the memory address of the variable.</p>
  10840. <p>Then we compare if the age that the user entered is &gt; 10, we print one thing, and if not we print <code>printf("are you a little kid, %d %d %c\n", age, 102, 103);</code> this will print the age itself (the first %d) will use the second parameter which is <code>age</code>, then the second %d will print 102, and then %c will print the ascii value of 103 (g).</p>
  10841. <p>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.</p>
  10842. <p>This is just the first steps towards C, dont worry if you dont get the <code>&amp;</code> thing and the memory address, with some practice things will click and it will all make sense.</p>
  10843. <p>Lets say your coputer has only 30 bytes of memory:</p>
  10844. <p><code>00-09|..........|
  10845. 10-19|0000......| int age at memory address 10, occupying 4 bytes
  10846. 20-29|..........|
  10847. 30-39|PPPPPPPPPP| the program itself</code></p>
  10848. <p><code>&amp;age</code> is the address of age, which is 10, its as simple as that, <code>scanf</code> gets the value 10 as the location in memory in which it should write down the number that it processed from the user input.</p>
  10849. <h2>[DAY-168] c; while; if</h2>
  10850. <p>Rock paper scissors in C.</p>
  10851. <p>```</p>
  10852. <h1>include <stdio.h></h1>
  10853. <h1>include <stdlib.h></h1>
  10854. <h1>define ROCK 0</h1>
  10855. <h1>define PAPER 1</h1>
  10856. <h1>define SCISSORS 2</h1>
  10857. <p>int main(void) {
  10858. while (1) {
  10859. int player;
  10860. printf("rock(0) paper(1) scissors(2): ");
  10861. scanf("%d", &amp;player);</p>
  10862. <pre><code> int computer = rand() % 3;
  10863. printf("player: %d, computer: %d\n", player, computer);
  10864. if (computer == player) {
  10865. printf("its a tie\n");
  10866. } else {
  10867. if (computer == ROCK &amp;&amp; player == PAPER) {
  10868. printf("player wins\n");
  10869. }
  10870. if (computer == ROCK &amp;&amp; player == SCISSORS) {
  10871. printf("computer wins\n");
  10872. }
  10873. if (computer == PAPER &amp;&amp; player == ROCK) {
  10874. printf("computer wins\n");
  10875. }
  10876. if (computer == PAPER &amp;&amp; player == SCISSORS) {
  10877. printf("player wins\n");
  10878. }
  10879. if (computer == SCISSORS &amp;&amp; player == ROCK) {
  10880. printf("player wins\n");
  10881. }
  10882. if (computer == SCISSORS &amp;&amp; player == PAPER) {
  10883. printf("computer wins\n");
  10884. }
  10885. }
  10886. }
  10887. return 0;
  10888. </code></pre>
  10889. <p>}
  10890. ```</p>
  10891. <p><code>#define ROCK 0</code> just makes the c compiler to replace ROCK with 0 wherever it sees it in the source code. </p>
  10892. <p><code>#include &lt;stdlib.h&gt;</code> is needed for the <code>rand</code> function, it returns an integer, but since we need a number from 0, 1, 2 we just do <code>rand() % 3</code>, which will take the reminder from the random number and 3.</p>
  10893. <p>Try this in python:</p>
  10894. <p><code>for i in range(100000):
  10895. print(i, i % 3)</code></p>
  10896. <p>You will see:</p>
  10897. <p><code>0 0
  10898. 1 1
  10899. 2 2
  10900. 3 0
  10901. 4 1
  10902. 5 2
  10903. 6 0
  10904. 7 1
  10905. 8 2
  10906. 9 0
  10907. 10 1
  10908. 11 2
  10909. 12 0
  10910. 13 1
  10911. 14 2
  10912. 15 0
  10913. 16 1
  10914. 17 2
  10915. 18 0
  10916. 19 1
  10917. 20 2
  10918. 21 0
  10919. 22 1
  10920. 23 2
  10921. 24 0
  10922. 25 1
  10923. 26 2
  10924. 27 0
  10925. 28 1
  10926. 29 2
  10927. 30 0
  10928. 31 1
  10929. 32 2
  10930. 33 0
  10931. 34 1
  10932. 35 2
  10933. 36 0
  10934. 37 1
  10935. 38 2
  10936. 39 0
  10937. 40 1
  10938. 41 2
  10939. 42 0
  10940. 43 1
  10941. 44 2
  10942. 45 0
  10943. 46 1
  10944. 47 2
  10945. 48 0
  10946. 49 1
  10947. 50 2
  10948. 51 0
  10949. 52 1
  10950. 53 2
  10951. 54 0
  10952. ...</code></p>
  10953. <h2>[DAY-169] c; while; if</h2>
  10954. <p>Battle ship in C.</p>
  10955. <p>Arrays are continous block of memory, for example <code>int x[10]</code> creates 10 integers (4 bytes each, so 40 bytes block), you can access each element by its index from <code>x[0]</code> to <code>x[9]</code>, e.g. <code>x[2] = 5</code> will set the 3rd element to be equal to 5.</p>
  10956. <p>In C it is very easy to have multi dimensional arrays, simply say <code>int x[10][10]</code> 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.</p>
  10957. <p>```</p>
  10958. <h1>include <stdio.h></h1>
  10959. <h1>include <stdlib.h></h1>
  10960. <h1>define SIZE 10</h1>
  10961. <p>int main(void) {
  10962. int hidden[SIZE][SIZE];
  10963. int display[SIZE][SIZE];
  10964. for (int i = 0; i &lt; SIZE; i++) {
  10965. for (int j = 0; j &lt; SIZE; j++) {
  10966. hidden[i][j] = 0;
  10967. display[i][j] = 0;
  10968. }
  10969. }</p>
  10970. <pre><code>// make 20 random ships
  10971. for (int i = 0; i &lt; 20; i++) {
  10972. hidden[rand() % SIZE][rand() % SIZE] = 1;
  10973. }
  10974. while (1) {
  10975. // print the display board
  10976. for (int i = 0; i &lt; SIZE; i++) {
  10977. for (int j = 0; j &lt; SIZE; j++) {
  10978. printf("%d ", display[i][j]);
  10979. }
  10980. printf("\n");
  10981. }
  10982. // get the row and column from the user
  10983. int row, column;
  10984. printf("row column&gt; ");
  10985. scanf("%d %d", &amp;row, &amp;column);
  10986. // modify the display board depending if ship is
  10987. // found in the hidden board or not.
  10988. if (hidden[row][column] == 1) {
  10989. display[row][column] = 1;
  10990. } else {
  10991. display[row][column] = 2;
  10992. }
  10993. }
  10994. return 0;
  10995. </code></pre>
  10996. <p>}
  10997. ```</p>
  10998. <h2>[DAY-170] pointers</h2>
  10999. <p>Watch "What Are Pointers? (C++)", by javidx9 on youtube. https://www.youtube.com/watch?v=iChalAKXffs</p>
  11000. <h2>[DAY-171] while; for; if; list</h2>
  11001. <p>Build a chess game in 3 days.</p>
  11002. <ul>
  11003. <li>day 1, build the board, black and white squares, think carefully about the algorithm how to alternate between the colors</li>
  11004. <li>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)</li>
  11005. <li>day 3, polish the pieces, make it possible to take a piece</li>
  11006. <li>todo: add queening the pawn code later</li>
  11007. <li>todo: add restrictions to illegal moves</li>
  11008. </ul>
  11009. <p><img alt="game-171.png" src="./screenshots/game-171.png" title="game 171 screenshot" /></p>
  11010. <blockquote>
  11011. <p>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.</p>
  11012. </blockquote>
  11013. <p>```
  11014. import pgzrun
  11015. HEIGHT = 800
  11016. WIDTH = 800</p>
  11017. <p>board = []</p>
  11018. <p>black = [
  11019. Actor('chess/rook-black',anchor=(0,0), pos=(0,0)),
  11020. Actor('chess/knight-black',anchor=(0,0), pos=(100,0)),
  11021. Actor('chess/bishop-black',anchor=(0,0), pos=(200,0)),
  11022. Actor('chess/queen-black',anchor=(0,0), pos=(300,0)),
  11023. Actor('chess/king-black',anchor=(0,0), pos=(400,0)),
  11024. Actor('chess/bishop-black',anchor=(0,0), pos=(500,0)),
  11025. Actor('chess/knight-black',anchor=(0,0), pos=(600,0)),
  11026. Actor('chess/rook-black',anchor=(0,0), pos=(700,0)),
  11027. Actor('chess/pawn-black',anchor=(0,0), pos=(0,100)),
  11028. Actor('chess/pawn-black',anchor=(0,0), pos=(100,100)),
  11029. Actor('chess/pawn-black',anchor=(0,0), pos=(200,100)),
  11030. Actor('chess/pawn-black',anchor=(0,0), pos=(300,100)),
  11031. Actor('chess/pawn-black',anchor=(0,0), pos=(400,100)),
  11032. Actor('chess/pawn-black',anchor=(0,0), pos=(500,100)),
  11033. Actor('chess/pawn-black',anchor=(0,0), pos=(600,100)),
  11034. Actor('chess/pawn-black',anchor=(0,0), pos=(700,100)),
  11035. ]</p>
  11036. <p>white = [
  11037. Actor('chess/pawn-white',anchor=(0,0), pos=(0,600)),
  11038. Actor('chess/pawn-white',anchor=(0,0), pos=(100,600)),
  11039. Actor('chess/pawn-white',anchor=(0,0), pos=(200,600)),
  11040. Actor('chess/pawn-white',anchor=(0,0), pos=(300,600)),
  11041. Actor('chess/pawn-white',anchor=(0,0), pos=(400,600)),
  11042. Actor('chess/pawn-white',anchor=(0,0), pos=(500,600)),
  11043. Actor('chess/pawn-white',anchor=(0,0), pos=(600,600)),
  11044. Actor('chess/pawn-white',anchor=(0,0), pos=(700,600)),
  11045. Actor('chess/rook-white',anchor=(0,0), pos=(0,700)),
  11046. Actor('chess/knight-white',anchor=(0,0), pos=(100,700)),
  11047. Actor('chess/bishop-white',anchor=(0,0), pos=(200,700)),
  11048. Actor('chess/queen-white',anchor=(0,0), pos=(300,700)),
  11049. Actor('chess/king-white',anchor=(0,0), pos=(400,700)),
  11050. Actor('chess/bishop-white',anchor=(0,0), pos=(500,700)),
  11051. Actor('chess/knight-white',anchor=(0,0), pos=(600,700)),
  11052. Actor('chess/rook-white',anchor=(0,0), pos=(700,700)),
  11053. ]
  11054. x = 0
  11055. y = 0</p>
  11056. <p>block = 0
  11057. for i in range(1,65):
  11058. if block % 2 == 0:
  11059. board.append(Actor('chess/white',anchor=(0,0), pos=(x,y)))
  11060. else:
  11061. board.append(Actor('chess/black',anchor=(0,0), pos=(x,y)))</p>
  11062. <pre><code>block += 1
  11063. x += 100
  11064. if i != 0 and i%8 == 0:
  11065. y += 100
  11066. x = 0
  11067. block+=3
  11068. </code></pre>
  11069. <p>pick_white = None
  11070. pick_black = None
  11071. elf = Actor("c1",ancor=(0,0))
  11072. king = Actor("c2")</p>
  11073. <p>def on_key_down(key):
  11074. global pick_white,pick_black</p>
  11075. <pre><code>if key == keys.R and pick_white == None:
  11076. # pick up the piece below
  11077. for w in white:
  11078. if elf.colliderect(w):
  11079. pick_white = w
  11080. elif key == keys.R and pick_white != None:
  11081. for b in board:
  11082. # shouldnt be able to drop if there is already white piece there
  11083. if elf.colliderect(b):
  11084. for w in white:
  11085. if w != pick_white and b.colliderect(w):
  11086. return
  11087. # snap the white piece to the board
  11088. pick_white.x = b.x
  11089. pick_white.y = b.y
  11090. # take the black piece if there
  11091. for bl in list(black):
  11092. if bl.colliderect(pick_white):
  11093. black.remove(bl)
  11094. # drop it
  11095. pick_white = None
  11096. break
  11097. if key == keys.P and pick_black == None:
  11098. # pick up the piece below
  11099. for b in black:
  11100. if king.colliderect(b):
  11101. pick_black = b
  11102. elif key == keys.P and pick_black != None:
  11103. for b in board:
  11104. if king.colliderect(b):
  11105. # dont allow a drop if there is already a black piece there
  11106. for l in black:
  11107. if l != pick_black and b.colliderect(l):
  11108. return
  11109. # snap the black piece to the board
  11110. pick_black.x = b.x
  11111. pick_black.y = b.y
  11112. # take the white piece if there
  11113. for w in list(white):
  11114. if w.colliderect(pick_black):
  11115. white.remove(w)
  11116. # drop it
  11117. pick_black = None
  11118. break
  11119. </code></pre>
  11120. <p>def update():
  11121. global pick_white,pick_black
  11122. speed = 2</p>
  11123. <pre><code>if keyboard.W:
  11124. elf.y -= 5
  11125. if keyboard.S:
  11126. elf.y += 5
  11127. if keyboard.A:
  11128. elf.x -= 5
  11129. if keyboard.D:
  11130. elf.x += 5
  11131. if keyboard.UP:
  11132. king.y -= 5
  11133. if keyboard.DOWN:
  11134. king.y += 5
  11135. if keyboard.LEFT:
  11136. king.x -= 5
  11137. if keyboard.RIGHT:
  11138. king.x += 5
  11139. # move the white piece with the elf
  11140. if pick_white != None:
  11141. pick_white.x = elf.x - 30
  11142. pick_white.y = elf.y - 30
  11143. # move the black piece with the king
  11144. if pick_black != None:
  11145. pick_black.x = king.x - 30
  11146. pick_black.y = king.y - 30
  11147. </code></pre>
  11148. <p>def draw():
  11149. screen.fill('deepskyblue')</p>
  11150. <pre><code>for b in board:
  11151. b.draw()
  11152. for b in black:
  11153. b.draw()
  11154. for w in white:
  11155. w.draw()
  11156. elf.draw()
  11157. king.draw()
  11158. </code></pre>
  11159. <p>pgzrun.go()
  11160. ```</p>
  11161. <h2>[DAY-172] if</h2>
  11162. <p>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.</p>
  11163. <p>```</p>
  11164. <h1>...</h1>
  11165. <h1>shouldnt be able to drop if there is already white piece there</h1>
  11166. <p>if elf.colliderect(b):
  11167. for w in white:
  11168. if w != pick_white and b.colliderect(w):
  11169. return</p>
  11170. <pre><code># snap the white piece to the board
  11171. pick_white.x = b.x
  11172. pick_white.y = b.y
  11173. # take the black piece if there
  11174. for bl in list(black):
  11175. if bl.colliderect(pick_white):
  11176. black.remove(bl)
  11177. # Queening the Pawn:
  11178. # pick_white.image is chess/pawn-white for the white pawn
  11179. # set the pick_white.image to chess/queen-white if it reaches the black end of the board
  11180. if pick_white.image == 'chess/pawn-white' and pick_white.y == 0:
  11181. pick_white.image = 'chess/queen-white'
  11182. # drop it
  11183. pick_white = None
  11184. break
  11185. </code></pre>
  11186. <h1>...</h1>
  11187. <p>```</p>
  11188. <p>and respective for the black pawn:</p>
  11189. <p>```</p>
  11190. <h1>...</h1>
  11191. <pre><code>if pick_black.image == 'chess/pawn-black' and pick_black.y == 700:
  11192. pick_black.image = 'chess/queen-black'
  11193. # drop it
  11194. pick_black = None
  11195. </code></pre>
  11196. <h1>...</h1>
  11197. <p>```</p>
  11198. <h2>[DAY-173] if; variables</h2>
  11199. <p>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 <code>for b in board</code> and then we were using <code>b.x</code> and etc, which was kind of confusing. We will rename it for <code>for square in board</code> and you will see how much more readable the code is.</p>
  11200. <p>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 <code>x</code> and <code>y</code> and once we select which piece we will be moving we will store the piece's .x and .y properties into our <code>x</code> and <code>y</code> variables.</p>
  11201. <p>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).</p>
  11202. <p>This is the whole program again, because of the rename of some variables, it is easier to re-read it.</p>
  11203. <p>```
  11204. import pgzrun
  11205. HEIGHT = 800
  11206. WIDTH = 800</p>
  11207. <p>board = []</p>
  11208. <p>black = [
  11209. Actor('chess/rook-black',anchor=(0,0), pos=(0,0)),
  11210. Actor('chess/knight-black',anchor=(0,0), pos=(100,0)),
  11211. Actor('chess/bishop-black',anchor=(0,0), pos=(200,0)),
  11212. Actor('chess/queen-black',anchor=(0,0), pos=(300,0)),
  11213. Actor('chess/king-black',anchor=(0,0), pos=(400,0)),
  11214. Actor('chess/bishop-black',anchor=(0,0), pos=(500,0)),
  11215. Actor('chess/knight-black',anchor=(0,0), pos=(600,0)),
  11216. Actor('chess/rook-black',anchor=(0,0), pos=(700,0)),
  11217. Actor('chess/pawn-black',anchor=(0,0), pos=(0,100)),
  11218. Actor('chess/pawn-black',anchor=(0,0), pos=(100,100)),
  11219. Actor('chess/pawn-black',anchor=(0,0), pos=(200,100)),
  11220. Actor('chess/pawn-black',anchor=(0,0), pos=(300,100)),
  11221. Actor('chess/pawn-black',anchor=(0,0), pos=(400,100)),
  11222. Actor('chess/pawn-black',anchor=(0,0), pos=(500,100)),
  11223. Actor('chess/pawn-black',anchor=(0,0), pos=(600,100)),
  11224. Actor('chess/pawn-black',anchor=(0,0), pos=(700,100)),
  11225. ]</p>
  11226. <p>white = [
  11227. Actor('chess/pawn-white',anchor=(0,0), pos=(0,600)),
  11228. Actor('chess/pawn-white',anchor=(0,0), pos=(100,600)),
  11229. Actor('chess/pawn-white',anchor=(0,0), pos=(200,600)),
  11230. Actor('chess/pawn-white',anchor=(0,0), pos=(300,600)),
  11231. Actor('chess/pawn-white',anchor=(0,0), pos=(400,600)),
  11232. Actor('chess/pawn-white',anchor=(0,0), pos=(500,600)),
  11233. Actor('chess/pawn-white',anchor=(0,0), pos=(600,600)),
  11234. Actor('chess/pawn-white',anchor=(0,0), pos=(700,600)),
  11235. Actor('chess/rook-white',anchor=(0,0), pos=(0,700)),
  11236. Actor('chess/knight-white',anchor=(0,0), pos=(100,700)),
  11237. Actor('chess/bishop-white',anchor=(0,0), pos=(200,700)),
  11238. Actor('chess/queen-white',anchor=(0,0), pos=(300,700)),
  11239. Actor('chess/king-white',anchor=(0,0), pos=(400,700)),
  11240. Actor('chess/bishop-white',anchor=(0,0), pos=(500,700)),
  11241. Actor('chess/knight-white',anchor=(0,0), pos=(600,700)),
  11242. Actor('chess/rook-white',anchor=(0,0), pos=(700,700)),
  11243. ]</p>
  11244. <p>x = 0
  11245. y = 0</p>
  11246. <p>block = 0
  11247. for i in range(1,65):
  11248. if block % 2 == 0:
  11249. board.append(Actor('chess/white',anchor=(0,0), pos=(x,y)))
  11250. else:
  11251. board.append(Actor('chess/black',anchor=(0,0), pos=(x,y)))</p>
  11252. <pre><code>block += 1
  11253. x += 100
  11254. if i != 0 and i%8 == 0:
  11255. y += 100
  11256. x = 0
  11257. block+=3
  11258. </code></pre>
  11259. <p>pick_white = None
  11260. pick_black = None
  11261. elf = Actor("c1",ancor=(0,0))
  11262. king = Actor("c2")
  11263. x = 0
  11264. y = 0</p>
  11265. <p>def on_key_down(key):
  11266. global pick_white,pick_black,x,y</p>
  11267. <pre><code>if key == keys.SPACE and pick_white == None:
  11268. # pick up the piece below
  11269. for w in white:
  11270. if elf.colliderect(w):
  11271. pick_white = w
  11272. # store the original position
  11273. x = w.x
  11274. y = w.y
  11275. elif key == keys.SPACE and pick_white != None:
  11276. for square in board:
  11277. # shouldnt be able to drop if there is already white piece there
  11278. if elf.colliderect(square):
  11279. for w in white:
  11280. if w != pick_white and square.colliderect(w):
  11281. return
  11282. # pawns cant move backwards
  11283. if pick_white.image == 'chess/pawn-white' and square.y &gt; y:
  11284. return
  11285. # snap the white piece to the board
  11286. pick_white.x = square.x
  11287. pick_white.y = square.y
  11288. # take the black piece if there
  11289. for b in list(black):
  11290. if b.colliderect(pick_white):
  11291. black.remove(b)
  11292. # Queening the Pawn:
  11293. # pick_white.image is chess/pawn-white for the white pawn
  11294. # set the pick_white.image to chess/queen-white if it reaches the black end of the board
  11295. if pick_white.image == 'chess/pawn-white' and pick_white.y == 0:
  11296. pick_white.image = 'chess/queen-white'
  11297. # drop it
  11298. pick_white = None
  11299. break
  11300. if key == keys.P and pick_black == None:
  11301. # pick up the piece below
  11302. for b in black:
  11303. if king.colliderect(b):
  11304. pick_black = b
  11305. # store the original position
  11306. y = b.y
  11307. x = b.x
  11308. elif key == keys.P and pick_black != None:
  11309. for square in board:
  11310. if king.colliderect(square):
  11311. # dont allow a drop if there is already a black piece there
  11312. for b in black:
  11313. if b != pick_black and square.colliderect(b):
  11314. return
  11315. # pawns cant move backwards
  11316. if pick_black.image == 'chess/pawn-black' and square.y &lt; y:
  11317. return
  11318. # snap the black piece to the board
  11319. pick_black.x = square.x
  11320. pick_black.y = square.y
  11321. # take the white piece if there
  11322. for w in list(white):
  11323. if w.colliderect(pick_black):
  11324. white.remove(w)
  11325. # Queen the Pawn
  11326. if pick_black.image == 'chess/pawn-black' and pick_black.y == 700:
  11327. pick_black.image = 'chess/queen-black'
  11328. # drop it
  11329. pick_black = None
  11330. break
  11331. </code></pre>
  11332. <p>def update():
  11333. global pick_white,pick_black</p>
  11334. <pre><code>if keyboard.W:
  11335. elf.y -= 5
  11336. if keyboard.S:
  11337. elf.y += 5
  11338. if keyboard.A:
  11339. elf.x -= 5
  11340. if keyboard.D:
  11341. elf.x += 5
  11342. if keyboard.UP:
  11343. king.y -= 5
  11344. if keyboard.DOWN:
  11345. king.y += 5
  11346. if keyboard.LEFT:
  11347. king.x -= 5
  11348. if keyboard.RIGHT:
  11349. king.x += 5
  11350. # move the white piece with the elf
  11351. if pick_white != None:
  11352. pick_white.x = elf.x - 30
  11353. pick_white.y = elf.y - 30
  11354. # move the black piece with the king
  11355. if pick_black != None:
  11356. pick_black.x = king.x - 30
  11357. pick_black.y = king.y - 30
  11358. </code></pre>
  11359. <p>def draw():
  11360. screen.fill('deepskyblue')</p>
  11361. <pre><code>for square in board:
  11362. square.draw()
  11363. for b in black:
  11364. b.draw()
  11365. for w in white:
  11366. w.draw()
  11367. elf.draw()
  11368. king.draw()
  11369. </code></pre>
  11370. <p>pgzrun.go()</p>
  11371. <p>```</p>
  11372. <h2>[DAY-174] if; list</h2>
  11373. <p>The knight moves in shape L, so we have to make all other moves illegal.</p>
  11374. <p>First draw on a sheet of paper all possible moves, and </p>
  11375. <p><img alt="game-174.png" src="./screenshots/game-174.png" title="game 174 screenshot" /></p>
  11376. <p>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.</p>
  11377. <p>With if conditions, what we do is we set the move as bad (<code>good = False</code>), and then we check if it is actually one of the good moves we do <code>good = True</code>, in the end if its not a good move we return from the <code>on_key_press</code> function and the piece is not dropped on the square.</p>
  11378. <p>```
  11379. elif key == keys.P and pick_black != None:
  11380. for square in board:
  11381. if king.colliderect(square):
  11382. ...</p>
  11383. <pre><code> # knight can only move L shape
  11384. if pick_black.image == 'chess/knight-black':
  11385. good = False
  11386. if square.x == x + 100 and square.y == y - 200:
  11387. good = True
  11388. elif square.x == x + 100 and square.y == y + 200:
  11389. good = True
  11390. elif square.x == x - 200 and square.y == y - 100:
  11391. good = True
  11392. elif square.x == x - 200 and square.y == y + 100:
  11393. good = True
  11394. elif square.x == x - 100 and square.y == y + 200:
  11395. good = True
  11396. elif square.x == x + 200 and square.y == y + 100:
  11397. good = True
  11398. elif square.x == x + 200 and square.y == y - 100:
  11399. good = True
  11400. elif square.x == x - 100 and square.y == y - 200:
  11401. good = True
  11402. elif square.x == x and square.y == y:
  11403. good = True
  11404. if not good:
  11405. return
  11406. </code></pre>
  11407. <p>... <br />
  11408. ```</p>
  11409. <p>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. <code>a = [[1,2],[3,4]]</code> you can just try <code>if [1,2] in a</code>, 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.</p>
  11410. <p>```
  11411. ...
  11412. elif key == keys.SPACE and pick_white != None:
  11413. for square in board:
  11414. # shouldnt be able to drop if there is already white piece there
  11415. if elf.colliderect(square):
  11416. ...</p>
  11417. <pre><code> # knight can only move L shape
  11418. knight_possible = [
  11419. [x,y],
  11420. [x+100,y-200],
  11421. [x+100,y+200],
  11422. [x-200,y-100],
  11423. [x-200,y+100],
  11424. [x-100,y+200],
  11425. [x+200,y+100],
  11426. [x+200,y-100],
  11427. [x-100,y-200]
  11428. ]
  11429. if pick_white.image == 'chess/knight-white' and [square.x,square.y] not in knight_possible:
  11430. return
  11431. </code></pre>
  11432. <p>...
  11433. ```</p>
  11434. <h2>[DAY-175] if</h2>
  11435. <p>The pawn can only move 2 squares from starting position and 1 square otherwise, try to implement this rule by yourself.</p>
  11436. <blockquote>
  11437. <p>this is the code she wrote (including the comment)</p>
  11438. </blockquote>
  11439. <p>```
  11440. ...
  11441. #if pawn.y == 600:
  11442. #pawn can only move 200:
  11443. #else
  11444. #pwan can move only 100
  11445. if pick_white.image == 'chess/pawn-white':
  11446. if y == 600:
  11447. if y - square.y &gt; 200:
  11448. return
  11449. if y != 600:
  11450. if y - square.y &gt;100:
  11451. return</p>
  11452. <p>...</p>
  11453. <pre><code> if pick_black.image == 'chess/pawn-black':
  11454. if y == 100:
  11455. if square.y - y &gt; 200:
  11456. return
  11457. if y != 100:
  11458. if square.y - y &gt;100:
  11459. return
  11460. </code></pre>
  11461. <p>```</p>
  11462. <h2>[DAY-176] if</h2>
  11463. <p>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.</p>
  11464. <blockquote>
  11465. <p>this is the code she wrote</p>
  11466. </blockquote>
  11467. <p><code>...
  11468. if pick_black.image == 'chess/king-black':
  11469. if square.y - pick_y &gt; 100 or square.y - pick_y &lt; -100:
  11470. return
  11471. if square.x - pick_x &gt; 100 or square.x - pick_x &lt; -100:
  11472. return
  11473. ...</code></p>
  11474. <h2>[DAY-177] if</h2>
  11475. <p>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.</p>
  11476. <p>Remember, always try the simple thing first.</p>
  11477. <blockquote>
  11478. <p>this is the code she wrote</p>
  11479. </blockquote>
  11480. <p><code>...
  11481. if pick_black.image == 'chess/rook-black':
  11482. if square.x != pick_x and square.y != pick_y:
  11483. return
  11484. ...</code></p>
  11485. <h2>[DAY-178] if; absolute</h2>
  11486. <p>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). </p>
  11487. <p><img alt="game-178.png" src="./screenshots/game-178.png" title="game 178 screenshot" /></p>
  11488. <p>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.</p>
  11489. <p><code>&lt;--------------------|--------------------&gt;
  11490. -5 -4 -3 -2 -1 0 1 2 3 4 5</code></p>
  11491. <p>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.</p>
  11492. <p><code>def abs(x):
  11493. if x &lt; 0:
  11494. return x * -1
  11495. return x</code></p>
  11496. <p>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.</p>
  11497. <p>```
  11498. ...</p>
  11499. <pre><code> if pick_white.image == 'chess/bishop-white':
  11500. # how much did the y change
  11501. d_y = pick_y - square.y
  11502. # how much did the x change
  11503. d_x = pick_x - square.x
  11504. # if they didnt change the same amount, then its illegal move
  11505. if abs(d_y) != abs(d_x):
  11506. return
  11507. </code></pre>
  11508. <p>...
  11509. ```</p>
  11510. <h2>[DAY-179] if; for</h2>
  11511. <p>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.</p>
  11512. <p>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'.</p>
  11513. <p>```
  11514. if pick_white.image == 'chess/rook-white':
  11515. if square.x != pick_x and square.y != pick_y:
  11516. return
  11517. if pick_white.image == 'chess/bishop-white':
  11518. d_y = pick_y - square.y
  11519. d_x = pick_x - square.x
  11520. if abs(d_y) != abs(d_x):
  11521. return
  11522. if pick_white.image == 'chess/queen-white':
  11523. d_y = pick_y - square.y
  11524. d_x = pick_x - square.x
  11525. if abs(d_y) != abs(d_x) and square.x != pick_x and square.y != pick_y:
  11526. return
  11527. ... </p>
  11528. <p>```</p>
  11529. <p>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 <code>is_on_square</code> function, that takes a position and a list and checks if any of the items of that list is on that position.</p>
  11530. <p>```
  11531. def is_on_square(x, y, pieces):
  11532. for p in pieces:
  11533. if p.x == x and p.y == y:
  11534. return True</p>
  11535. <pre><code>return False
  11536. </code></pre>
  11537. <p>```</p>
  11538. <p>Now that we have the <code>is_on_square</code> function, we can simply check if the <code>y</code> of the square is exactly on top of the original position, and the <code>x</code> 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.</p>
  11539. <p><img alt="game-179.png" src="./screenshots/game-179.png" title="game 179 screenshot" /></p>
  11540. <p>```
  11541. ...
  11542. if pick_white.image == 'chess/pawn-white':
  11543. # 1 or 2 squares
  11544. if pick_y == 600:
  11545. if pick_y - square.y &gt; 200:
  11546. return
  11547. if pick_y != 600:
  11548. if pick_y - square.y &gt; 100:
  11549. return</p>
  11550. <pre><code> # pawn can only go left or right if theres someone
  11551. if pick_x != square.x:
  11552. ok = False
  11553. if pick_y - square.y == 100 and pick_x - square.x == 100 and is_on_square(square.x, square.y, black):
  11554. ok = True
  11555. if pick_y - square.y == 100 and pick_x - square.x == -100 and is_on_square(square.x, square.y, black):
  11556. ok = True
  11557. if not ok:
  11558. return
  11559. </code></pre>
  11560. <p>...
  11561. ```</p>
  11562. <h2>[DAY-180] if</h2>
  11563. <p>There is an important rule in chess, that many people dont know, En Passant (In Passing).</p>
  11564. <p>From Wikipedia (https://en.wikipedia.org/wiki/En_passant):</p>
  11565. <blockquote>
  11566. <p>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.</p>
  11567. <p>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.</p>
  11568. <p>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.</p>
  11569. </blockquote>
  11570. <p><img alt="game-180-a.png" src="./screenshots/game-180-a.png" title="game 180-a screenshot" />
  11571. <img alt="game-180-b.png" src="./screenshots/game-180-b.png" title="game 180-b screenshot" />
  11572. <img alt="game-180-c.png" src="./screenshots/game-180-c.png" title="game 180-b screenshot" /></p>
  11573. <p>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</p>
  11574. <p>the code looks like this:</p>
  11575. <p>```
  11576. enpassant = None</p>
  11577. <p>def on_key_down(key):
  11578. global pick_white, pick_black, pick_x, pick_y, enpassant</p>
  11579. <pre><code>...
  11580. elif key == keys.SPACE and pick_white != None:
  11581. for square in board:
  11582. # shouldnt be able to drop if there is already white piece there
  11583. if elf.colliderect(square):
  11584. ...
  11585. if pick_white.image == 'chess/pawn-white':
  11586. # 1 or 2 squares
  11587. if pick_y == 600:
  11588. if pick_y - square.y == 200:
  11589. enpassant = pick_white
  11590. if pick_y - square.y &gt; 200:
  11591. return
  11592. if pick_y != 600:
  11593. if pick_y - square.y &gt; 100:
  11594. return
  11595. # if y &gt; 200 first move:
  11596. # pawn can only go left or right if theres someone
  11597. if pick_x != square.x:
  11598. ok = False
  11599. if pick_y - square.y == 100 and pick_x - square.x == 100 and is_on_square(square.x, square.y, black):
  11600. ok = True
  11601. if pick_y - square.y == 100 and pick_x - square.x == -100 and is_on_square(square.x, square.y, black):
  11602. ok = True
  11603. if (pick_y - square.y == 100 and pick_x - square.x == 100) or (pick_y - square.y == 100 and pick_x - square.x == -100):
  11604. if enpassant != None and enpassant.image == 'chess/pawn-black':
  11605. if enpassant.x == square.x and enpassant.y == square.y + 100:
  11606. black.remove(enpassant)
  11607. ok = True
  11608. if not ok:
  11609. return
  11610. # pawns cant move backwards
  11611. if square.y &gt; pick_y:
  11612. return
  11613. # Queening the Pawn:
  11614. # pick_white.image is chess/pawn-white for the white pawn
  11615. # set the pick_white.image to chess/queen-white if it reaches the black end of the board
  11616. if square.y == 0:
  11617. pick_white.image = 'chess/queen-white'
  11618. ...
  11619. # snap the white piece to the board
  11620. pick_white.x = square.x
  11621. pick_white.y = square.y
  11622. if enpassant != pick_white:
  11623. enpassant = None
  11624. </code></pre>
  11625. <p>...
  11626. ```</p>
  11627. <p>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:</p>
  11628. <p><code>if (pick_y - square.y == 100 and pick_x - square.x == 100) or (pick_y - square.y == 100 and pick_x - square.x == -100):
  11629. if enpassant != None and enpassant.image == 'chess/pawn-black':
  11630. if enpassant.x == square.x and enpassant.y == square.y + 100:
  11631. black.remove(enpassant)
  11632. ok = True</code></p>
  11633. <p>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.</p>
  11634. <h2>[DAY-181] if</h2>
  11635. <p>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.</p>
  11636. <p>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.</p>
  11637. <p>```
  11638. ...
  11639. back = []</p>
  11640. <p>def on_key_down(key):
  11641. global pick_white, pick_black, pick_x, pick_y, pick_image, enpassant,back</p>
  11642. <pre><code>if key == keys.SPACE and pick_white == None:
  11643. # pick up the piece below
  11644. for w in white:
  11645. if elf.colliderect(w):
  11646. pick_white = w
  11647. # store the original position
  11648. pick_x = w.x
  11649. pick_y = w.y
  11650. pick_image = w.image
  11651. elif key == keys.SPACE and pick_white != None:
  11652. for square in board:
  11653. # shouldnt be able to drop if there is already white piece there
  11654. if elf.colliderect(square):
  11655. # make sure the move is valid
  11656. ...
  11657. back.append(pick_image)
  11658. back.append(pick_y)
  11659. back.append(pick_x)
  11660. back.append(pick_white)
  11661. pick_white.x = square.x
  11662. pick_white.y = square.y
  11663. ...
  11664. if key == keys.B:
  11665. if len(back) != 0:
  11666. actor = back.pop()
  11667. x = back.pop()
  11668. y = back.pop()
  11669. image = back.pop()
  11670. actor.x = x
  11671. actor.y = y
  11672. actor.image = image
  11673. </code></pre>
  11674. <p>... <br />
  11675. ```</p>
  11676. <p>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.</p>
  11677. <p>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.</p>
  11678. <h2>[DAY-182] look back</h2>
  11679. <p>Today we will look back on some of the first programs you wrote.</p>
  11680. <p>Open our old files and read as many of them as you can.</p>
  11681. <h2>[DAY-183] Generalization</h2>
  11682. <p>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.</p>
  11683. <p>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.</p>
  11684. <p>Lets start with an example. You know that <code>1 + 2</code> is the same as <code>2 + 1</code>, or <code>1 + 2 = 2 + 1</code>, same with <code>3 + 5 = 5 + 3</code>, 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 <code>a + b = b + a</code>, meaning that any number <code>a</code> plus any number <code>b</code> is the same as wiriting <code>b+a</code>. It might seem like we did nothing here, just stated the obvious, but I will show you how powerful this generalization is.</p>
  11685. <p>At first we were thinkging of numbers, but with this generalization we can actually use expressions, for example <code>a = ((4838 + 8272) * 3)</code> and <code>b = ((7467 / 2) + 27838)</code> and still <code>a + b = b + a</code>, we can substitute <code>a</code> and <code>b</code>, so <code>((4838 + 8272) * 3) + ((7467 / 2) + 27838) = ((7467 / 2) + 27838) + ((4838 + 8272) * 3)</code>. We have higher level of reason, we are not confined to numbers anymore, but to whole expressions and expressions of expressions.</p>
  11686. <p>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'.</p>
  11687. <p>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.</p>
  11688. <h2>[DAY-184] Generalization</h2>
  11689. <blockquote>
  11690. <p>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.</p>
  11691. </blockquote>
  11692. <h2>[DAY-185] Generalization</h2>
  11693. <p>Today we will build three different versions of snakes and ladders to illustrate different approaches.</p>
  11694. <p>We will use super small Snakes and Ladders game with the following rules:</p>
  11695. <ul>
  11696. <li>there are 9 squares, from 0 to 8</li>
  11697. <li>0 -&gt; 0</li>
  11698. <li>1 -&gt; 2</li>
  11699. <li>2 -&gt; 2</li>
  11700. <li>3 -&gt; 3</li>
  11701. <li>4 -&gt; 2</li>
  11702. <li>5 -&gt; 7</li>
  11703. <li>6 -&gt; 0</li>
  11704. <li>7 -&gt; 7</li>
  11705. <li>
  11706. <p>8 -&gt; 8</p>
  11707. </li>
  11708. <li>
  11709. <p>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.</p>
  11710. </li>
  11711. </ul>
  11712. <p>```
  11713. player1 = 0
  11714. while True:
  11715. print("player board position: ", player1)
  11716. dice = int(input("dice roll&gt; "))</p>
  11717. <pre><code>player1 += dice
  11718. if player1 == 1:
  11719. player1 = 3
  11720. elif player1 == 4:
  11721. player1 = 2
  11722. elif player1 == 5:
  11723. player1 = 7
  11724. elif player1 == 6:
  11725. player1 = 0
  11726. </code></pre>
  11727. <p>```</p>
  11728. <ol>
  11729. <li>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.</li>
  11730. </ol>
  11731. <p>```
  11732. board = [
  11733. 0,
  11734. 2, # 1 -&gt; 3
  11735. 0,
  11736. 0,
  11737. -2, # 4 -&gt; 2
  11738. 2, # 5 -&gt; 7
  11739. -6, # 6 -&gt; 0
  11740. 0,
  11741. 0
  11742. ]</p>
  11743. <p>player1 = 8
  11744. while True:
  11745. print("player board index: ", player1)
  11746. dice = int(input("dice roll&gt; "))
  11747. player1 += dice</p>
  11748. <pre><code>if player1 &gt;= len(board) - 1:
  11749. print("finished")
  11750. break
  11751. snake_or_ladder = board[player1]
  11752. player1 += snake_or_ladder
  11753. </code></pre>
  11754. <p>```</p>
  11755. <p>The whole game is actually encoded in those two lines:</p>
  11756. <p><code>snake_or_ladder = board[player1]
  11757. player1 += snake_or_ladder</code></p>
  11758. <p>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 <code>render</code> function and be done. This is actually not possible in the first version with the if conditions unless we almost duplicate the whole program.</p>
  11759. <ol>
  11760. <li>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.</li>
  11761. </ol>
  11762. <p>```
  11763. class Board:
  11764. def <strong>init</strong>(self):
  11765. self.player = 0
  11766. self.squares = [
  11767. 0,
  11768. 2, # 1 -&gt; 3
  11769. 0,
  11770. 0,
  11771. -2, # 4 -&gt; 2
  11772. 2, # 5 -&gt; 7
  11773. -6, # 6 -&gt; 0
  11774. 0,
  11775. 0
  11776. ]</p>
  11777. <pre><code>def move(self, dice):
  11778. position = self.player + dice
  11779. if position &gt;= len(self.squares) - 1:
  11780. return True
  11781. self.player += self.squares[position]
  11782. return False
  11783. </code></pre>
  11784. <h6></h6>
  11785. <p>b = Board()
  11786. while True:
  11787. print("player board position: ", b.player)
  11788. roll = int(input("dice roll&gt; "))
  11789. if b.move(roll):
  11790. print('finished')
  11791. break
  11792. ```</p>
  11793. <h2>[DAY-186] If</h2>
  11794. <p>Make snakes and ladders on your own with pygame zero.</p>
  11795. <p><img alt="game-186-b.png" src="./screenshots/game-186-b.png" title="game 186-b screenshot" /></p>
  11796. <blockquote>
  11797. <p>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.</p>
  11798. </blockquote>
  11799. <p>```
  11800. import pgzrun
  11801. import random</p>
  11802. <p>HEIGHT = 500
  11803. WIDTH = 500</p>
  11804. <p>elf = Actor("c1")
  11805. elf.x = -25
  11806. elf.y = 475
  11807. game_over = False
  11808. board = Actor("snake-500")
  11809. def on_key_down(key):
  11810. if key == keys.SPACE:
  11811. elf.x += random.choice([50,100,150,200,250,300])
  11812. if elf.x &gt; 475 and elf.y == 25:
  11813. elf.x = 25
  11814. elf.y = 25
  11815. if elf.x &gt; 475:
  11816. elf.x -= 500
  11817. elf.y -= 50
  11818. if elf.y == 375 and elf.x == 225:
  11819. elf.y = 475
  11820. elf.x = 225
  11821. if elf.y == 25 and elf.x == 25:
  11822. elf.y = 175
  11823. if elf.y == 475 and elf.x == 125:
  11824. elf.y = 225
  11825. elf.x = 25
  11826. if elf.y == 325 and elf.x == 175:
  11827. elf.y = 475
  11828. elf.x = 25
  11829. if elf.y == 475 and elf.x == 275:
  11830. elf.y = 375
  11831. elf.x = 325
  11832. if elf.y == 175 and elf.x == 125:
  11833. elf.y = 25
  11834. elf.x = 225
  11835. if elf.y == 75 and elf.x == 325:
  11836. elf.y = 225
  11837. elf.x = 325
  11838. if elf.y == 25 and elf.x == 425:
  11839. elf.y = 175
  11840. elf.x = 425
  11841. if elf.y == 475 and elf.x == 425:
  11842. elf.y = 175
  11843. elf.x = 425</p>
  11844. <p>def update():
  11845. global game_over
  11846. speed = 10</p>
  11847. <pre><code>if keyboard.UP:
  11848. elf.y -= speed
  11849. if keyboard.DOWN:
  11850. elf.y += speed
  11851. if keyboard.LEFT:
  11852. elf.x -= speed
  11853. if keyboard.RIGHT:
  11854. elf.x += speed
  11855. if elf.x == 475 and elf.y == 25:
  11856. game_over = True
  11857. </code></pre>
  11858. <p>def draw():
  11859. board.draw()
  11860. elf.draw()
  11861. if game_over == True:
  11862. screen.draw.text('YOU WIN CONGRATULATION',(100,100),color = (0,0,0))
  11863. pgzrun.go()
  11864. ```</p>
  11865. <blockquote>
  11866. <p>she also made a grid to compute the positions of each square</p>
  11867. </blockquote>
  11868. <p><img alt="game-186-a.png" src="./screenshots/game-186-a.png" title="game 186-a screenshot" /></p>
  11869. <h2>[DAY-187] If; While; Functions</h2>
  11870. <p>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</p>
  11871. <h2>[DAY-188] OOP</h2>
  11872. <p>Watch https://www.youtube.com/watch?v=JeznW_7DlB0 (Python Object Oriented Programming (OOP) - For Beginners
  11873. from Tech With Tim)</p>
  11874. <h2>[DAY-189] Keyword Arguments; String Methods</h2>
  11875. <p>Today you have to watch three videos:</p>
  11876. <ul>
  11877. <li>Python keyword arguments 🔑 by Bro Code - https://www.youtube.com/watch?v=Tu0lFBXQgPw</li>
  11878. <li>Python string methods by Bro Code - https://www.youtube.com/watch?v=crw3rVFNwIM</li>
  11879. <li>Python Object Oriented Programming (OOP) - For Beginners from Tech With Tim - https://www.youtube.com/watch?v=JeznW_7DlB0 (watch it again)</li>
  11880. </ul>
  11881. <h2>[DAY-190] While</h2>
  11882. <p>Make a web whatsapp bot that sends the same message in an infinite loop</p>
  11883. <ul>
  11884. <li>click on the chrome tab with whatsapp</li>
  11885. <li>click on the search box</li>
  11886. <li>searche for contact name (dad)</li>
  11887. <li>clicks on the top result</li>
  11888. <li>click on the message input field</li>
  11889. <li>type 'hello world'</li>
  11890. <li>click the send button</li>
  11891. </ul>
  11892. <p>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.</p>
  11893. <p>This is a snippet with examples taken from pyautogui's page:</p>
  11894. <p>```</p>
  11895. <blockquote>
  11896. <blockquote>
  11897. <blockquote>
  11898. <p>import pyautogui</p>
  11899. <p>screenWidth, screenHeight = pyautogui.size() # Get the size of the primary monitor.
  11900. screenWidth, screenHeight
  11901. (2560, 1440)</p>
  11902. <p>currentMouseX, currentMouseY = pyautogui.position() # Get the XY position of the mouse.
  11903. currentMouseX, currentMouseY
  11904. (1314, 345)</p>
  11905. <p>pyautogui.moveTo(100, 150) # Move the mouse to XY coordinates.</p>
  11906. <p>pyautogui.click() # Click the mouse.
  11907. pyautogui.click(100, 200) # Move the mouse to XY coordinates and click it.
  11908. pyautogui.click('button.png') # Find where button.png appears on the screen and click it.</p>
  11909. <p>pyautogui.move(400, 0) # Move the mouse 400 pixels to the right of its current position.
  11910. pyautogui.doubleClick() # Double click the mouse.
  11911. pyautogui.moveTo(500, 500, duration=2, tween=pyautogui.easeInOutQuad) # Use tweening/easing function to move mouse over 2 seconds.</p>
  11912. <p>pyautogui.write('Hello world!', interval=0.25) # type with quarter-second pause in between each key
  11913. pyautogui.press('esc') # Press the Esc key. All key names are in pyautogui.KEY_NAMES</p>
  11914. <p>with pyautogui.hold('shift'): # Press the Shift key down and hold it.
  11915. pyautogui.press(['left', 'left', 'left', 'left']) # Press the left arrow key 4 times.</p>
  11916. <h1>Shift key is released automatically.</h1>
  11917. <p>pyautogui.hotkey('ctrl', 'c') # Press the Ctrl-C hotkey combination.</p>
  11918. <p>pyautogui.alert('This is the message to display.') # Make an alert box appear and pause the program until OK is clicked.
  11919. ```</p>
  11920. </blockquote>
  11921. </blockquote>
  11922. <p>use <code>pyautogui.position()</code> to find the accurate positions for your screen.
  11923. <code>import pyautogui
  11924. import time
  11925. while True:
  11926. pyautogui.click(305,10)
  11927. pyautogui.click(117,252)
  11928. pyautogui.write('dad', interval=0.25)
  11929. pyautogui.click(185, 395)
  11930. pyautogui.write('hello world!', interval=0.20)
  11931. pyautogui.click(935, 1132)
  11932. time.sleep(1)</code></p>
  11933. </blockquote>
  11934. <p>Have some fun with it pranking your parents :) <em>but not too much</em>.</p>
  11935. <h2>[DAY-191] While</h2>
  11936. <p>Make another whatsapp bot, but this time send a very very long message.</p>
  11937. <p>```
  11938. import pyautogui
  11939. import time
  11940. import random
  11941. while True:
  11942. pyautogui.click(305,10)
  11943. pyautogui.click(117,252)
  11944. pyautogui.write('dad', interval=0.25)
  11945. time.sleep(1)
  11946. pyautogui.click(185, 395)
  11947. time.sleep(1)</p>
  11948. <pre><code>for i in range(3000):
  11949. s = 'yo' * random.randint(1, 4)
  11950. pyautogui.write(s + ' ')
  11951. time.sleep(5)
  11952. pyautogui.click(935, 1132)
  11953. </code></pre>
  11954. <p>```</p>
  11955. <p>this will send the message:</p>
  11956. <p>"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"</p>
  11957. </article>
  11958. <hr>
  11959. <footer>
  11960. <p>
  11961. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  11962. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  11963. </svg> Accueil</a> •
  11964. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  11965. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  11966. </svg> Suivre</a> •
  11967. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  11968. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  11969. </svg> Pro</a> •
  11970. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  11971. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  11972. </svg> Email</a> •
  11973. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  11974. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  11975. </svg> Légal</abbr>
  11976. </p>
  11977. <template id="theme-selector">
  11978. <form>
  11979. <fieldset>
  11980. <legend><svg class="icon icon-brightness-contrast">
  11981. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  11982. </svg> Thème</legend>
  11983. <label>
  11984. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  11985. </label>
  11986. <label>
  11987. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  11988. </label>
  11989. <label>
  11990. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  11991. </label>
  11992. </fieldset>
  11993. </form>
  11994. </template>
  11995. </footer>
  11996. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  11997. <script>
  11998. function loadThemeForm(templateName) {
  11999. const themeSelectorTemplate = document.querySelector(templateName)
  12000. const form = themeSelectorTemplate.content.firstElementChild
  12001. themeSelectorTemplate.replaceWith(form)
  12002. form.addEventListener('change', (e) => {
  12003. const chosenColorScheme = e.target.value
  12004. localStorage.setItem('theme', chosenColorScheme)
  12005. toggleTheme(chosenColorScheme)
  12006. })
  12007. const selectedTheme = localStorage.getItem('theme')
  12008. if (selectedTheme && selectedTheme !== 'undefined') {
  12009. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  12010. }
  12011. }
  12012. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  12013. window.addEventListener('load', () => {
  12014. let hasDarkRules = false
  12015. for (const styleSheet of Array.from(document.styleSheets)) {
  12016. let mediaRules = []
  12017. for (const cssRule of styleSheet.cssRules) {
  12018. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  12019. continue
  12020. }
  12021. // WARNING: Safari does not have/supports `conditionText`.
  12022. if (cssRule.conditionText) {
  12023. if (cssRule.conditionText !== prefersColorSchemeDark) {
  12024. continue
  12025. }
  12026. } else {
  12027. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  12028. continue
  12029. }
  12030. }
  12031. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  12032. }
  12033. // WARNING: do not try to insert a Rule to a styleSheet you are
  12034. // currently iterating on, otherwise the browser will be stuck
  12035. // in a infinite loop…
  12036. for (const mediaRule of mediaRules) {
  12037. styleSheet.insertRule(mediaRule.cssText)
  12038. hasDarkRules = true
  12039. }
  12040. }
  12041. if (hasDarkRules) {
  12042. loadThemeForm('#theme-selector')
  12043. }
  12044. })
  12045. </script>
  12046. </body>
  12047. </html>