Sei sulla pagina 1di 193

Laboratoriodi Informatica

MatematicaeGeometriacon Python OpenOffice.org Pygraph


DanieleZambelli2007 (v=0.5.01)

TitoloOriginale: LaboratoriodiInformatica,matematicaegeometriaconPython,Openoffice.org,Pygraph Versione:0.5rc1 1aEdizione:2007 copyleftbyZambelliDaniele

Quest'operarilasciatasottoladisciplinadellaseguentelicenza: CreativeCommonsPublicLicence AttribuzioneNoncommercialeCondividiallostessomodo2.5Generico

Tuseilibero diriprodurre,distribuire,comunicarealpubblico,esporreinpubblico,rappresentare,eseguiree recitarequest'opera dimodificarequest'opera Alleseguenticondizioni: Attribuzione.Deviattribuirelapaternitdell'operaneimodiindicatidall'autoreodachitihadato l'operainlicenzaeinmodotaledanonsuggerirecheessiavallinoteoilmodoincuituusil'opera. Noncommerciale.Nonpuoiusarequest'operaperfinicommerciali. Condividiallostessomodo.Sealteriotrasformiquest'opera,oselausipercrearneun'altra,puoi distribuirel'operarisultantesoloconunalicenzaidenticaoequivalenteaquesta.

Ognivoltacheusiodistribuisciquest'opera,devifarlosecondoiterminidiquestalicenza,cheva comunicataconchiarezza. Inognicaso,puoiconcordarecoltitolaredeidirittiutilizzidiquest'operanonconsentitidaquestali cenza. Questalicenzalasciaimpregiudicatiidirittimorali.

Leutilizzazioniconsentitedallaleggesuldirittod'autoreeglialtridirittinonsonoinalcunmodolimi tatidaquantosopra. Questounriassuntoinlinguaggioaccessibileatuttidelcodicelegale,versioneintegrale,chesipulegge renellapaginaweb: http://creativecommons.org/licenses/byncsa/2.5/it/legalcode Ogniesemplaredellapresenteopera(informatocartaceoodigitale)privodiquestapaginadaritenersi contraffatto.

Indicegenerale
0.Introduzione 0.1.Scopodiquestomanuale 0.2.Installazione 0.3.TrovaredocumentazionesuPython: 0.4.Feedback 1.IntroduzioneallinguaggioPython 1.1.Iprimicomandi 1.2.Pythoncomecalcolatore 1.3.Dati:nomieoggetti 1.4.Convertire,formattare 1.5.Ripetereistruzioni 1.6.Ilprimoprogramma 1.7.Organizzazione 1.8.Parametri 1.9.Nuoveoperazioni 1.10.Operarescelte 1.11.Sequenzeecicli 1.12.Listeetuple 1.13.Ilciclowhile 1.14.Funzioniricorsive 1.15.Fileditesto 1.16.Dizionari 1.17.Laprogrammazioneorientataaglioggetti 2.Numeri 2.1.Operazioni 2.2.Arraydiinteri 2.3.Criterididivisibilit 2.4.Divisibilit 2.5.Numeriprimi 2.6.Inumeridell'orologio 2.7.Scomposizioneinfattoriprimi 3.Geometriainterattiva 3.1.Elementifondamentali 3.2.Circonferenzeeintersezioni 3.3.Lacongruenza 3.4.Triangoloequilateroeprocedure 3.5.Poligoniregolariefunzioni 3.6.Unalibreriadifunzioni
i

1 1 2 3 3 5 7 10 13 17 20 23 26 29 32 35 39 42 45 49 52 55 58 61 63 69 77 87 94 101 107 117 119 122 125 128 131 134

4.Geometriaanalitica 4.1.Punti,segmenti,poligoni 4.2.Trasformazioni 4.3.Rette,parabole,cubiche... 4.4.RetteedestensionedellaclassePlot 5.Geometriadellatartaruga 5.1.Avanti,indietro,destra,sinistra 5.2.Camminidell'ubriacoetartarugaacolori 5.3.Poligoni 5.4.Quadratini,quadratoni...quadrati! 5.5.Poligoniditutteleformeedimensioni 5.6.Unorribileragno 6.Fogliodicalcolo 6.1.Celle,colonne,righe...ilfogliodicalcolo 6.2.Formatieordinamenti 6.3.Copiareinmodointelligente 6.4.Diagrammi 7.Indiceanalitico

139 141 144 147 150 155 157 160 163 166 169 172 175 177 180 183 186 189

ii

Introduzione

0. Introduzione
0.1. Scopodiquestomanuale
Chesensohainsegnareunlinguaggiodiprogrammazionenellascuola?Noncertoquellodipre pararefuturiinformatici,datoche: manmanochelatecnologiamaturarichiedesempremenotecnicietecnicisemprepispe cializzati; moltodifficilepensarediformare,conannidianticipo,tecnicicompetentiperunatecno logiaancoracosinevoluzione. L'introduzionediogninuovostrumentotecnicotecnologicomodificailmododiaffrontarei problemidiunasocietemodificaancheiproblemichelasocietritieneimportanterisolvere. Unostrumentocospotenteemultiformecomel'elaboratoreelettronicohaperunforteimpat tonellaculturaepuessereunfortestimoloperesplorareecapireilmondochecicirconda. Quil'informatica,nontantol'usodelcomputer,vistacomeunostrumentoriccodistimoliper esplorare,imparare,crescere.Gi,l'informatica...macos'l'informatica? L'informaticalascienzachestudiacomerisolvereproblemiusandoillinguaggio(Lucio Varagnoloanni'80). Illinguaggioilpipotente(l'unico?)strumentodiconoscenzaumano.Ilinguaggidiprogram mazione,sonolinguaggiformali,certononparagonabili,inespressivit,conillinguaggionatu rale.Affrontareproblemi,riprodurreedescriveresituazioni,confrontarel'effettodidiversede finizionioalgoritmiusandounlinguaggiodiprogrammazione,pucomunqueessereunpoten testimoloadunapiprofondaepersonaleconoscenza. Illinguaggiodiprogrammazionepudunqueavereunsensonellascuola:noncomefinedel l'insegnamento,macomemezzoperapprendere.Illinguaggiodevequindirisultarepitraspa rentepossibile:nondevetediareeconfondere,conunasintassicomplicata,devepossedere dellestrutturedialtolivelloinmododapermetterediaffrontareproblemisignificativimolto presto,deveavereunrigorosoimpiantologicoinmododarisultareformativo. Questecaratteristichelehotrovatein Python cheancheunlinguaggiomultipiattaforma (funzionasottoWindows,Mac,Linuxemoltialtrisistemioperativi),haunagrandequantitdi libreriechelorendonoadattoarisolvereproblemiinambitimoltodiversi,haunanotevoledo cumentazione,inpartetradottaancheinitalianodavolontari. InoltrePythonfapartedellagrandefamigliadisoftwarelibero,cio: 0. puessereusatosenzarestrizioni, 1. puesserestudiatoeadattatoalleproprieesigenze, 2. puesserecopiatoliberamenteedistribuito, 3. puesseremodificato,madeverestarelibero.

Introduzione

Scopodiquestomanuale

Insomma,attualmente,Pythonunottimocandidatocomelinguaggiodiprogrammazioneper lascuolasecondaria.

0.2. Installazione
Perinstallareunqualunquesoftwarebisognaessereunpo'praticidicomputer.Convieneeven tualmentefarsiaiutare.L'autorenonpuessereritenutoresponsabiledellaperditadiinforma zioniconseguentiaderroridiinstallazione. 1. InstallarePython 1. Pythonunsoftwareliberoeddistribuitosottounalicenzacompatibileconlalicenza GPLquindipossibileusarlo,copiarloedistribuirlosenzarestrizioni. 2. GNU/Linux:ilprogrammadeveessereinstallatodall'amministratoredelsistema,luisa comefare.SesiutilizzaunadistribuzionelacosapisemplicecaricarePythonalmo mentodell'installazionedelsistema.OcomunqueinstallarloapartiredaiCDodaidepo siti della distribuzione stessa. Noi utilizzeremo per gli esempi l'ambiente di sviluppo IDLE (nonl'unicasceltapossibile).Inmoltedistribuzioni GNU/Linux IDLE un pacchettoseparatodaPython,selovogliamousaredobbiamoinstallarlo. 3. Windows:scaricarelaversionepiaggiornatadiPythondawww. python quindi .org doppioclicsulpacchettodainstallare. 2. Installarepygraph 1. Copiareilfilepygraph_x.xx(nelmondorealealpostodixcisarannodeinumeri cheindicanolaversione)all'internodiunapropriacartella(ilfilepuessereprelevatoda Internetdallapagina:https://www.verona.linux.it/index.php?title=Download) 2. Scompattareilfilepygraph_x.xxall'internodiunadirectorydilavoro. 3. Ladirectorypygraphcontieneletredirectoryseguenti: doc,ladocumentazionevaria examples,esempid'uso pygraph,lelibreriedelprogetto: pycart.py unpianocartesiano pyturtle.py lagraficadellatartaruga pyplot.py graficodifunzioninelpiano,cartesianeepolari pyig geometriainterattiva 4. Spostareledirectorydoceexamplesinunapropriacartellafacilmenteraggiungibile (adesempio:.../mieidocumenti/python/pygraph) 5. Spostare la directory pygraph e il file pigraph.pth all'interno di: .../pythonx.x/site-packages/(osservazioni:1:perfarequestoinLinuxbisognaavere i privilegi di amministratore; 2: a seconda della versione di Python installata, pythonx.xpotrebbeesserepython2.4,python2.5opython3.0...)

Laboratoriodiinformatica

TrovaredocumentazionesuPython:

0.3. TrovaredocumentazionesuPython:
1. Documentazioneininglese:www. python .org 2. Documentazioneinitaliano:www. python .it 3. Un'ottimaintroduzioneall'informaticausandoquestolinguaggiodiprogrammazioneil testo:Howtothinklikeacomputerscientist:learningwithPythondiDowney,Allen tradottomagnificamenteinitaliano(sitrovasuInternetpartendodailinkprecedenti).

0.4. Feedback
Sperochequalcunotroviinteressantequestolavoroelousiperimparareoperinsegnarel'infor maticaelageometriaconPython.Utilizzandolo,senz'altroverrannoallalucemoltierrori,di fettiocarenzesianelsoftwaresianelladocumentazione;chiedoachitroverqualchemotivodi interesseinquestolavorodiinviarmi: 0. 1. 2. 3. Commenti, Critiche, Suggerimenti, ...emagarianchealtrimaterialidilavoroperaccrescereladocumentazione

Ringraziofind'orachiunqueperdadeltempoaleggerequestotesto,loutilizzinell'insegnamen toosiprendalabrigadimandarmiqualcheriscontro. DanieleZambelliemail:daniele.zambelli@inwind.it

Introduzione

Feedback

Laboratoriodiinformatica

IntroduzioneallinguaggioPython

1. IntroduzioneallinguaggioPython
Inquestasezionesonopresentativariargomentirelativiallinguaggiodiprogrammazione,sono glistrumenticheillinguaggiometteadisposizionedelprogrammatore.Perogniargomento vengonodatesuccinteinformazioni,vieneindicatalasintassidellenuoveistruzioni,vengono propostidegliesempiedegliesercizi. Nonmisonopostol'obiettivoditrattareinmodocompletoivaristrumentimessiadisposizione daPython,mascriveresolodeicennichenepermettanol'uso.Suognunodiessisipossono trovareinformazionipicompleteneivaritesti(anchetradottiinitaliano)presentinelsitoita lianodiPython:www.python.it.

IntroduzioneallinguaggioPython

IntroduzioneallinguaggioPython

Laboratoriodiinformatica

Iprimicomandi

1.1. Iprimicomandi
Cos'unlinguaggiodiprogrammazione, laprimaistruzione, comescrivereedeseguireunsempliceprogramma.
L'informaticalascienzacheusaillinguaggioperrisolvereiproblemi.L'uomotrovalasolu zionedelproblema,poicomunicaallamacchinaqualipassideveeseguirepertrovareilrisulta todesiderato.Lamacchinaesegueicomandiricevuti.

Si pone problemi Cerca soluzioni L'umano La macchina Comunica comandi Esegue comandi

Percomunicareallamacchinausiamoundispositivochelatastiera.Suquestapossiamoscri vereicomandichevogliamolamacchinaesegua.Adesempio: "preparami un paninazzo con la soppressa!" No,questocomandononverreseguitodallamacchina.Possiamochiederledieseguiresolo azionipercuistatarealizzataenonsolo,dobbiamochiederedieseguirequelleazioniusando unlinguaggiocheleipossacomprendere. Purtroppoillinguaggiochefafunzionareicomputerpiuttostooscuro: 1000110101000110 0011111010101110 1100010101101111 ... edettolinguaggiomacchina. Dopoqualcheannodiprogrammazioneconparolefattedizerieuni,gliinformaticihannoin ventatodeiprogrammicapaciditradurreicomandiscrittiinunlinguaggiocomprensibiledagli umani,nellinguaggiomacchinacomprensibiledaglielaboratorielettronici. Pythonuninterpretedilinguaggiochetraducecomandichepossiamocapirenoi,incoman dichelamacchinacapisceedesegue. Ovviamentenonpossiamodaredeicomandicomecipareepiace,dobbiamoseguireleregole
IntroduzioneallinguaggioPython 7

Iprimicomandi

diunlinguaggio,obbedireadunaprecisagrammaticaedusaresololeparolechePythoncapi sce. ComeprimocomandodiciamoaPythondiscriverequalcosasulloschermo:ilcomandoper direquestostampaforseperchunavoltaicomputernonavevanoloschermo,masolouna tastieraeunastampante.Ilcomandopervascrittoininglese(chissperchPythonnonco noscel'italiano?) print Manonbastadirestampa,bisognaanchedirechecosadeveesseremostrato,ilprimocoman docheproducequalcosadisignificativodunque: print "Ciao gente!" printun'istruzionediPythonelapartedicomandocompresotralevirgoletteunastrin gadicaratteri. MacomefacciamoadireaPythondileggereedeseguirequestocomando?Chihaimplemen tatoillinguaggiohaancherealizzatoemessoadisposizioneunambienteperlosviluppodei programmi:IDLE. IDLE,cheunprogrammascrittoinPython,permettediscriverecomandieosservareimme diatamenteilloroeffetto,unostrumentomoltocomodo.Scoviamodoveilprogrammadiin stallazionehamessoIDLEedeseguiamolo(perWindowsStartProgrammiPython2.4IDLE, perLinux,senonsitrovanelmenudelleapplicazioni,sipuscrivereidleoppureidlepython2.5inunafinestraditerminale). Unavoltaavviatol'ambientedisviluppo,Sottoadalcunimessaggicheriportanolaversionedi PythoninusoediIDLEstesso,appaionotresimboliimaggioreeilcursorelampeggiantesu bitodopo: >>> Ilsignificatodiquestisimboli:sonopronto,cosavuoicheesegua?. Bene,quipossiamodareilnostrocomando: >>> print "Ciao gente!" Possoanchefarstamparepistringheconunostessocomando: >>> print "Ciao", "gente!" Inquestocasolestringhedevonoessereseparatedavirgole.Pythoninserisceautomaticamen teunospaziotraunastringael'altra.Possoancheinserirenellastringadeicaratterispeciali: >>> print "Ciao\n\n\n\tgente!"

Laboratoriodiinformatica

Iprimicomandi

Ilsignificatodellasequenza\n:quivaacapo...scoprituqualilsignificatodi\t. Riassumendo Unlinguaggiodiprogrammazioneunalinguaartificialechepuesseretradottadalcalco latoreelettronicoinunasequenzadicomandieseguibili. Ilprogrammazioneunasequenzadiistruzioni,ades.:print <stringa>. <stringa> unasequenzadicaratteriracchiusatraapicisingoliodoppiades. Ciao gente\n . Lasequenzadicaratteri \n nonvienestampatamaindicaall'interpretechedeveandarea capo(new line). Lasequenzadicaratteri\tsignifica... Provatu 1. Scrivicomandichestampinodiversefrasi. 2. Scriviuncomandochestampidiversefrasiunasottol'altra,ades.: Nelmezzodelcammindinostravita miritrovaiperunaselvaoscura cheladirittaviaerasmarrita. (DanteAlighieri) 3. Descrivicosasuccedeseinuncomandoprintaggiungounavirgoladopol'ultima stringa.

IntroduzioneallinguaggioPython

Pythoncomecalcolatore

1.2. Pythoncomecalcolatore
ComefarfarecalcoliaPython.
Bene,abbiamoimparatoafarscriverequalcosaa Python,malafaccendaunpo'stupida datochesiamonoiadireesattamentecosacidevemostrare.Vediamodichiedergliqualcosadi pi...Cosac'dimegliodichiedereauncalcolatoresenondifarcalcoli?Mettiamoloalla prova.Possiamoscrivereistruzioniperstampareilrisultatodelleoperazioniaritmetiche: >>> print 5+9 14 Alcuneosservazioni: 1. L'espressione5+9puanchecontenerespazi:5+9evienecomunqueinterpretata edeseguitacorrettamente. 2. All'internodiIDLEsipotrebbeancheomettereilcomandoprint,l'ambienteIDLEag giungeautomaticamenteun'istruzioneperlavisualizzazionedelrisultatodiun'espres sione: >>> 5+9 14 mapreferibileevitarecomandiimpliciti:Nonbastachetucalcoli5+9,devianche stampareilrisultato!. 3. Nota:l'ambienteIDLE(macosavuoldireidleininglese?)permettediriprendereemo dificareun'istruzioneprecedentesenzariscriverla,bastaportareilcursoresull'espres sione,premere <Invio> e IDLE celaricopiasuunanuovariga,prontaperessere modificataerieseguita. Provatu 1. Scriviespressioniconpioperazioni. 2. Scriviespressioniconparentesi. 3. ControllachePythonfacciaicalcoligiusti! Sehaifattodiverseproveecontrollatoconattenzionetisaraiaccortoche: 1. Pythoncommettedeglierrori, 2. Pythonsaeseguirepocheoperazioni. Ilprimoproblemasorgequandotentiamodieseguireunadivisione:

10

Laboratoriodiinformatica

Pythoncomecalcolatore

>>> print 33/7 4 Dovrebbealmenoavvisarcichec'unrestoomegliodarciilrisultatoconunpo'didecimali. Macomepossibilecheunlinguaggiodiprogrammazioneseriofacciaquestierrori?Ipro grammatorichehannoprogettatoPythonhannopensatocheilrisultatodiunadivisionetrain teridebbaessereunnumerointero(lafaccendadovrebbecambiarenelleprossimeversionidel linguaggio).Sevogliamovedereidecimalidelrisultato,almenounodeglioperandideveessere unnumeroconlavirgola(lavirgolaneilinguaggidiprogrammazioneilpunto!): >>> print 33./7 4.71428571429 QuindiPythontrattainmododiverso33da33.:ilprimounoggettoint(intero),il secondounoggettofloat(invirgolamobile).importante,quandosiaffrontaunproble ma,prestarebenattenzionesepossiamotrattarlousandonumeriinterioinvirgolamobileper evitareerroridifficilidascovare. Poichdallaversione3Pythoncambierilcomportamentoeilrisultatodiunadivisionesar sempreunnumeroinvirgolamobile,possiamoanticiparequestocomportamentoimportandola divisionedalmodulo__future__ >>> from __future__ import division >>> print 33/7 4.71428571429 Secondoproblema.Setentiamodieseguireunaradicequadrata(sqrtininglese),Pythonciri spondeconunmessaggiodierrore: >>> sqrt(16) Traceback (most recent call last): File "<pyshell#0>", line 1, in -toplevelsqrt(16) NameError: name 'sqrt' is not defined l'ultima riga quella che ci interessa in questo momento: Python non conosce la parola sqrt,nonsafareleradiciquadrate.Neilinguaggimoderni,latendenzaquelladiavereun nucleodilinguaggiopiuttostoristretto,ampliatopoidalibrerie.Pythonpossiedeunagrande quantitdilibrerie,unadiquestemathchecontieneleoperazioniefunzionimatematiche. Perpoterusarelefunzionipresentiinunalibreriadobbiamocaricarlaepoichiamarelafunzio nedesiderataspecificandoilnomedellalibreriaincuisitrova: >>> import math >>> print math.sqrt(16) 4.0
IntroduzioneallinguaggioPython 11

Pythoncomecalcolatore

Nota:ilrisultatodellafunzionemath.sqrt()unnumerofloat. Per avere informazioni sulle funzioni contenute in una libreria possiamo usare il comando help: >>> help("math") Riassumendo PossiamousarePythoncomeunacalcolatrice.Facendoglicalcolareilrisultatodiespres sionicomplessequantovogliamo. LalibreriamathpermettediestenderelefunzionalitmatematichediPythonperusarlala sideveprimacaricareconilcomandoimport. Lafunzionehelp()pudarciinteressantiinformazionisuunoggettoPython. SipufarriscrivereaIDLEun'espressione,modificarlaerieseguirla. Provatu 1. Scegliun'espressionedallibrodimatematicaefallacalcolareaPython. 2. Spiegacomedevonoessereleparentesinelleespressionimatematiche. 3. Scrivil'espressionechecalcolal'ipotenusadiuntriangolorettangoloconicatetilun ghi3e4. 4. Modifical'espressioneprecedenteinmodochecalcolileipotenuseditriangolirettan goliconcatetilunghi:643e786,32332e57543,775472e547545. 5. Scrivileespressionichecalcolanoilperimetroel'areadeiquadrilatericheconosci. 6. Scrivileespressionichecalcolanoilperimetroel'areadeltriangoloequilatero.

12

Laboratoriodiinformatica

Dati:nomieoggetti

1.3. Dati:nomieoggetti
Comememorizzaredeidatierichiamarliquandoserve.
Abbiamovistoilmododifareseguiredelleistruzionialcalcolatore,maciservirebbebena pocosenonpotessimoancheinseriredeidatineinostriprogrammi.InPythonidatisonode glioggettichel'interpretememorizzadaqualcheparteesipremuradicancellare,perliberare memoria,quandononservonopi.Alcunidiquestioggettisonoimmutabili,ilnumero5sar sempre5,nonpudiventare7.Altrisonomutabili:lalistachecontieneilnumero5pudiven tareunalistachecontieneilnumero7.Inunprogramma,noipossiamofareriferimentoaquesti oggettiusandodeinomidettiidentificatori.Ilmeccanismochepermettedicollegareunnome adunoggettosichiamaassegnazionee,inPythonvieneindicatadalsimbolo:=. >>> data = "13-10-2001" datal'identificatore=l'operatorediassegnazionee13-10-2001 un oggetto stringa. La riga precedente significa: collega alla parola data il valore 13-10-2001

Perl'identificatorecisonoalcunerestrizioni:nonpuiniziareconunacifraenonpucontenere lettereaccentateoalcunialtricaratteri. Osserviamocheilsimbolofattodaduetrattiniorizzontalisovrapposti,hamoltisignificatiche dipendonodalcontesto.Inmatematicapusignificare: uguale, congruente, equivalente,...In certilinguaggidiprogrammazioneindicailpredicatouguale,inPython,comeinmoltialtri linguaggiindical'istruzionediassegnamento.InPythonilpredicatougualevienetradottoda: ==. Cospermemorizzareilnomeecognomediunapersona,lasuaeteilsuoindirizzoposso scrivere: >>> nome = "Mario Rossi" >>> eta = 45 >>> indirizzo = "via Verdi, 4" Pythonsembranonreagireaicomandiprecedenti,ilfattochenonstampimessaggidierrore comunqueconfortante.Pythonhascrittoleduestringheeilnumerointeroinunazonadime moriaehaassociatoaquestioggettitrenomi. Inquestomodoabbiamolegatoallaparola nomelastringaMario Rossi,allaparolaetailnumero45eallaparolaindirizzola stringavia Verdi, 4epossiamousarel'identificatorealpostodell'oggetto:

IntroduzioneallinguaggioPython

13

Dati:nomieoggetti >>> print nome ario Rossi >>> print indirizzo via Verdi, 4 >>> print eta 45

Orasevolessimostampareunaschedainformatoburocratichese,conidatidiMarioRossi, usandounsolocomando,potremmoscrivere: >>> print "Sig.", nome, "\nabitante in", indirizzo, "\ndi anni", eta Sig. Mario Rossi abitante in via Verdi, 4 di anni 45 Sesorgonodeidubbisulsensodituttequellevirgoleesulsignificatodellacoppiadicaratteri \n,convieneriguardarsiilcapitolointitolato:Iprimicomandi Riprendiamoleespressionimatematiche,sevoglioscrivereun'espressioneeilsuorisultato, possodareilcomando: >>> print "2 + 3 =", 2+3 2 + 3 = 5 Masedevocambiareglioperandi,devointervenireinpipuntidell'istruzioneprecedentee questononcarino.Possousareinvecelevariabili: >>> >>> >>> 7 + a=7 b=5 print a, "+", b, "=", a+b 5 = 12

Inquestomodo,cambiandoilvaloredellevariabilipossousaresemprelastessaistruzioneper visualizzareungrannumerodiespressionidiverse. >>> a=73584784689 >>> b=5647468959 >>> print a, "+", b, "=", a+b Aprimavista,pusembrarechenonvisiaungranvantaggioinquestomododiprocedere.Co mandareletrelineeprecedentisembrapilungo,complicatoenoiosocheutilizzarediretta menteivalori,comesarebbeperesempio: >>> print 73584784689,"+",5647468959,"=", 73584784689+5647468959

14

Laboratoriodiinformatica

Dati:nomieoggetti

E'unmodobarbaro,ma,infondo,dlostessorisultato. Traiduemetodic'unaimportantedifferenzadiimpostazione.Conunpaiodirighedicoman doinpisiottienelaseparazionedeidatidallorouso.Unavoltaassegnatelevariabilia,b, essesonoriutilizzabiliperaltricalcoli.Prova:


>>> a=100 >>> b=-2 >>> print "somma=",a+b, "differenza =", a-b, "prodotto =", a*b, "quoziente =", a/b, "potenza =", a**b

Aquestopunto,lalineadicomandopuessereriusataconaltridati.Peresempio: >>> a= 27.5 >>> b= -34.21 epoisiricopialalineaprintprecedente,conunclice<Invio>,comegisai. Separareidatidaiprogrammicheliusanounodeimetodifondamentalidell'informatica.Que stoconsentediaccedereaglistessidatiinmomentidiversieperscopi(operazionioprogram mi)diversi.Oppureconsentedidiutilizzareglistessiprogrammisudatidiversi.


Neilinguaggidiprogrammazione,disolito,unnomechefariferimentoadunvalorevienedettovaria bile,perchilnome,inmomentidiversi,pufareriferimentoavaloridiversi.LevariabiliinPython

sonodunquedelleparolecollegateconoggetti.Alcunitipidioggettiliabbiamogiincontrati: numeriinteri(int),numeriinvirgolamobile(float),stringhe(string).Cenesonoaltri cheimpareremoausarepiavanti:liste(list), tuple,dizionari,...inrealtognicosain Pythonunoggetto. Vediamocomunquesubitounprimobanaleusodelleliste: >>> omo=["Mario Rossi", 45, "via Verdi, 4"] >>> print "Sig.", omo[0], "\nabitante in", omo[2], "\ndi anni", omo[1] Sig. Mario Rossi abitante in via Verdi, 4 di anni 45 Alcuneosservazioni: 1. Unalistapucontenereoggettidiversi,anchealtreliste.Nelcasoprecedente,ilprimoe l'ultimoelementodellalistasonostringheilsecondounnumerointero. 2. Si possono estrarre gli elementi di una lista usando gli indici con la sintassi: <lista>[<indice>] 3. Importantericordarechelelistepartonodall'elemento0,cioilprimoelementodi unalistahasempreindice0,ilsecondohaindice1ecosvia. 4. Possiamoancheestrarreglielementiriferendociallafinedellalista:l'ultimoelemento haindice1,ilpenultimo2ecosvia.
IntroduzioneallinguaggioPython 15

Dati:nomieoggetti

Riassumendo Unavariabileunnomeassociatoadunoggetto. L'usodivariabilirendepiflessibiliiprogrammi. Adunavariabilesipuassociareunvaloreconl'istruzionediassegnazione: <nome> = <oggetto> Glioggetticheabbiamousatofinorasono:numeriinteri,avirgolamobile,stringheeliste. Perestrarreglielementidiunalistasiusal'indicizzazione<lista>[<indice>]. Ilprimoelementodiunalistahaindice0,l'ultimohaindice-1. Provatu 1. Usandolevariabiliscrivil'espressionepercalcolarel'areadeiquadrilaterinotevoli. 2. Dopoavermessoinunavariabiledinomenunnumerointeroscrivil'istruzione chenestampilasuatabellina.(>>> print 1*n, 2*n, ...).Stampalastessa tabellinaincolonna. 3. Datalaseguentelista:detto=["Se","non","sara'","seren","si","rasserenera'"]scrivi induemodidiversil'istruzionechestampiilsuopenultimoelemento. 4. Scriviunalistadi10elementieicomandichestampinoglielementidipostoparie poidipostodispari. 5. ControllaseinPythonadunnomepuessereassociatoprimaunoggettodiuncer totipoepoiditipodiverso. 6. Glioggetti5,5.,5e[5]sonolastessacosa?Perch 7. Qualioperazionipossonoesserefatteconlestringhe?Econleliste? 8. Ungiocoiniziacos:Prendiunnumerointero.Raddoppialo.Aggiungi10Creala variabileeassegnalevaloridiversi,stampandoognivoltailrisultatodell'espressione chedescrivelafrase.Ilgiococompletosarebbecos:Prendiunnumerointero.Rad doppialo.Aggiungi 10.Poidimezzailrisultato.Togli ilnumerochehaipensato. Scommetticherisulta5?Scrivil'espressioneeprovacondiversivaloridellavariabi le.Secondoteperchproprioverocherisulta5?

16

Laboratoriodiinformatica

Convertire,formattare

1.4. Convertire,formattare
ComefarstampareaPythonquellochevogliamonoi.
Abbiamovistocheesistonodiversitipidioggetti:int,float,string,list,...indiffe renteusareuntipoounaltro?ProviamoachiederlodirettamenteaPython,costruiamo4og gettichecontengonoilnumero7econfrontiamolitradiloro: >>> i=7 >>> f=7. >>> s="7" >>> l=[7] >>> i==f True >>> i==s False >>> i==l False >>> f==s False >>> f==l False >>> s==l False Alcuneosservazioni:
1. 2. 3. Comevediilsimbolo=vieneusatoinduemodi.Nelsolitomodofungedaoperatorediasse gnazione.Invece,seripetutoduevolte(cos:==)serveaconfrontareduevalori. Seiduevalorisonouguali,ilconfrontodarcomerisultatoTrue,altrimentidarcomerisultato False TrueeFalsesonoparticolarioggettidiPython,edindicano,ovviamente,cichetuttinoiin tendiamoperveroefalso.

Evidentementeicontenutidellevariabiliprecedentinonsonouguali!Eilprimocaso?Sepro viamoi/2ef/2 vediamocheanchequestidueoggetti,puressendoequivalenti,sicomporta noinmododiverso.Pythonmetteadisposizionedellefunzionichecercanoditrasformareun oggettodiuntipoinunoggettodiunaltrotipo.possibiletrasformareunnumerointeroinun numeronumeroinvirgolamobileeviceversa(ovviamenteperdendoidecimali),unastringa checontieneunnumeroinunnumerocorrispondenteeviceversa,unnumeroinunastringa. Unalistanonpuesseretrasformatainnumero,mapuesseretrasformatainstringa.

IntroduzioneallinguaggioPython

17

Convertire,formattare

>>> i==int(f) True >>> i/2 3 >>> int(f)/2 3 >>> f/2 3.5 >>> float(i)/2 3.5 >>> i==int(s) True >>> s==str(i) True Orasupponiamodiaverenellavariabileailnumero15enellavariabilebilnumero4edivo lerottenerelastampadiquestastringa:15/4=3.75.Creiamolenostrevariabilieusiamoime todichegiconosciamo: >>> a=15 >>> b=4 >>> print a, "/", b, "=", a/b 15 / 4 = 3 Ladivisionedsololaparteinteradelquoziente,masetrasformiamounavariabileinterain virgolamobileotteniamoilrisultatocorretto: >>> print a, "/", b, "=", float(a)/b 15 / 4 = 3.75 Icalcoliorasonoesatti,manonmipiaccionoglispaziinseriti.Pereliminarli,possoevitarele virgole,trasformareinstringheogninumeroeconcatenarelestringhe: >>> print str(a) + "/" + str(b) + "=" + str(float(a)/b) 15/4=3.75 Ottengoesattamentequellochevolevo,mal'istruzionepenosadascrivere...Pythonmettea disposizioneunaltrometodoperottenerelostessorisultato:laformattazionedistringhe.Scrivo lastringacomevoglioottenerla,maalpostodellevariabilimettodeisegnaposto:%s,dopola stringac'l'operatorediformattazione%eunatupla(ciounasequenzadioggettiseparati davirgoleracchiusitraparentesitonde)contantioggettiquantisonoisegnaposto.Questiog gettiverrannoconvertitiinstringheeinseritialpostodeicaratteri%s: >>> print "%s/%s=%s" % (a, b, float(a)/b) 15/4=3.75
18 Laboratoriodiinformatica

Convertire,formattare

Laformattazionedistringhefornisceancheunmodoalternativoperconcatenarestringhe: >>> a="abra" >>> b="cadabra" >>> s1=a+b >>> s2="%s%s" % (a, b) >>> s1==s2 True >>> print s1 abracadabra Riassumendo possibileentrocertilimititrasformareunoggettoinunaltro. Questopermetteditrattareintericomefloat,stringhecomeinteri,... possibilecostruirestringheconl'operatorediformattazionedistringhe:%usandocome segnapostiicaratteri%soaltreparticolaricombinazionidicaratteri. Provatu 1. ProvaleseguentilineedicomandoeprendinotadicichefaPython. >>> int(10) >>> str("10") >>> int("10") >>> print str(10.33)+ str(10) >>> int(10.3) >>> print str(10)*5 >>> float(10) >>> print float(10)*5 >>> float("10") >>> print float(5)/2 >>> float(10.3) >>> print float(5/2) >>> str(10)
2. Scriviun'istruzionechediailquozientedecimalediduenumeriinteri?

3. Riprendigliesercizi3,5,6delcapitoloriguardanteleespressioniecostruiscidelle stringheconlarispostacompletaalproblemausandolaconversioneditipoconla concatenazioneepoiusandolaformattazionedistringhe(ades.L'ipotenusa di un triangolo con i cateti lunghi 3 e 4 lunga 5).


4. Mettiilvalore5nellavariabilebaseeilvalore3nellavariabileesponente,poiscriviilco mandoperottenerelastringa:5^3=125usandolefunzionidiconversioneelaformattazio nedistringa. Cambiaivaloridellevariabiliprecedentiecontrollacheilrisultatosiasemprecorretto. Mettiinunavariabileunnumerointero,poiscrivil'istruzionecheproducelastringaformata dalnumerodellavariabile,dalsuoquadratoedalsuocubo,separatidauntabulatore.

5. 6.

IntroduzioneallinguaggioPython

19

Ripetereistruzioni

1.5. Ripetereistruzioni
Comefarstaremillecomandiinunarigadicodice.
Icomputerattualieseguonomilioniomiliardidiistruzionialsecondo,masedevoscrivere esplicitamenteogniistruzionechedeveeseguire,impiegosecoliesecoliperscrivereunpro gramma.Sevogliocheunprogrammastampi3voltediseguitounafrasepossoscrivere: >>> print "ciao a tutti"; print "ciao a tutti"; print "ciao a tutti"; ciao a tutti ciao a tutti ciao a tutti oppurepossousareun'istruzionecheproduceunciclo: >>> for cont in range(3): print "ciao a tutti"

ciao a tutti ciao a tutti ciao a tutti Alcuneosservazioni: 1. L'istruzionefor ...nonmoltopisinteticadei3comandimessidiseguito.Mase dovessistampare1000voltelafrase,colprimometodolafaccendadiventerebbecom plicataenoiosa,mentreconl'istruzionefor ...mibasterebbecambiareunnumero: for cont in range(1000): ... 2. L'istruzionevacapita,partiamodalfondo: 1. range(1000)fornisce,unalistachecontienegliinterida0a999(1000numeri), 2. unoallavolta,inumericontenutinellalistaprodottadarange,vienemessonella variabilecont... 3. eperognivaloredicontvieneeseguitoilbloccodicodicechesegueilsimbolo : 3. Lasintassi: for <variabile> in range(<numero>): <istruzioni> 4. L'istruzioneforripetetutteleistruzionichelaseguonoechesonoindentate,ciorien tratedialcunispazirispettoall'istruzionestessa.

20

Laboratoriodiinformatica

Ripetereistruzioni

5. InPythonlerighedicodiceconsecutivecheinizianoallastessacolonna,formanoun bloccodicodice. 6. Seavviamounciclotroppolungoevogliamointerromperlopossiamopremereiltasto: <Ctrl-c>. 7. Iltipodistrutturainformaticaprodottadalcomandoforsichiamaiterazione. Proviamoadesplorareilsignificatodellavariabilecheseguel'istruzionefor,acosapuservi te?Iniziamoaprovareilcomando: >>> for cont in range(5): print cont

0 1 2 3 4 Possiamofarcistampareunatabelladiquadratiecubi: >>> for num in range(11): print "%s num*num*num) %s %s" % (num, num*num,

mainumerisonoallineatimale.Provaquestavariante: >>> for num in range(5): print "%5s %5s %5s" % (num, num*num, num*num*num) Chesignificatohailnumeroinseritonelsegnaposto?Epervedereireciprocideinumeriprece denti?Ovviamente(?!)nonpossopartireda0,mada1.Devoanchestareattentoalleespressio ni:1/i*inonlostessodi1/(i*i).Poichsia1cheisonovaloriinteri,Pythontroncailrisulta toeliminandoidecimali.Unmodoperrisolvereiproblemiprecedenti: >>> for n in range(1, 5): print "%10s %10s (n*n*n)) %10s" %(1./n, 1./(n*n), 1./

Riassumendo PossiamofarripetereaPythonunbloccodicodiceusandol'istruzionefor. Unbloccodicodicesiriconosceperchformatodaistruzioniconsecutivecheinizianoin


IntroduzioneallinguaggioPython 21

Ripetereistruzioni

modoallineato,sullastessacolonna. Lasintassidell'istruzionefor: for <variabile> in range(<numero>): <bloco di istruzioni> Lavariabiledelciclocontiene,adogniciclo,unnumerointerosuccessivoda0a<numero>escluso. rangepuaveredueparametriinquestocasolavariabilevadalprimoall'ultimoescluso. Provatu 1. Laformattazionedell'ultimoesempio,faunpo'schifo...provaconquest'altrastringa: "%10.5f %10.5f %10.5f"

2. QualialtricaratteridiformattazionesonoriconosciutidaPython? 3. Scriviunciclochestampiperogninumeroda0a20:ilnumerostesso,ilsuodoppio ilsuotriploeilsuoquadruplo,inmodocherisultinoallineati. 4. Mettiinunavariabile,nunnumero.Scriviilciclochestampiisuoiprimi15mul tipli. 5. Scriviunciclochestampiimultiplidiunnumerosenzaandareacapo. 6. Scriviunciclochestampiimultiplidi7masolodal35multiploal43. 7. Unciclopucontenerealtricicliannidati...Scriviilcomandochestampilatabellina pitagorica.

22

Laboratoriodiinformatica

Ilprimoprogramma

1.6. Ilprimoprogramma
Comescrivereilnostroprimoprogramma, unprogrammachenonfaniente, unprogrammachefaqualcosa.
Finalmenteabbiamoglistrumentiperscriverequalcosadisignificativo,qualcosadiabbastanza complicatodavalerlapenadiconservare,unprogramma. ApertoIDLE,attraversoilmenuFile - New Windowcreiamounnuovofilevuoto.Prima ancora di incominciare a scriverci qualcosa lo salviamo, nella nostra cartella, con il nome primo.py.importantel'estensione.pycheavvisailsistemaoperativo,eIDLEstesso, chequestounprogrammaPython. Abbiamoscrittoilnostroprimoprogramma!Possiamoancheeseguirloinunodiquestidue modi: 1. Menu:Run - Run Module 2. tasto:<F5> Faunpo'poco,maincompenso,disicuro,noncontieneerrori!!!Forseilcasodicominciarea riempirlo. Perprimacosaaggiungiamodelleistruzionichenonfannoniente,deicommenti.Ognilinguag giopermettediscriveredeicommenti.Eicommentisonomoltoimportantiperrendereleggibi leilcodiceeperrenderlocomprensibileadaltrioancheasstessiadistanzaditempo.InPythoncisonopimodiperfarlo.Sonocommenti: 1. lerighecheinizianoconilcaratterecancelletto:# 2. leporzioniditestodelimitatidatreapicisingoliodoppi:"""o''' Ogniprogrammadeveavereall'iniziodeicommentichefornisconoalcuneinformazionicome minimo:data,autore,titolo.Ilcommentoinizialepotrebbeessere: # 27-08-06 # il mio primo programma # Mario Rossi Primadiscrivereunprogramma,bisognaavereun'ideaabbastanzaprecisadicosadevefare questoprogramma.Nelnostrocasoiniziamoacreareunprogrammachestampiavideoletavo lenumeriche,quelleconiquadrati,icubi,leradiciquadrateeradicicubiche. Perprimacosamodifichiamoiltitolodelprogramma.Poi(magariandandoariguardarelein formazionisuicicli)scriviamoleistruzioniperstamparesemplicementeinumerida0a100 for num in range(101): print "%s" % num

IntroduzioneallinguaggioPython

23

Ilprimoprogramma

Alcuneosservazioni: 1. Mentre nell'ambiente IDLE una voltascritto un comando, quando si preme iltasto <Invio>,magri2volte,ilcomandovieneeseguito,quiiltasto<Invio>hasoloil significatodiandareacapo. 2. Inunprogramma,noiscriviamoleistruzioni,pereseguirledobbiamodirloesplicita menteaPython,losipufareinunodeiduemodivistisopra,ilpisvelto<F5>. 3. Primadieseguireunprogramma,Pythonlosalvasuldisco. 4. Ilrisultatodelprogramma(l'output)lovediamonellafinestradiIDLE.Convienequin didisporreleduefinestreinmodochepermettanodivedereilprogrammael'outputdel programma. Bene,setuttofunzionaabbiamounbell'elencodinumeriscrittiunosottol'altro,mal'allinea mentoasinistranoncarino:torniamoalprogrammaemodifichiamoloinmododariservare5 spaziperquestinumeri: for num in range(101): print "%5s" % num Conilsolito<F5>verifichiamocheilprogrammafacciaquellochevogliamonoi.Aggiungerei quadratieicubinonunanovitdatochequestoproblemagistatorisoltoquandoabbiamo vistoilciclofor.Magaripotrservirequalcheprovaperaggiustaregliallineamenti: for num in range(101): print "%5s" % (num, num*num, num*num*num) quandoeseguiamoquestoprogrammaotteniamoilseguentedeludenterisultato: Traceback (most recent call last): File "/dati/daniele/06-07/scuola/materiali/informatica/python/primo.py", line 8, in -toplevelprint "%5s" % (num, num*num, num*num*num) TypeError: not all arguments converted during string formatting Sevogliamoimparareaprogrammaredobbiamoabituarciaquestesorpreseeimpararealegge reimessaggidierrore.Nelprecedentemessaggiocisonodiverseinformazioni:ilnomedelfile, larigaincriminataeiltipodierrore.Possiamotradurreilmessaggiocos: Nellalinea8delfileprimo.pycisonodeivalorichenonsonopotutientrarenellastringa formattata.Torniamoamodificareilprogrammainserendoisegnapostimancanti: for num in range(101): print "%4s %6s %8s" % (num, num*num, num*num*num)

24

Laboratoriodiinformatica

Ilprimoprogramma

Questivaloripotrebberoandare.Oradobbiamoinserirealtreduecolonneecalcolareleradici quadrateecubiche.AbbiamogivistochePythonsenzailsupportodiappositelibrerienon ingradodicalcolareleradici,quindidobbiamomodificareilprogrammainmodocheimporti lalibreriamath.Aggiungiamoprimadelcicloilcomando: import math

Riassumendo Unprogrammaundocumentoditestochecontieneleistruzionichedevonoessereesegui te. Concettualmentedobbiamodistinguerebenelafasediscritturadelprogramma,dallafasedi esecuzione. Inpraticaconvienescrivereunpezzettodiprogramma,provarlo,correggerlo,riprovarloe, quandoquelpezzoproducequellochevogliamonoi,aggiungerealtrefunzionalit. Durantelaprogrammazioneinevitabilecommettereerrori.Imessaggidierrore,seletti, sonodigrandeaiuto. Provatu 1. Completailprogrammaprecedente.Comepossibilefarcalcolarelaradicecubicase nonc'unaappositafunzione? 2. Aggiungialprogrammaleistruzionichestampinoanchel'intestazionedellatabella. 3. Scriviilprogrammasecondo.pychestampilelunghezzedeilatideitriangoli rettangoliisosceliconicatetichevarianotra1a10.

IntroduzioneallinguaggioPython

25

Organizzazione

1.7. Organizzazione
Comedareunnomeapezzidiprogramma, definizioneeusodifunzioni.
Unprogrammaunasequenzadiistruzionimasonopassatiitempiincuiunprogrammaera semplicementeunalistanumeratadiistruzioni.Inunbuonprogrammaleistruzionisonorag gruppateinblocchichehannounsensopreciso,unafunzioneprecisa.questiblocchisichiama noappuntofunzioni(inaltrilinguaggisidistinguetrafunzionieprocedure).Ognifunzioneha unsuonomeeognivoltachedefiniamounanuovafunzioneillinguaggiosiampliadiunnuovo comando.Ades.sedefiniscounafunzionechesichiamasaluta,illinguaggiosapreseguire ilcomandosaluta.Unafunzionecostituitadallaparolariservatadefseguitadalnome dellafunzione,daunacoppiadiparentesitonde,dalcarattere:edaunbloccodiistruzioni: def <nome>(): <istruzioni> <nome>unaqualunqueparola,madobbiamoscegliereunaparolachedescrivamegliopossi bileilsignificatodellafunzionestessa:illinguaggiodiprogrammazioneserveinnanzituttoa renderecomprensibileunprogrammaagliumani,<istruzioni>unaqualsiasisequenzadi istruzionichepuesserecostituitaadaistruzionigipresentinellinguaggioodefinitedanoi comenuovefunzioni. Unprogrammageneralmentenonaltrocheuninsiemedifunzioni.Perallenarciscriviamole procedurechecalcolinoiprimiterminidialcunesuccessioni. 1. Iniziamocreandounnuovoprogramma:daIDLE,Menu: File - New Window. 2. Poisalviamoilfileconilnomesuccessioni.py,Menu: File - Save as. 3. Orascriviamoleprimerighedelprogrammascrivendodeicommentichecontengano: data,titolo,autori. Iniziamoconlasuccessionedeiprimi10numeritriangolari.Questasuccessionesiottienepar tendoda0eaggiungendoilsuccessivonumeronaturaleall'ultimonumerotriangolare: 0+0,0+1,1+2,3+3,6+4,... Servequindiunavariabilechecontengailnumerotriangolare(all'inizio0)eunciclocheper corrainumerinaturali(ciclofor).All'internodelcicloaggiungoalnumerotriangolareattuale l'attualenumeronaturaleestampoilnuovovalore def triangolari10(): triangolare=0 for num in range(10): triangolare+=num print "%5s" % triangolare

26

Laboratoriodiinformatica

Organizzazione

Oraproviamoaeseguireilprogramma:<F5>...Nonsuccedeniente!InrealtPyhonhalavo rato,mailrisultatodiquestolavorononciappare.Pythonhaimparatocosadevefarequando noiglidiciamodieseguiretriangolari10.Perprovarlocispostiamonell'ambienteIDLEe diamoilcomando: >>> triangolari10() Senoncivengonosegnalatierrori,vengonostampatiiprimi10numeritriangolari.Masenon ciandasserobeneiprimi10numeridellasuccessionenevolessimo15o20o100?Possiamo scrivereun'altraprocedura,simileaquestachecichiedaquantinumerivogliamostampare.L'i struzionechepermettedileggeredatastieraunastringadicaratteri raw_input([<messaggio>]).Possiamoancheiniziarelafunzioneconun'istruzionechestampiun'intestazione: def triangolari(): print "Successione dei numeri triangolari" print n=raw_input("Quanti termini della successione? ") triangolare=0 for num in range(n): triangolare+=num print "%5s" % triangolare Solito<F5>epoinell'ambienteIDLE.diamoilcomandotriangolari(),rispondiamoalla richiestaconunnumero,...eleggiamoilmessaggiodierrore Traceback (most recent call last): File "<pyshell#4>", line 1, in -topleveltriangolari() File "/dati/daniele/06-07/scuola/materiali/informatica/python/successioni.py", line 16, in triangolari for num in range(n): TypeError: an integer is required Manoiavevamoscrittounnumerocomemairangedicecheinnnonc'unnumero?Lafun zioneraw_input()restituisceunastringa,dobbiamoconvertirlainnumero.Quindiritornare nelprogrammaemodificarelaterzarigadellafunzioneinmodocheesegualaconversionee inserisca in n, nonil risultato di raw_input ma la conversione in intero del risultato di raw_input: n <-- int <-- raw_input InPython: n=int(raw_input("Quanti termini della successione? "))

IntroduzioneallinguaggioPython

27

Organizzazione

Conquestamodifica,senoncisonoaltrierrori,lafunzioneproducelasuccessionedesiderata. Riassumendo Inunprogramma,leistruzionevannoraggruppateinfunzioni(oprocedure). Lasintassiperscrivereunafunzione: def <nome>(): <istruzioni> Bisognadistinguerebeneladefinizionediunafunzionedall'esecuzionedellafunzionestes sa.Quandosidefinisce(def ...)lafunzione, Python associaunbloccodicodiceaun nome.Quandosiesegueunafunzione,siscriveilsuonomeseguitodaunacoppiadiparen tesiePythonesegueilcodiceassociatoaquelnome. Ilmeccanismodellefunzionipermettedicrearedellenuovefunzionalitdellinguaggioper mettendodicollegareunbloccodicodiceaunaparola. Provatu 1. Scrivilefunzionichestampanoiprimi10numeriparieiprimi10numeridispari. 2. Scrivilefunzioni,derivatedalleprecedenti,machechiedonoquantinumeristampa re. 3. Scrivilefunzionichestampanoinumeriquadratieinumeriesagonali.

28

Laboratoriodiinformatica

Parametri

1.8. Parametri
Comegeneralizzarefunzioni, comepassarevaloriallefunzioni.
Lefunzionidefinitedalprogrammatoresonomoltoutiliperdividereilprogrammainpartisuf ficientementepiccole.Mahannolapossibilitdidiventaremoltopiutilisealnomedellafun zioneaggiungiamodeiparametri.Iparametrisonodellevariabili,deinomiscrittitraleparente sicheseguonoilnomedellafunzione,aiparametrivengonoassociatideglioggettiquandola funzionestessavienechiamata. Riprendiamoilprogrammasuccessioni.Salviamolocambiandogliilnome(Menu: File Save as),chiamiamolosuccessioni02.py.Aggiustiamolerighediintestazionedelpro gramma(ladataeiltitolo).Modifichiamooralafunzionetriangolariaggiungendotrale parentesiilnomediunavariabile:n.Togliamoancheleprimetrerigheinmododaavere: def triangolari(n): triangolare=0 for num in range(n): triangolare+=num print "%5s" % triangolare Ilcodiceritornaadessereessenzialeepulito.Proviamolo:<F5>epoinell'ambienteIDLE: >>> triangolari() Traceback (most recent call last): File "<pyshell#0>", line 1, in -topleveltriangolari() TypeError: triangolari() takes exactly 1 argument (0 given) Ilrisultatononproprioquellocheciaspettavamo!Ilmessaggiocisegnalachetriangolarisiaspettadiricevereunargomentomentrenonneharicevutoneancheuno,cinongliva beneePythonprotesta.Inpratica,allavariabilen(parametro)chenelladefinizionedellafun zionemessatraparentesi,nonstatoassociatonessunoggetto(argomento)equinditriango larinonpuandareavanti.Comedareunvalorealparametron?Almomentodellachiamata dellafunzione,traleparentesipossiamoinseriredegliargomentiequestiverrannoassociatiai parametri. >>> triangolari(5) 0 1 3 6 10
IntroduzioneallinguaggioPython 29

Parametri

Iparametricipermettonodiscrivereprocedurepiflessibilicheutilizzanovariabiliilcuivalo revienedefinitoalmomentodellachiamatadellafunzionestessa. Affrontiamounaltroproblema:proviamoascrivereprocedurechecalcolinoareeeperimetri dellefigurepianestudiateallemedie.Periniziarevogliounaprocedurache,datibaseealtezza, diuntriangolonestampil'area.Poichidatisono2,avrbisognodi2parametri,edatochede vonocontenerelamisuradellabaseelamisuradell'altezzaconvienechiamarleunabasee l'altraaltezza(mano!).Nota:inomidellefunzioniedellevariabilidevonoaversensoper noi,perilcomputerunnomeol'altrolostesso. Datocheiniziamounnuovoprogetto,creiamounnuovofileeintestiamoloconisoliticom menti,poiiniziamoariempirloconlefunzioninecessarie.Adesempio: def areatriangoloBH(base, altezza): print "Area del triangolo" print "base = %s" % base print "altezza = %s" % altezza print "area = %s" % (base*altezza/2.)

Alcuneosservazioni: 1. Datochecisonopimodipercalcolarel'areadeltriangolo,ilnomedellafunzionecon tienequelleduestranelettere:BHcheindicanobaseealtezza. 2. Nell'ultimalineadellafunzionebisognaprestareattenzioneadunpaiodiparticolari. Puressendociunsoloelementodainserirenellastringa,leparentesisononecessarie penaunostranoerroredovutoaquestionidiprecedenzadeglioperatori:%vieneese guitoprimadi*.Secondo:dopoil2necessariounpunto,perch? Un'altrafamosaformulapercalcolarel'areadeltriangoloquellachepartedai3lati:lafor muladiErone. Perchisel'dimenticataeccolafamosaformula:

area= p pl1 pl2 pl3 dovepilsemiperimetroel1,l2,l3sonoitrelati.


Riassumendo Iparametrisonodellevariabilidiproprietdellefunzioni. Ogniparametrohaunnomechevienedecisoquandosidefiniscelafunzione. Ilcontenutodeiparametrivienedecisoquandovienechiamatalafunzionechelicontiene. Iparametripermettonodiscriverefunzionichehannocomportamentidiversi,decisialmo mentodellachiamata. Unafunzionepuchiamareun'altrafunzione,cheasuavoltapuchiamarneun'altra,ecos via.

30

Laboratoriodiinformatica

Parametri

Provatu 1. Modificalefunzionicopiatedasuccessioni.pyinmodocheaccettinounpara metroecancellaquelledivenutesuperflue. 2. Scrivilafunzionechecalcolal'areadeltriangoloconlaformuladiErone. 3. Provalaprecedentefunzionefinchnondunerrore,qualivaloripossonodareerro re,perch? 4. Scrivilefunzionichecalcolanoiperimetrideipoligonicheconosci. 5. Scrivilefunzionichecalcolanoleareedeiquadrilaterinotevoli.

IntroduzioneallinguaggioPython

31

Nuoveoperazioni

1.9. Nuoveoperazioni
Comescriverefunzioniconunrisultato.
Abbiamoscrittodellefunzionichecalcolanoestampanoilrisultatodicerteformule,mailin guaggidiprogrammazionepermettonoanchediscriveredeiblocchidicodicechesicomporta nocomedelleoperazioniciofunzionichedannounrisultato.Ilinguaggidiprogrammazione permettonopercidicrearedellenuoveoperazioni.L'istruzionechepermettedicrearenuove operazionil'istruzionereturn.Questaistruzionehadueeffetti:terminaunafunzioneeresti tuisceunrisultatoachil'hachiamata. Vediamounesempio,possiamoscriverel'operazionecherestituiscelamediadiduenumeri. Iniziamounnuovoprogramma,menu -File-New window,soliterighedicommento,poi scriviamolafunzione: def media(n1, n2): return (n1+n2)/2. Solito<F5>epoiinIDLE: >>> print media(12, 18) 15.0 Ilfattodiusaredellefunzionicherestituisconounvaloreimportanteininformatica,permette disepararelapartedicalcolodaquelladiinputeoutputdeidati.Riprendiamoilcalcolodell'a readiuntriangolodatiitrelati,possiamoscrivereunafunzionechecalcolilaformuladiErone: def erone(l1, l2, l3): p=(l1+l2+l3)/2. return (p*(p-l1)*(p-l2)*(p-l3))**0.5 Osservazioni: 1. Nellaformula p=(l1+l2+l3)/2. leparentesieilpuntodopoil2sononecessari, perch? 2. Questavoltanonhoutilizzatolalibreriamathpercalcolarelaradicequadrata,maho usatountruccomatematico:laradicequadratadiunnumerougualeaunapotenzache haperesponenteilvaloreo0.5cheequivalente. 3. Neifoglidicalcoloeinaltrilinguaggiilsimbolodellapotenza^,inPythonuna coppiadiasterischi**. OralafunzioneareatriangoloABCdiventa:

32

Laboratoriodiinformatica

Nuoveoperazioni

def areatriangoloABC(l1, l2, l3): """Calcolo dell'area con la formula di Erone.""" # Immissione dati print "Area del triangolo" print "lato1 = %s" % l1 print "lato2 = %s" % l2 print "lato3 = %s" % l3 # Calcolo area=erone(l1, l2, l3) # Visualizzazione risultati print "area = %s" % area Inquestomodoabbiamorealizzatounaseparazionetralafunzionecherealizzalacomunicazio neconl'utenteelafunzionecherealizzailcalcolo.Questaseparazionemoltoimportantenei programmiseri.Lefunzionipermettonountipodiprogrammazionemoltosinteticaepulita. Cisonolinguaggidiprogrammazionecheusanopesantementequestatecnica,sonodettilin guaggifunzionali.Pythonpermetteancheunaprogrammazioneditipofunzionale. Supponiamodidovercalcolarelamediadell'areadiduetriangoli.LatraduzioneinPythondi ventaquasiletterale: def mediatri(a1, a2, a3, b1, b2, b3): return media(erone(a1, a2, a3), erone(b1, b2, b3)) InIDLEperprovarla: >>> print mediatri(3, 4, 5, 13, 14, 15) 45.0 Comefunziona?mediatririceve6numeri,ilatidei2triangoli,chiamalafunzionemediae lepassaduevaloriirisultatidieroneconiprimi3latieeroneconglialtri3.Lefunzioni eronecalcolanoleduearee,lafunzionemedianecalcolalamediaelafunzionemediatri restituisceilrisultato. Pythonpermetteanchedicostruirefunzionichedannopirisultati.Questopurisultareutile in matematica, ad esempio il punto medio M di un segmento di estremi A=(xa, ya) e B=(xb, e yb)hapercoordinatexm=(xa+xb)/2eym=(ya+yb)/2.InPythonsipu scriverelafunzione: def puntomedio(xa, ya, xb, yb): return (xa+xb)/2., (ya+yb)/2. einIDLE: >>> print puntomedio(2, 5, -6, 1) (-2.0, 3.0)
IntroduzioneallinguaggioPython 33

Nuoveoperazioni

Riassumendo possibilescriverefunzionicherestituisconounrisultato. Unafunzioneterminaquandononcisonopiistruzionidaeseguireoquandovieneeseguita l'istruzionereturn. Ilcomandocheterminal'esecuzionediunafunzionefornendoilrisultato return <espressione[,..]>. Unafunzionepurestituirepidiunrisultato,inquestocasoirisultativannoelencatidopo l'istruzionereturn,separatidavirgole. Pythonpermetteunaprogrammazionefunzionale. Provatu 1. Riscriviilcalcolodell'areadeipoligoniusandodellefunzioni. 2. Scrivilafunzionechecalcolalamediatra3numeri. 3. Riscrivilafunzionepuntomedio()inmodocheusilafunzionemedia. 4. Scrivilafunzionecherestituiscecoefficienteangolareeterminenotodellarettapas santeperduepunti. 5. Scrivilafunzionecherestituiscecoefficienteangolareeterminenotodell'assediun segmento. 6. Scrivilafunzionecheeffettualatraslazionediunpuntonelpianocartesiano. 7. Scrivilefunzionicheeffettuanoilribaltamentodiunpuntorispettoagliassieall'ori gine.

34

Laboratoriodiinformatica

Operarescelte

1.10. Operarescelte
Comeeseguirediverseporzionidicodiceasecondadelrisultatodiun'espressione, comeusarel'istruzionedisceltaodiselezione
Iprogrammielefunzioniscrittifinoraeseguonotutteleistruzionichevengonoscritte,mailin guaggidiprogrammazionedannoanchelapossibilitdieseguireungruppodiistruzionioun altroinbaseadeterminatecondizioni.Permettonociodidescriverealgoritmichesvolgonoil seguentecompito: se vera una certa condizione esegui qualcosa altrimenti esegui qualcos'altro Ilprincipalecomandochepermettedioperaredellescelteifelasuasintassiunadellese guenti. if <condizione>: <istruzioni> oppure: if <condizione>: <istruzioni 1> else: <istruzioni 2> Nelcalcolodell'areadeltriangolodatiilati,laformuladiEronefunzionasoloseiltriangolo puesserecostruito,seilatinonrispettanoledisuguaglianzetriangolarialloralafunzioneter minaconunerroreinfatti,inquestocaso,l'espressioneall'internodellaradiceassumevalore negativo.possibilemodificarelafunzioneinmodocherestituiscaunvaloreparticolarenel casoitrenumerinonpossanoesserelemisuredeilatidiuntriangolo.Inuntriangoloognilato deveessereminoredellasommadeglialtridue.Possiamoquindicalcolarelesommedellecop piedilatieconfrontareognunaconilterzolato;setuttiquesticonfrontidannoesitopositivo calcoliamol'area,altrimentirestituiamoilvaloreNone.Lafunzioneerone()puesserescritta cos:

IntroduzioneallinguaggioPython

35

Operarescelte

def erone(lato1, lato2, lato3): """Restituisce l'area di un triangolo dati i tre lati utilizzando la Formula di Erone.""" if (lato3<=lato1+lato2 and lato2<=lato1+lato3 and lato1<=lato2+lato3): p=(lato1+lato2+lato3)/2. return (p*(p-lato1)*(p-lato2)*(p-lato3))**0.5 else: return None Orascriviamounafunzionecheleggadall'utentelalunghezzadeitrelatideltriangoloene stampil'area: def areatriangolo(): """Calcolo dell'area con la formula di Erone.""" # Inserimento dati print "Area del triangolo" lato1=float(raw_input("primo lato = ")) lato2=float(raw_input("secondo lato = ")) lato3=float(raw_input("terzo lato = ")) # Calcolo area=erone(lato1, lato2, lato3) # Visualizzazione risultati if area!=None: print "area = %s" % area else: print "Nessun triangolo pu avere questi tre lati!" Proviamolafunzionenellashellcondiversivaloridegliargomenti. Proviamooraascrivereunafunzionechericeva2numeriediacomerisultatoilpipiccolo. Conunlinguaggioquasinaturale: i due numeri sono n1 e n2: se n1 minore di n2 allora il risultato n1 altrimenti il risultato n2 TraducendoloinunafunzionescrittaconillinguaggioPython: def min(n1, n2): """Restituisce il minore tra n1 e n2.""" if n1<n2: return n1 else: return n2

36

Laboratoriodiinformatica

Operarescelte

Possiamousarlaperscrivereunascrivereunaproceduracheleggaduenumeriestampiilmino re: def pmin(): """Legge due numeri e ne stampa il minore.""" # Inserimento dati a=float(raw_input("primo numero = ")) b=float(raw_input("secondo numero = ")) # Calcolo e visualizzazione risultati print "Il minore tra: %s e %s %s" % (a, b, min(a, b)) Avoltedobbiamodistinguerepidi2casi,adesempiosevogliamodistingueresedi2numeri ilprimominoremaggioreouguale,possiamoscrivere: def confronta(): """Confronto tra due numeri.""" # Inserimento dati n1=float(raw_input("primo numero = ")) n2=float(raw_input("secondo numero = ")) # Visualizzazione risultati if n1<n2: print "%s minore di %s" % (n1, n2) elif n1>n2: print "%s maggiore di %s" % (n1, n2) else: print "%s uguale a %s" % (n1, n2)

Riassumendo possibile,inbaseaunacondizioneeseguiredelleistruzioniodellealtre.Questastruttura dicontrollosichiamaselezione. Lasintassidell'istruzioneif: if <condizione1>: <istruzioni 1> [elif <condizione2>: <istruzioni 2> [...]] [else: <istruzioni 3>] Leparentesiquadreindicanoporzionifacoltativedicodice. Leclausoleelifeelsepossonononesserci.

IntroduzioneallinguaggioPython

37

Operarescelte

Provatu 1. Scrivilafunzionemassimochedcomerisultatoilmassimotra2numeri. 2. Scrivilafunzioneche,usandolafunzione massimo,legge2numeriestampail maggioredeidue. 3. Scrivilefunzionimin3emax3cherestituisconorispettivamenteilminimoeilmas simotra3numeri. 4. Scrivilafunzioneordina2chedatiduenumerilirestituiscedispostiinordine,pri mailpipiccoloepoiilpigrande. 5. Scrivilafunzioneordina3,analogaallaprecedente,machelavorasu3numeri. 6. Riscrivilafunzionechecalcolailcoefficienteangolarediunaretta,dati2punti,con siderandoancheilcasoincuiiduepuntiabbianolastessaascissa. 7. Scriviunafunzionecheforzaunvaloreall'internodiunmassimoeunminimo: taglia(50, 68, 100)->68; taglia(50, 27, 100)->50

38

Laboratoriodiinformatica

Sequenzeecicli

1.11. Sequenzeecicli
Cometrattaresequenzedidati.
Neicapitoliprecedentiabbiamovistoalcunitipididati,int,float,streunmodoperripe tereleistruzioniusandol'istruzionefor.Inquestocapitoloapprofondiamolaconoscenzadelle stringheedell'istruzionefor,vedendocomesonocollegatitradiloro. C'un'importantedifferenzatrainumerielestringheinPython.inumerivengonovisticome unoggettocompatto,lestringhecomeunasequenza:unastringaunasequenzadicaratteri. Pythonmetteadisposizionedituttiglioggettiditiposequenzadeglistrumentiperricavare singolielementiointerefettedellasequenzaepersaperequantielementicontengono.Incomin ciamoconilcostruireunastringaestamparnelalunghezza,cioilnumerodielementichela compongono: >>> s="Pippo Pluto Paperino" >>> print s Pippo Pluto Paperino >>> print len(s) 20 Orasevogliamostampareilsuoprimocaratterepossiamoapplicareallasequenzaunindice: >>> print s[1] i No,nonfunziona,nonrestituisceilprimocarattere,infattiPythoniniziatuttelesequenzecon l'indice0: >>> print s[0] P Cosilnonocaratterelosiottieneusandol'indice8: >>> print s[8] u PossiamoanchedireaPythondiiniziareacontaredall'ultimoelemento: >>> print s[-1], s[-4], s[-10] o r o Avolteutileestrarredaunasequenzanonunsoloelemento,maunasottosequenza,unafetta. Bastaspecificarequalepezzovogliamoscrivendodueindiciseparatidalsimbolo:.Dobbia motenerecontochelastringarestituitavadalprimoindicecompresoall'ultimoescluso
IntroduzioneallinguaggioPython 39

Sequenzeecicli

>>> print s[6:11] Pluto Seomettiamounindice,sarannosottintesiilprimool'ultimoelemento: >>> print s[:4] Pipp >>> print s[4:] o Pluto Paperino L'operatore+permettediconcatenarestringhe: >>> s1="bar" >>> s2="bone" >>> print s1+s2 barbone Edoravediamocomeilcicloforcollegatoconlesequenze.L'usogivistonelcapitolosulla ripetizionediistruzionisolounadellepossibilitdell'istruzionefor.Ingeneralequestaistru zionepermettediscorrereglielementidiunasequenza.Comeesempio,stampiamounadopo l'altraleletterediunaparola: >>> for carattere in "Casa": print carattere, C a s a Inunnuovofile(stringhe.py)scriviamolaproceduraperstampareunaparolatriangolare: l'interaparola,laparolasenzalaprimalettera,dallaterzainpoi,ecosvia. def triangolo(s): for indice in range(len(s)): print s[indice:] e,nell'ambienteIDLE,proviamola: >>> triangolo("scala") scala cala ala la a Pythonforniscediversealtrefunzioniutilirelativeallestringhe,possiamofarcelodiredaPythonstessoscrivendo: >>> help(str)
40 Laboratoriodiinformatica

Sequenzeecicli

Inquestomodosiotterrlastampadituttiimetodidellaclassestr. Riassumendo Lestringhesonodeglioggettisequenza,vuoldirechesonovistedaPythoncomeunase quenzaordinatadielementi.Nelcasodellestringhe,ovviamente,glielementisonocaratteri. Ilprimoelementodiunasequenzahasempreindice0,l'ultimohaindice-1. possibileestrarreunelementodiunasequenzaconlasintassi: <sequenza>[<indice>]. L'indicepuessereunnumeropositivo(ilconteggiopartedall'inizio)onegativo(ilconteg giopartedallafine).Sel'indiceeccedeilimitidellasequenzavienesollevatounerrore. Sevoglioestrarreunasottosequenzadaunoggettosequenzapossousarel'affettamento: <sequenza>[<indice1>:<indice2>] L'istruzioneforpermettediscorrereglielementidiunasequenza,lasuasintassi: for <variabile> in <sequenza> <istruzioni>

Provatu 1. Scrivilaproceduraverticale(s)chestampaicaratteridiunastringaunosotto l'altro. 2. Scrivilaproceduratriangoloinverso(s) chestampal'ultimocaratterediuna stringa,poigliultimidueecosviafinoastamparetuttalastringa. 3. Scrivilafunzioneche,dataunastringa,stampilesueletteresaltandoglispazi. 4. Scrivilafunzioneche,dataunastringa,stampilesueletteresaltandolevocali.

IntroduzioneallinguaggioPython

41

Listeetuple

1.12. Listeetuple
Cometrattaresequenzedioggettivari.
Pythonmetteadisposizionestrumentipertrattaresequenzedioggettiqualsiasiinmodoana logoacometrattalestringhechesonosequenzedicaratteri.Glioggettilisteeletuplesonose quenzeordinatedialtrioggettichepossonoesserenumeri,stringheoanchelisteotuple.Una lista puesserecostruitaponendoglioggetti,separatidavirgole,traunacoppiadiparentesi quadre.Unatuplacostruitaponendoglioggetti,sempreseparatidavirgole,traunacoppiadi parentesitonde.Esempi: >>> >>> >>> 4 >>> 5 lista=[3, "pippo", ["sotto", "lista"], 3.14] tupla=(["multipli", "di", 7], 0, 7, 14, "ecc") print len(lista) print len(tupla)

Allaparolalistaassociataunalistadi4elementi:unintero,unastringa,unalistaeunnu meroinvirgolamobile.Allaparolatuplaassociataunatupladi5elementi:unalista,3in terieunastringa. Tuttoquellocheabbiamodettosullestringhecomesequenze,imetodiperestrarreelementio fette,valeancheperlelisteeperletuple.Ades.sevoglioestrarrel'ultimoelementodalista eitreinteridatuplapossoscrivere: >>> print lista[-1] 3.14 >>> print tupla[1:4] (0, 7, 14) Bisognaricordarecheintuttelesequenzel'indiceparteda0.Listeetuplesonomoltosimilitra diloro,ladifferenzapiuttostotecnica:lelistesonooggettimodificabilimentreletuple,come lestringhe,unavoltacreate,nonpossonoesseremodificate.Leoperazionichemodificanol'og gettopossonoesserecompiutesullelistemanonsustringheetuple.Nellelistepossibileeli minareunelementooinserirloinuncertopunto: >>> >>> [3, >>> >>> [3, del lista[1] print lista ['sotto', 'lista'], 3.1400000000000001] lista.insert(2, "Mario") print lista ['sotto', 'lista'], 'Mario', 3.1400000000000001]

42

Laboratoriodiinformatica

Listeetuple

Mal'operazionecheuseremopispessosarquelladicostruireunalistapartendodaunalista vuotaeaggiungendoelementiallafine. Adesempiosevogliounalistadinumeriquadratiincomincioassegnandoallaparolaquadratiunalistavuotaepoiinuncicloconilmetodoappendaggiungoallalistaquantiquadrati voglio: >>> quadrati=[] >>> for num in range(10): quadrati.append(num*num) >>> print quadrati [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] C'ancheunaltromodoperottenerelostessorisultatousandolasintassidellacostruzionedili ste.Adesempiosevogliounalistaconiprimi10numericubipossousareunmeccanismoana logoalprecedente,maconunascritturapisintetica. >>> cubi=[num*num*num for num in range(10)] >>> print cubi [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] Scriviamounprogrammachestampialcunidatistatisticisuinumericontenutiinunalista.La sommadeglielementidiunalistalasipuottenereinizializzandoa0unavariabileepoiag giungendo,aquesta,ognielementodellalista: def somma(lista): """Somma gli elementi di una lista di numeri.""" risultato=0 for n in lista: risultato+=n return risultato Realizzatalafunzionesomma,trovarelamediabanale: def media(lista): return somma(lista)/float(len(lista)) Sipossonorealizzarediversealtrefunzionistatisticheeunaprocedurachericevacomeparame trounalistaestampiirisultatidellefunzionistatistichecheabbiamocreato: def statistica(lista): print "La lista : %s" % lista print "Media dei valori: %s" % media(lista) print "Valore minimo %s" % minimo(lista) <F5>epoiinIDLElaproviamo:

IntroduzioneallinguaggioPython

43

Listeetuple

>>> statistica([23, 65, 73, 13, 33, 95, 47, 83, 72]) La lista : [23, 65, 73, 13, 33, 95, 47, 83, 72] Media dei valori: 56.0 Valore minimo 13

Riassumendo Lelisteeletuplesonocontenitoridioggetti.L'indicizzazioneel'affettamento,cheabbiamo vistoperlestringhe,funzionanoallostessomodopertuttelesequenze. Lelistesonosequenzemodificabili,letupleno. Ilmetodoappendpermettediaggiungereelementiallafinedelleliste.Lasintassi: <lista>.append(<oggetto>). InPythonesisteancheunasintassiparticolarepercostruireliste. Provatu 1. Scrivialtrefunzionistatisticheperlistedinumeri:massimo,scartoquadraticomedio, ... 2. Integraquestenuovefunzioninellaprocedurastatistica. 3. Scriviunafunzionechestampiglielementidiunalistaunosottol'altro. 4. Scriviunafunzioneche,dataunalistadinumerieunvalore,stampisoloinumeri maggioridiquelvalore. 5. Scriviunafunzioneche,dataunalistadinumerieunvalore,restituiscaunalistafor matasolodaglielementidellalistamaggioridiquelvalore.

44

Laboratoriodiinformatica

Ilciclowhile

1.13. Ilciclowhile
Comeripetereunciclounnumerodivoltenonpredeterminato.
Abbiamovistocomeripetereblocchidiistruzioni,maconl'istruzioneforilnumerodiripeti zionideveesserenotoprimacheiniziilciclo.Nonsemprecipossibile.Supponiamodivoler leggeredeinumeridallatastieraecontinuareafarlofinquandol'utentenonimmetteunnumero convenuto.Ilprogrammanonpusapere,all'iniziodelciclo,sel'utenteimmetter3,5o5000 numeri.Ilinguaggidiprogrammazionemettonoadisposizioneuncostruttochepermettediri solverequestoproblema:ilciclowhile.InPyhtonlasintassi: while <condizione>: <istruzioni> Scriviamolaproceduracheleggenumeriscrittidall'utente,necalcolalasomma,esiferma quandovieneimmessoilnumero0. Laproceduradeve: predisporrelavariabilecheconterrlasommainizializzandolaa0. eseguireuncicloincuileggeunnumeroeloaggiungeallasommafinquandoilnumero diversoda0. Unaprimaprocedurapotrebbeessere. def sommanumeri(): somma=0 while numero<>0: numero=int(raw_input("scrivi un numero: ")) somma+=numero print "la somma dei numeri immessi : %s" % somma Alcuneosservazioni: 1. somma=0 messoprimadelcicloaltrimentiverrebbecontinuamenteazzeratoenon memorizzerebbelasommadeinumeri. 2. L'istruzioneprintfuoridalciclowhileinfattinonindentatacomelealtreistru zionidelbloccodiwhile,quindiverreseguitaquandoilciclotermina. 3. Primadimettereinnumeroquellocheholettodallatastiera,devoconvertirloininte ro. Quandoproviamolaproceduraotteniamounerrore:

IntroduzioneallinguaggioPython

45

Ilciclowhile

Traceback (most recent call last): File "<pyshell#1>", line 1, in -toplevelsommanumeri() File "/sorgenti/while.py", line 9, in sommanumeri while numero<>0: UnboundLocalError: local variable 'numero' referenced before assignment Questomessaggiocidicechenellalinea9delfilewhile.py,all'internodellafunzionesommanumeri() e precisamente nell'istruzione while numero<>0:, Pyhton dovrebbe trovarequalcosadentrolavariabilenumero,variabilechenonancorastatadefinita,quindi nonsacomeandareavanti. Mettiamoinnumerounvaloreafantasia,bastachesiadiversada0altrimentiilciclononviene eseguitoneppureunavolta.Poiproviamolaprocedura: def sommanumeri(): somma=0 numero=2652 while numero<>0: numero=int(raw_input("scrivi un numero: ")) somma+=numero print "la somma dei numeri immessi : %s" % somma

>>> sommanumeri() scrivi un numero: 4 scrivi un numero: 5 scrivi un numero: 6 scrivi un numero: 0 la somma dei numeri immessi : 15 Funziona,manonscrittabene: 1. numerodeveessereinizializzatoconunnumerochepoinonvieneusato. 2. ilnumeroimmessoconvenzionalmenteperterminareilciclovieneusato.Finche0e fincheseguiamoaddizioni,nondfastidio,maseilnumeroconvenzionaleforre999o sestessimoeseguendomoltiplicazioni? Riporto,diseguitoduepossibilisoluzioni:

46

Laboratoriodiinformatica

Ilciclowhile

def sommanumeri2(): somma=0 numero=int(raw_input("scrivi il primo numero: ")) while numero<>0: somma+=numero numero=int(raw_input("scrivi un altro numero: ")) print "la somma dei numeri immessi : %s" % somma

def sommanumeri3(): somma=0 while True: numero=int(raw_input("scrivi un numero: ")) if numero==0: break somma+=numero print "la somma dei numeri immessi : %s" % somma Inquest'ultimocasolacondizionechecomandalaripetizionedelciclosempreveraquindiil ciclononterminanaturalmente,macontinuaall'infinito.All'internodelcicloc'perun'istru zionediselezioneche,incertecondizioni,seguel'istruzione break.L'istruzione break fa terminareimmediatamenteilcicloincuisitrova. Riassumendo Ilciclowhilepermettediripetereunbloccodiistruzionifinquandoveraunacertacondi zione.Lasintassi: while <condizione>: <istruzioni> Ilciclowhilesiusaquandoprimadiavviareilciclononpossibileconoscereperquante voltedovressereripetutoilbloccodiistruzioni. Incerticasicomodorealizzareuncicloinfinitoefarloterminarequandosideterminano determinatecondizioniconl'istruzionebreak.

IntroduzioneallinguaggioPython

47

Ilciclowhile

Provatu 1. Scrivilaprocedurachestampailprodottodinumeriimmessidall'utente. 2. Scrivilefunzionicherestituisconolasommaeilprodottodinumeriimmessidall'u tente. 3. Scrivilaproceduracheleggenumerifinquandosonomaggioridi0epoistampala media,ilmassimoeilminimodeinumeriimmessi.

48

Laboratoriodiinformatica

Funzioniricorsive

1.14. Funzioniricorsive
Funzionichedefinisconosstesse
Abbiamovistocheunavoltascrittaunafunzione,questapuesserechiamatadaaltrefunzioni. Illinguaggiocostruitoinmodotalecheunafunzionepuchiamareanchesstessa.Funzioni chechechiamanosstessesidiconoricorsive.AdesempiolascalinatadiGiacobbepuessere definitacomeunoscalinoseguitodaunascalinatadigiacobbe.InPython: def scalinata_di_Giacobbe(): print "Scalino" scalinata_di_Giacobbe() AprimavistasipotrebbepensarechequestaprocedurastampiunavoltaScalinooalmassi mo2volte,invececontinuaastampareScalinofinchc'memoriadisponibileovienepre mutoiltasto<Ctrl-c>. Comepotremmocostruireunascalapiumana?unascaladiuncertonumerodigradini?Prima discriverelaprocedura,scriviamoladefinizione: scala(n) = | se n=0 la scala gi finita | | se n>0 uno scalino seguito da una scala(n-1)

Utilizzandoilcomandoifsipucontrollarelafinedellavorodellaprocedura.Scriviamola proceduraeproviamoilsuofunzionamentoinIDLE: def scala(n): if n==0: return print "scalino" scala(n-1)

>>> scala(3) scalino scalino scalino Anchelaprocedurachestampaunaparolatriangolarepuessererealizzatausandolaricorsio ne:

IntroduzioneallinguaggioPython

49

Funzioniricorsive

def triangolo(s): if s=="": return print s triangolo(s[1:]) Diciamocheunaproceduraricorsivaterminalesenonvengonoeseguitealtreistruzionidopo lachiamataricorsiva.Leprocedurevistesoprasonoterminali. possibilecostruireanchefunzioniricorsive,chedianounrisultato.Moltedefinizioniaritmeti chesonoricorsiveepossonoesseretradottefacilmenteinfunzioniricorsive.Adesempiouna potenzachehaperesponenteunnumeronaturalepuesseredefinitainquestomodo:unnume roelevatoall'esponenteenneugualea1seenneugualea0altrimentiugualealnumeroper lapotenzachehaesponenteenne1.Scrittoinaltromodo: baseesp= | se esponente=0 allora la potenza 1 | | se esponente>0 allora la potenza base*baseesp-1

Ladefinizionepotrsembrarepiuttostostrana,matradottainlinguaggiodiprogrammazione funziona: def potenza(base, esponente): if esponente == 0: return 1 else: return base * potenza(base, esponente - 1) Altroesempio:ilfattorialedelnumeroenne1seilenne1,altrimentienneperilfattoriale dienne1: fatt. di n= | se n=0 allora il risultato 1 | | se n>0 allora il risultato n*fatt. di n-1

Un'altradefinizionericorsivainteressanteilmetododiEuclideperdeterminareilmassimoco munedivisoretraduenumeri: Seiduenumerisonougualiilmassimocomunedivisoreunodeidue,altrimentiilmassimo comunedivisoretrailpipiccoloeladifferenzatraiduenumeri: | se n1=n2 il risultato n1 macd(n1, n2)= | se n1>n2 il risultato macd(n1-n2, n2) | se n2>n1 il risultato macd(n2-n1, n1) Dataladefinizionericorsivadiunafunzione,lasuatraduzioneinlinguaggio Pythonrisulta moltosemplice.
50 Laboratoriodiinformatica

Funzioniricorsive

Riassumendo Leprocedurericorsiveconlacondizionediterminazionepermettonodiripeteredeiblocchi diistruzioni. Unaproceduraricorsivasidice terminalesenonvengonoeseguitealtreistruzionidopola chiamataricorsiva. Moltedefinizionimatematichepossonoessereespresseinformaricorsivaesonofacilmente traducibiliinPython. Ledefinizioniricorsivesonointeressantiperchrisolvonounproblemautilizzandoitermini delproblemastesso. Provatu 1. Cosasuccedesenellaproceduratriangoloscambitradilorol'istruzioneprintsela chiamataricorsiva?Primacercadiimmaginarlo,poicontrollascrivendoquest'altra proceduraeprovandola. 2. Scrivilefunzionicheproduconoilfattoriale,eilmassimocomundivisore. 3. Scriviunaproceduraricorsivachestampiunosottol'altroglielementidiunalista. 4. Scriviunafunzionericorsivachecalcolilasommadeinumericontenutiinunalista.

IntroduzioneallinguaggioPython

51

Fileditesto

1.15. Fileditesto
Comeleggereescriveresufileditesto.
Spessoiprogrammidevonoelaborareunanotevolemoledidati.Illuogomiglioredovememo rizzaredatineldiscosottoformadifile,ilprogrammadevedunqueessereingradodileggere escrivereinformazionisufile.Inunfileidatipossonoesserememorizzatiindiversimodi,noi vedremoifileditesto.Unfileditestomemorizzatosuldiscoconunsuonomeecontiene stringheseparateleunedallealtredasimbolidifinelinea. Proviamoarealizzareilgiocodellamaestra.Ilprogrammafadelledomande,leggelerispostee controllasesonogiusteomeno.Ledomandeelerispostelememorizziamoinunfileditesto: Io scrivo il nome di uno stato, tu devi scrivere il nome della capitale. Italia Roma Francia Parigi Gran Bretagna Londra ... Salviamoquestofileconilnomecapitali.dat. Alcuneosservazioni: 1. Hodecisochelaconsegnavienescrittainun'unicariga,laprima. 2. Nellerighesuccessivecisonoledomandeelerisposteseparatedauncaratterechenon deveesserepresentennelledomandennellerisposte,iohosceltoilcarattereditabu lazione. 3. Ilsempliceprogrammachescriveremononprevederighevuoteorighedicommento. 4. Ilfiledeveessereunfileditestosemplice,nondevecontenereinformazionirelativeal formato,masoltantocaratteriascii. Orascriviamoilprogrammacheleggeilfile: def gioco01(nomefile): file_dati=file(nomefile+".dat") dati=file_dati.readlines() print dati Oraabbiamounalistadistringhe,stampiamolaprimaeavviamounciclosullealtre.Inquesto ciclodobbiamospezzarelastringainduedovec'iltabulatore.Laprimaparteconterrlado mandaelasecondalasoluzione. Alcuneosservazioni: 1. Lafunzionerichiedecomeargomentounastringacontenenteilnomedelfilesenza estensione.
52 Laboratoriodiinformatica

Fileditesto

2. Nellaprimariga:alnomedelfilevieneaggiuntal'estensione: nomefile+".dat", poivienecreatounoggettofileassociatoalnomefile_dati. 3. Vengonolettetuttelesuelineeinunalistadistringhe: dati=file_dati.readlines() 4. L'ultimarigaservepervederecosaabbiamoeffettivamenteletto. def gioco02(nomefile): file_dati=file(nomefile+".dat") dati=file_dati.readlines() print dati[0] for linea in dati[1:]: ese=linea.split("\t") domanda=ese[0] soluzione=ese[1][:-1] print "%s --> %s" % (domanda, soluzione) Osservatechelasecondapartedellarigacontieneancheilcaratterediacapo:loeliminiamo, prima di associarlo alla variabile soluzione con l'istruzione: con l'istruzione: soluzione=ese[1][:-1].Convieneprovareilfunzionamentoinserendounbelprint... Oraaggiungiamolevariabilichepermettanodiconteggiarelerispostegiusteesbagliateeden tronelcicloilcodicechepongaladomandaememorizzilarisposta,chefacciailconfrontotra larispostaelasoluzione.Allafinedelciclocifacciamodirequanterispostegiusteesbagliate abbiamodatoefacciamoscriverequestainformazioneinunfileconlostessonomedeidati,ma conun'altraestensione: def gioco03(nomefile): file_dati=file(nomefile+".dat") dati=file_dati.readlines() giuste=0 sbagliate=0 print dati[0] for linea in dati[1:]: ese=linea.split("\t") domanda=ese[0] soluzione=ese[1][:-1] risposta=raw_input(domanda+" -> ") if risposta==soluzione: print "Giusto!"

IntroduzioneallinguaggioPython

53

Fileditesto

giuste+=1 else: print "Sbagliato, la soluzione :", soluzione sbagliate+=1 tot=giuste+sbagliate risultati="Hai dato %s risposte giuste su %s (%s%%)" \ % (giuste, tot, float(giuste)/tot*100) print risultati file(nomefile+".res", "w").write(risultati) Alcuneosservazioni: 1. Perscrivereinunfile,bisognaaprirloinscrittura,aggiungendo,l'argomentow. 2. Nell'ultimariga,vienecreatounoggettofileevienescrittalastringaalvolosenzausa revariabili. 3. Setentodiaprireinletturaunfileinesistente,ottengounerrore. 4. Seaproinscritturaunfileinesistente,vienecreato.Seesistegi,vienecancellatoilsuo contenuto. Riassumendo Ilcomandofilepermettediaprire,inletturaoinscritturaunfile,lasintassi: file(<nomefile>[, "w"]) Perleggeretuttounfileditestosipuusareilmetodo<file>.readlines()eperscri vereunastringainunfileditesto<file>.write(<stringa>). Provatu 1. Creaaltriesercizi. 2. Scriviunprogrammacheleggaunfileditestoenescrivaunaltroconlerighenume rate. 3. Scriviunprogrammacheleggaunfileenescrivaunaltrocrittografato.

54

Laboratoriodiinformatica

Dizionari

1.16. Dizionari
Comecollegarevaloriaglioggettiimmutabili.
Pythonmetteadisposizionedelprogrammatoreun'altrapotentestrutturadidati:idizionari. Assomiglianoalleliste,magl'indici,invecediesserenumerisuccessivisonooggettiimmutabili qualunque,possonoesserenumeri,stringheotuple. >>> >>> >>> >>> >>> {1: d={} # 1 d[1]="pippo" # 2 d["gigi"]="pluto" # 3 d[(2,6)]="paperino" # 4 print d 'pippo', (2, 6): 'paperino', 'gigi': 'pluto'}

Alcuneosservazioni: 1. dvieneassociatoaundizionariovuoto. 2. alnumero1vieneassociatoilvalore"pippo" 3. allastringa"gigi"vieneassociatoilvalore"pluto" 4. allatupla(2, 6)vieneassociatoilvalore"paperino" 5. Idizionarimantengonoleassociazionichiavevalore,nonl'ordinedeglielementi. possibileottenereilvaloreassociatoadunacertachiaveomodificarlousandolasintassidel l'indicizzazione: >>> print d["gigi"] pluto >>> d["gigi"]="clarabella" >>> print d["gigi"] clarabella Sipuottenerelalistadituttelechiavidiundizionarioconilmetodo<dict>.keys(): >>> print d.keys() [1, (2, 6), 'gigi'] Cercarediottenereilvalorecollegatoadunachiavenonesistenteneldizionariosollevauner rore: >>> print d["mario"] [...]KeyError: 'mario' Laclassedictmetteadisposizioneduemetodichepermettonoditrattareilcasodichiavinon
IntroduzioneallinguaggioPython 55

Dizionari

presentineldizionario.Ilmetodo<dict>.get(<chiave>[, <valore>])restituisceil valorecollegatoallachiavesequestaesiste,altrimentirestituisceilvaloredidefault,nonmodi ficaildizionario: >>> print d.get("gigi", "clarabella") pluto >>> print d.get("mario", "clarabella") clarabella >>> d {1: 'pippo', (2, 6): 'paperino', 'gigi': 'pluto'} Ilmetodo<dict>.setdefault(<chiave>[, <valore>])restituisceilvalorecolle gatoadunacertachiave,ma,senonesiste,creaunelementoconquellachiaveeilvalorepas satocomesecondoargomento. >>> print d.setdefault(1, "clarabella") pippo >>> d {1: 'pippo', (2, 6): 'paperino', 'gigi': 'pluto'} >>> print d.setdefault(2, "clarabella") clarabella >>> d {1: 'pippo', 2: 'clarabella', (2, 6): 'paperino', 'gigi': 'pluto'} Sevogliamocontaretutteleparolepresentiinuncertotesto(iohoscaricatodaInternetbibbia.txt),possiamo: 1. predisporreundizionariovuoto, 2. perognilineadeltesto: 1. spezzarelalineainunalistadiparoleeperogniparola: 1. aumentare di 1 il contatore di quella parola (partendo dal valore 0 se non esiste). 3. estrarretuttelechiaviemetterleinordine,cospicomodoricercareunaparola, 4. stamparelecoppieparola,numerodioccorrenze. L'algoritmositraducefacilmenteinPython:

56

Laboratoriodiinformatica

Dizionari

def contaparole(nomefile): contatore = {} for linea in file(nomefile): for parola in linea.split(): contatore[parola]=1+contatore.get(parola, 0) parole = contatore.keys() parole.sort() for parola in parole: print "%25s: %s" % (parola, contatore[parola]) Percontareleoccorrenzedelleparoledellabibbiaimpiegaunafrazionedisecondo,poiimpie gaqualcheminutoperstamparletutte. Riassumendo Undizionariovuotorappresentatodaunacoppiadiparentesigraffe. Undizionariounacontenitorecheassociaoggetti(valori)aoggettiimmutabili(chiavi). Neidizionarinonmantenutol'ordinedeglielementi,masolol'associazionechiavevalore. possibileottenerelalistadellechiavidiundizionarioconilmetodo<dict>keys(). Sipuaccedereadunvaloreusandol'indicedeldizionario:<dict>.[<chiave>]. Si pu creare un elemento assegnando un valore a una chiave: <dict>. [<chiave>]=<valore>. iduemetodi: <dict>.get(<chiave>[,<valore>]), <dict>.setdefault(<chiave>[,<valore>]), permettonoditrattareinmodouniformeicasiincuinonsappiamoseesisteunelementocon unacertachiave. Provatu 1. Modificacontaparole()inmodochestampiglielementidalpifrequentealpi raro. 2. Inserisciunfiltroinmodochelapunteggiaturaelemaiuscolenonabbianoinfluen zaneiconteggi.

IntroduzioneallinguaggioPython

57

Laprogrammazioneorientataaglioggetti

1.17. Laprogrammazioneorientataaglioggetti
Comedefinireeusareunanuovaclassedioggetti.
ParlandodeidatiPythonhospessousatoiltermineoggetto.Ilterminenoneracasuale,tutto inPythonunoggetto.Glioggettisonodelleentitformatedadatiealgoritmistrettamente collegatitradiloro.Idatidell'oggetto,cherappresentanoilsuostato,sonodettiattributi,glial goritmichepermettonodifarfunzionarel'oggettosonodettimetodi.Ingeneralechiusaunog gettonondevesaperecomeorganizzatoalsuointerno,qualisonoisuoiattributiequalialgo ritmilofannofunzionare,madevesoloconoscerelasuainterfaccia,cioimetodichepermet tonoall'oggettodiinteragireconglialtrioggetti.Glioggettisonoelementidiunaclasse:una stringaunoggettodellaclassestr,unaparticolarelistaunoggettodellaclasselist,... Nellaprogrammazioneorientataaglioggetti,unapartedellavoroconsisteneldefinireleclassi. Unacaratteristicaimportantedelleclassiquelladiereditaredaaltreclassiattributiemetodi. Inquestomodosipossonoavereinterefamigliediclassiimparentatetradiloro. Comeesempiocostruiremolaclassedellefrazionifacendoladerivaredallaclassemadreditutte leclassi: object.Ilprimometodocheforniremoallaclassesarilmetodo__init__(...)che vienechiamatoquandosicreaunnuovooggettodiquestaclasse: class Frazione(object): def __init__(self, num, den): self.num=num self.den=den Alcuneosservazioni: 1. LaprimarigadichiarachestiamodefinendounaclassechesichiamaFrazioneeche discendedallaclasseobject. 2. Tuttaladefinizionedellaclassedeveessereindentata. 3. Ilmetodo __init__ haunprimoparametroconvenzionalmenteindicatocon self checontieneilriferimentoalparticolareoggetto.Poialtridueparametriicuivalori vengonoassociatiagliattributiself.numeself.den. CreiamoilnostroprimooggettodellaclasseFrazione: >>> f1=Frazione(4, 6) >>> print f1 <__main__.Frazione object at 0xb6e00bec> Funziona,manoncidicemolto...Aggiungiamounaltrometodoconunnomeconvenzionale:il metodo __str__ verrchiamatotuttelevoltecisarlanecessitdiconvertireFrazionein

58

Laboratoriodiinformatica

Laprogrammazioneorientataaglioggetti

stringa: def __str__(self): return "%s/%s" % (self.num, self.den)

>>> f1=Frazione(4, 6) >>> print f1 4/6 Ilrisultatogipicarino!Laprimaoperazionechecihannoinsegnatoaeseguireconlefra zionilariduzioneaiminimitermini.Perfarloabbiamoperbisognodiunafunzioneche,dati duenumerirestituiscailmassimocomundivisore(abbiamogiincontratoun'implementazione diquestafunzione)emodifichiamoancheilmetodo__init__inmodochedopoaverdefini toilnumeratoreeildenominatoreriducaaiminimiterminilafrazione: def __init__(self, num, den): self.num=num self.den=den self.riduci()

def riduci(self): def macodi(a, b): while a<>b: if a>b: a-=b else: b-=a return a d=macodi(self.num, self.den) self.num/=d self.den/=d

>>> f1=Frazione(4, 6) >>> print f1 2/3 Aggiungiamoimetodiperaddizionareemoltiplicarelefrazioni: def __add__(self, altra): return Frazione(self.num*altra.den+self.den*altra.num, self.den*altra.den)

IntroduzioneallinguaggioPython

59

Laprogrammazioneorientataaglioggetti

def __mul__(self, altra): return Frazione(self.num*altra.num, self.den*altra.den)

>>> >>> >>> f1, 1/2

f1=Frazione(3, f2=Frazione(4, print "%s + %s f2, f1*f2) + 2/5 = 9/10;

6) 10) = %s;

%s * %s = %s" % (f1, f2, f1+f2,

1/2 * 2/5 = 1/5

Alcuneosservazioni: 1. All'internodelmetodoriducidefinitalafunzionemacodi(a, b),effettivamen teservesoloperridurreaiminimiterminiequindinonnecessariochesiavistadall'e sterno. 2. Imetodi__add__e__mul__nohannobisognodiridurreaiminimiterminiperch questovienefattoalmomentodellacrazionediunanuovafrazione. 3. Imetodi__add__e__mul__vengonochiamatiquandoinun'espressionedeveesse reeseguital'addizioneolamoltiplicazionetradueoggettidiquestaclasse. Riassumendo L'istruzioneclasspermettedicreareunanuovaclasse. Unaclasseformatadall'unionedidati,gliattributiealgoritmi,imetodi. Unmetodoparticolare__init__chevieneeseguitoquandovienecostruitol'oggetto. Ilmetodo__str__vieneeseguitoquandol'oggettodeveessereconvertitoinstringa. Provatu 1. Laclasseprecedentenonfunzionaseunodeitermini0,risolviquesticasi. 2. Aggiungiimetodipereseguiresottrazioniedivisioni.

60

Laboratoriodiinformatica

Numeri

2. Numeri
Inquestasezionesonopresentatideiproblemisignificatividarisolverecon Python puroo conl'aggiuntadellalibreriamath.Peraffrontareiproblemiseguentibisognaconoscerealcuni argomentipresentatinellasezioneprecedente.

Numeri

61

Numeri

62

Laboratoriodiinformatica

Operazioni

2.1. Operazioni
Cosapufareuncalcolatorechesasoloaggiungereotogliereuno Prerequisiti funzioniconparametri, funzionicherestituisconounvalore, strutturadiiterazione:while, Argomentitrattati concettiprimitividell'aritmetica, algoritmi, grafielinguaggio cicli.

Problema SecondoillavorodiPeanotuttal'aritmeticapuesserederivatada3ideeprimitive: 1. zero 2. numero(naturale) 3. successore eda5proposizioniprimitive: 1. Zerounnumero. 2. Ilsuccessorediogninumerounnumero. 3. Duenumerinonpossonoaverelostessosuccessore. 4. Zerononilsuccessoredialcunnumero. 5. Selozerohaunaproprieteperogninumerocheabbiaquellaproprietancheilsuo successorelahaalloratuttiinumerihannoquellapropriet. Tuttal'aritmeticapuquindiesserederivatadaquestitreconcettiprimitiviedaquestepoche proposizioni.Inparticolarelaquintaproposizionedettaancheprincipiodiinduzioneestaalla basedelledefinizioniricorsive. IspiratidaPeano,ciponiamoilproblemadistabilirequalisianoleoperazioniminimecheun calcolatoredevesaperfareperimplementarel'aritmeticadeinumerinaturali. Soluzione Lasoluzionenonunica,possiamopartiredaunesecutorechesappia: 1. leggeredati, 2. confrontareunnumerocon0, 3. aggiungere1aunnumero, 4. togliere1aunnumero, 5. ripeteredelleistruzionifinquandoveraunacertacondizione,
Numeri 63

Operazioni

6. restituireunrisultato, 7. (perladivisione)eseguireporzionidiversedicodiceasecondadelrisultatodiunacon dizione. UsandoillinguaggioPython: 1. Perleggereidatipossiamousareilmeccanismodelpassaggiodiargomentiadunafun zionedotatadiparametri. 2. Perconfrontareilnumeroncon0possiamousareleespressioni:n>0,n>=0on==0. 3. Peraggiungere1aunnumerocontenutonellavariabilenpossiamousareapiacerel'i struzione:n=n+1oppurelapisintetican+=1,deltuttoequivalenti. 4. Inmodoanalogopertogliere1possiamoscriveren=n-1on-=1. 5. Perripeteredeicomandipossiamousarel'istruzione while <condizione>: <blocco di istruzioni>. 6. Perrestituireunrisultatousiamol'istruzionereturn. 7. Pereseguirediverseporzionidicodice: if <condizione>: <blocco di istruzioni> else: <blocco di istruzioni> Scriviamodellefunzionicherealizzinolequattrooperazionieilconfrontodinumeri.Iniziamo dall'addizione.Peraddizionareduenumericontenutiinn1en2possotrovareilsuccessoredi n1tantevoltequantocontenutoinn2.Possiamodescriverecosl'algoritmo: definisci la somma di n1 e n2 cos: finquando n2 maggiore di 0: aumenta di 1 n1 e diminuisci di 1 n2 alla fine, il risultato contenuto in n1 LatraduzioneinPythonnondovrebbepresentaregrandidifficolt.Aggiungiamoinfondoal filediprogrammaunaproceduratesteuncomandochevieneeseguitoquandovieneeseguitoil filecomeprogramma: def test(): t=[(4, 5), (5, 4), (367, 1), (1, 754), (0, 25), (36, 34), (56, 0), (20, 4), (4, 20), (243, 243), (0, 0), (1, 1)] for a, b in t: print "%s+%s=%s" % (a, b, somma(a, b)) if __name__=="__main__": test()
64 Laboratoriodiinformatica

Operazioni

Provatu 1. ScrivilafunzionePythonchedefiniscalasommadiduenumerinaturali. 2. Provailprogrammaverificandochefunzionicorrettamente 3. Scrivi,inlinguaggionaturale,ladefinizionedidifferenza. 4. Aggiungiiltestperladifferenza. 5. Scrivilafunzionechecalcolaladifferenza. Perrealizzarelafunzioneprodotto,usandoilmetododelleaddizioniripetute,avremobisogno diunavariabilelocalechecontengalesommeparziali.Ladescrizionedell'algoritmopotrebbe essere: definisci il prodotto di n1 e n2 cos: in s metti zero fin quando n2 maggiore di 0: in s metti la somma di s e n1 diminuisci di 1 n2 alla fine, il risultato contenuto in s Provatu 6. Aggiornalaproceduratest(). 7. Scrivilafunzionechecalcolailprodotto. 8. Verificachelafunzionisicomporticorrettamente. Perimplementarecorrettamentelafunzionequoziente,dobbiamousareun'altraistruzionePython:l'istruzioneif.Infattinonsemprepossibileeseguireledivisionitranumerinaturali, nondefinitaunadivisioneconildivisoreugualeazero.Quindilafunzionequoziente,prima diprocederedevecontrollareilvaloredelsecondonumeroeterminareconunmessaggiodier roreseugualeazero. Provatu 9. Scrivi,inlinguaggionaturale,ladefinizionediquoziente(parteinteradelquoziente). 10. Scrivilafunzionechecalcolailquozienteinterodiduenumerieaggiornalaprocedu ratest(). Altracaratteristicaimportantedeinumeriilfattochepossonotuttiessereconfrontatitradi loro.Usandolesoliteistruzionipossiamorealizzareletrefunzionidiconfronto:maggiore,mi nore,uguale.Cisonodiversimodiperrealizzarle,unoquesto:
Numeri 65

Operazioni

definisci maggiore n1 di n2 cos: fin quando n2 maggiore di 0: diminuisco sia n1 sia n2 di 1 alla fine, il risultato equivalente a in n1>0 Provatu 11. Scrivilafunzionemaggiorecherealizzaladescrizionedatasopraerestituisceilvalo reTrueseilprimonumeromaggioredelsecondo,Falsenelcasocontrario. 12. Scriviladescrizioneinlinguaggionaturaledellefunzioniminoreeuguale. 13. Scrivilefunzioniminoreeugualecheconfrontanoduenumerinaturalierestituisco noilvaloreTrueoFalse.Aggiornalaproceduraditest. Proviamoadaffrontareilproblemaconunapprocciodiverso,chiudiamoquestofileeapriamo neunonuovo. Seilnostroesecutoreingradodigestirefunzioniconparametricherestituisconovalori,pos siamofareamenodell'istruzionewhileeusarelaricorsione.Abbiamogiosservatocomeil principiodiinduzionesiavicinoalmeccanismodellaricorsione,oravedremocomescrivere delledefinizioniricorsiveetradurleinfunzioni. Unadefinizionericorsivadefiniscequalcosaneiterminidellacosastessa.Nonsempreledefini zioniricorsivefunzionano,perchsianoaccettabilibisognachetrasforminouncasoinuncaso pisempliceeabbianounacondizionediterminazione.Adesempio: addizionareiduenumeri6e3equivalenteadaddizionare7e2questoequivalenteadaddi zionare8a1equestoequivalenteadaddizionare9a0.Sipuosservarecheilsecondoad dendodiventasemprepipiccolo,ilproblemadiventapisemplice.Lacondizioneditermina zioneinquestocaso:lasommadiunnumerocon0ilnumerostesso.nelcasogeneralepos siamodescrivereladefinizioneinquestomodo: | n1 se n2=0 somma di n1 e n2 | | altrimenti somma di (n1+1) con (n2-1) LatraduzioneinPythonpressochletterale: def somma(n1, n2): """somma(n1, n2) -> restituisce la somma n1+n2.""" if n2==0: return n1 return somma(n1+1, n2-1) Possiamoosservarecheleduerighedelladefinizionesisonotradotteinduerighedellafunzio ne.Laprimarigadellafunzioneuncommentoutilecomedocumentazione.Scrivianchela

66

Laboratoriodiinformatica

Operazioni

proceduraditestecontrollailfunzionamentocorrettodellafunzione. Seproviquestafunzioneconnumerimoltograndi,Pythonterminaconunerroreperchnon ingradodigestiretroppefunzioniricorsiveannidateunaall'internodell'altra. Riassumendo UnCalcolatorepuimplementaretuttal'aritmeticapartendodapochesemplicioperazioni. Iconcettidisuccessore,predecessore,confrontoconzeroeiterazionepermettonodirealiz zarel'addizione,lasottrazione,lamoltiplicazioneelapotenza. Perrealizzareladivisionedobbiamoanchecontrollarecheildivisoresiadiversodazero. Lestessesemplicioperazionipermettonodirealizzareancheilconfrontotranumeri. Leoperazionieilconfrontopossonoancheesseredefinitiinmodoricorsivo. Ledefinizioniricorsiverisultanomoltosintetiche,edespressive. faciletradurredefinizioniricorsiveinfunzioniequivalenti. IllinguaggioPythonnontrattalefunzioniricorsiveinmodomoltoefficiente,altrilinguag gilofannomoltomeglio.

Provatu 14. Scrivilaproceduraditesteverificachesomma(n1,n2)diarisultatiesatti. 15. Scriviladefinizioneelafunzionericorsivadidifferenzaeprovala. 16. Scriviladefinizioneelafunzionericorsivadiprodottoeprovala. 17. Scriviladefinizioneelafunzionericorsivadiquozienteeprovala. 18. Scriviladefinizioneelafunzionericorsivadidifferenzaeprovala. Puoiandareoltre 19. Scriviledefinizionielefunzioniricorsivedimaggiore,minoreeuguale. 20. Aggiornalaproceduraditesteverificaindiversicasilacorrettezzadellefunzioni scrittesopra. 21. Scriviladefinizioneelafunzioneiterativadipotenzaeprovala. 22. Scriviladefinizioneelafunzionericorsivadipotenzaeprovala. 23. Scrivilafunzionecherestituisceilrestodiunadivisione. 24. Scrivilafunzionecherestituiscequozienteinteroerestodiunadivisione.

Numeri

67

Operazioni

68

Laboratoriodiinformatica

Arraydiinteri

2.2. Arraydiinteri
Cosafareconvettoridinumeriinteri.
Prerequisiti funzioniconparametri, funzionicherestituisconounvalore, strutturadiselezione:if, strutturadiiterazione:for, Sequenzedidati:liste. Argomentitrattati Letturadinumeridatastiera, inizializzazionediunalistaconvaloricasuali, sommadiunasequenzadinumeri, ricercadelminimo, verificadellapresenzadiunelementoinunasequenza, ordinamentodiunasequenza.

Problema Leggerenumerieinserirliinunalista,visualizzareinumericontenutiinunalista,svolgereal cuneoperazionidibasesuunalistadiinteri:somma,prodotto,ricercadelminimo,ricercadel delmassimo,ordinamento. Soluzione Unastrutturadidatiimportanteininformaticacostituitadagliarray.Gliarraysonosequenze indicizzabilidielementi.InPythongliarraypossonoessereemulatidall'oggettolistelosi pucostruireracchiudendotraparentesiquadreunasequenzadioggettiseparatidavirgole: >>> a=[1, 3, 5, 7, 9, 11] Dopoquestocomando,l'oggettoacontieneiprimi6numeridispari.Sipuottenerel'ennesimo elementodiunalistascrivendoilnomedellalistaseguitodall'indicepostotraparentesiquadre. InPython,ilprimoelementodiognilistahasempreindice0. >>> print a[0] 1 >>> print a[3] 7

Numeri

69

Arraydiinteri

Ciproponiamodiscriverealcunefunzionidibaseperl'elaborazionedellelistedinumeri.Per incominciareciserveunafunzionecherestituiscaunarray,dinumeriinteri,lettodatastiera.La funzionedevecontinuarealeggerenumerifnquandovieneintrodottounvaloreparticolaredetto sentinella. Inmetalinguaggio: per leggilistainteri(sentinella) fa: prepara una lista vuota avvia un ciclo infinito che: leggi un valore se uguale alla sentinella: termina il ciclo altrimenti: aggiungi il valore alla lista restituisci la lista. Possiamopartire:menu File - New Window,soliteintestazioni,menu File - Save. Scriviamoquestaprimafunzione: import random def leggilistainteri(sentinella="0"): result=[] while True: e=raw_input("introduci un numero (%s per finire): " % sentinella) if e==sentinella: break else: result.append(int(e)) return result Alcuneosservazioni: 1. Ilcomandoimport randomservirperlaprossimafunzione,maiopreferiscomet terloall'iniziodelprogramma. 2. Ilparametrosentinellahacomevaloredidefault0.civuoldirecheleduechiamate difunzioneseguentisonoequivalenti: leggilistainteri() leggilistainteri( 0 ) 3. QuandoPythonincotrailcomandobreakescedalciclo,questopermettedieseguire unciclowhile True:chealtrimentisarebbeinfinito. Perleproveseguentisarutileavereunafunzionecherestituiscaunalistadiennevaloricasua li.

70

Laboratoriodiinformatica

Arraydiinteri

per listacasuale(n, mi=0, ma=100) fa: prepara una lista vuota per n volte: aggiungi alla lista un numero casuale tra mi e ma restituisci la lista. Questavolta,poichilnumerodielementiginotoprimadiavviareilciclo,convieneusare unciclofor: def listacasuale(n, mi=0, ma=100): result=[] for i in xrange(n): result.append(random.randrange(mi, ma)) return result primadiprocedereconvieneverificareleduefunzioni.<F5>perfarvalutareaPythonilno stroprogramma,poinell'ambienteIDLEproviamoleduenuovefunzioni.Nelmiocaso,dopo lacorrezionediunpo'dierrori,hannomostratoilseguentefunzionamento: >>> a=leggilistainteri() introduci un numero (0 per finire): 34 introduci un numero (0 per finire): 65 introduci un numero (0 per finire): 2 introduci un numero (0 per finire): 0 >>> a [34, 65, 2] >>> b=listacasuale(10) >>> b [20, 1, 88, 77, 25, 62, 43, 60, 20, 42] >>> b=listacasuale(10, 0, 1000) >>> b [117, 266, 960, 567, 39, 122, 581, 289, 759, 73] Bene,messiapuntoquestiduestrumenti,passiamoarisolverealcunitipiciproblemisuivettori dinumeri.Ilprimoconsisteneltrovareilminimovalorecontenutonell'array.Iltruccoconsiste nelfarfintacheilminimosiailprimoelementoe,poi,confrontarequestovaloreconglialtri cambiandolosesenetrovaunopipiccolo.Inmetalinguaggio: per minimo(lista) fa: metti in minimo il primo elemento della lista per ogni elemento della lista: se l'elemento pi piccolo del minimo metti in minimo l'elemento restituisci il minimo.

Numeri

71

Arraydiinteri

Latraduzionerisultaabbastanzasemplice:ricordiamocidimettereunastringadicommento comeprimarigadellafunzione: def minimo(lista): """Restituisce l'elemento minimo di una lista.""" mi=lista[0] for e in lista: if e<mi: mi=e return mi Inqualche(raro)casopuinteressarenonl'elementominimo,malaposizionedell'elemento minimo.Lafunzioneinquestocasounpo'picomplicataperchdobbiamoconfrontaregli elementidellalista,madobbiamomemorizzareerestituireunindice.Inmetalinguaggio: per indiceminimo(lista) fa: metti in minimo il primo indice della lista (0) per ogni indice della lista: se (l'elemento con questo indice pi piccolo dell'elemento che ha per indice minimo) allora: metti in minimo questo indice restituisci il minimo. Accidenti,pidifficiledascrivereinmetalinguaggiocheinPython: def indiceminimo(lista): """Restituisce l'indice dell'elemento min. di lista.""" indmin=0 for indice in range(len(lista)): if lista[indice]<lista[indmin]: indmin=indice return indmin Provatu 1. Eseguiilnuovoprogramma,poinell'ambienteIDLE,provaatrovareilminimodiun arrayconvaloriintrodottidatastieraeconvalorigeneraticasualmente. 2. Aggiungilafunzionemassimo(lista)eprovala. 3. Aggiungilafunzioneindicemassimo(lista)eprovala. Un'altrafunzioneutilequellachecalcolalasommadeglielementidiunalista:

72

Laboratoriodiinformatica

Arraydiinteri

per somma(lista) fa: poni a 0 la somma parziale per ogni elemento della lista: aggiungi il suo valore alla somma parziale restituisci la somma parziale che, ora, il totale. LatraduzioneinPythonnonpresentasorprese: def somma(lista): """Restituisce la somma degli elementi di una lista.""" somma=0 for elemento in lista: somma+=elemento return somma Provatu 4. Verificailfunzionamentodisomma(lista)convaloriimmessidatastiera. 5. Scriviunafunzionecherestituiscaiprimiennenumerinaturali. 6. Scriviunafunzionecherestituiscalasommadeiprimiennenumerinaturali,numeri triangolari. 7. Scriviunafunzionechecalcoliilprodottodeglielementidiunalista. 8. Scrivilafunzionechecalcoliilprodottodiennenumerinaturaliapartireda1(fatto riale). 9. Scrivilafunzionechecalcolilamediadeglielementidiunarray. 10. Calcolalamediadeiprimi10,100,1000,...numerinaturali. 11. Calcolalamediadiarraycasualidi10,100,1000,...elementi. Avolteutileunafunzionechecontrollaseuncertoelementocontenutooppurenoinunar ray,oppurechecirestituiscel'indicediundeterminatoelemento.Duefunzionicherisolvono questiproblemipossonoesserescrittecos: def appartiene(elemento, lista): """Restituisce True se elemento appartiene a lista.""" for e in lista: if e==elemento: return True return False

Numeri

73

Arraydiinteri

def indicedi(elemento, lista): """Restituisce l'indice della prima occorrenza di elemento in lista, retituisce -1 se l'elemento non presente nella lista.""" for ind, ele in enumerate(lista): if ele==elemento: return ind return -1 Alcuneosservazioni: 1. Ilcomandoreturnterminailciclo,lafunzioneerestituiscecomerisultatoilvalore chelosegue. 2. Poichgliindicidegliarrayinizianoda0,perindicarecheunelementononpresente nell'arraypossiamousareunnumeronegativo. 3. Lafunzioneenumeraterestituiscelecoppieformatedaunindiceeilcorrispondente elemento. 4. Lafunzioneindicedirestituiscel'indicedelprimoelementougualeaquellocercato presentenell'array. Perprovarelefunzioniappenaaggiunte,possiamocreareunalistaechiamarlecondiversiargo menti: >>> a=[3,6,2,8,6,4,1] >>> print appartiene(6, a) True >>> print appartiene(23, a) False >>> print indicedi(4, a) 5 >>> print indicedi(6, a) 1 Unaltroimportanteproblemarelativoagliarrayquellodell'ordinamento.siparteconunarray disordinatoesivuoleottenereunoordinato.unproblemaimportante,perchfacilescrivere algoritmipocoefficienti,maquelliefficientirisultanopiuttostocomplicati.Neiproblemipratici faciledoverordinarearraydimigliaiaomilionidielementiequindinonsecondarioaverea disposizioneunalgoritmopiefficiente. Possiamorealizzareunaprimasoluzionenellaqualelafunzionecercal'elementopipiccolo dellalista,lotoglieelometteinfondoadunanuovalista,procedendocosfinquandolaprima listavuota.Perquestafunzioneuseremounaltrometododelleliste,metodocherestituisceun elementotogliendolodallalista:<lista>.pop(<indice>):

74

Laboratoriodiinformatica

Arraydiinteri

per insertionsort(lista) fa: il risultato la lista vuota finquando la lista di partenza non vuota: trova l'indice dell'elemento minimo togli questo ele. dalla lista e mettilo nel risulato restituisci il risultato InPython: def insertionsort(lista): """Rest. una lista con gli ele. di lista ordinati.""" elementi=lista[:] result=[] while elementi!=[]: im=indiceminimo(elementi) result.append(elementi.pop(im)) return result Ilbubblesortconfrontaognielementocontuttiquellicheloseguonoscambiando,glielementi quandononsonoinordine.Questafunzionenonproduceunnuovoarraydisfandoquellodato comeargomento,maordinadirettamentel'arraypassatocomeargomento. def bubblesort(lista): """Ordina "sul posto" una lista.""" for i in xrange(len(lista)-1): for j in xrange(i+1, len(lista)): if lista[j]<lista[i]: lista[j], lista[i] = lista[i], lista[j]

Riassumendo Quandosidevonoelaboraredegliarrayspessosiusailcicloforapplicatodirettamenteagli elementidell'array. Lefunzionicheabbiamoscrittofornisconodeglistrumentidibaseutilissimiintuttiipro grammicheoperanoconarray.SonocosutilichePythonlefagituttesenzabisognodi programmarle...ilcomandohelp(list)cimostratuttoquellochelelistesannogifare senzabisognodelnostrointervento.Comediconoglihackerduesettimanedisperimenta zioneinlaboratoriopossonofarrisparmiareduebuoneoredistudiodeimanualiinbibliote ca...

Numeri

75

Arraydiinteri

Provatu 12. Verificalacorrettezzadellefunzionidiordinamentocondiverseliste.Ilmeccanismo concuisonocostruitemoltodiverso,laprimadistruggelalistapassatacomeargo mentoenecostruisceun'altra,lasecondamodificalalistapassatacomeargomento. 13. Provaleduefunzioniprecedenticonarraydilunghezzediverseecronometraitempi diesecuzione. 14. Scriviunafunzionecheleggaunarraydistringhe. 15. Qualidellefunzioniprecedentigiranoancheconarraydistringhe? 16. Scriviunprogrammacheusilefunzioniscritteinquestaunitperintrodurreunarray dinumeri,estamparneilminimo,ilmassimo,lamediaeladeviazionestandard. Puoiandareoltre 17. Inunarrayordinatolaricercadiunelementopuesseremoltopiefficiente,ricerca chemetodisipossonousareeimplementaliinPython. 18. Gli algoritmi di ordinamento proposti non sono affatto efficienti. Aggiungi delle istruzionipercontareilnumerodiconfrontiediassegnazionichevengonofattiper ordinareunarraydienneelementi. 19. TrovaaltrialgoritmidiordinamentoeimplementaliinPython.

76

Laboratoriodiinformatica

Criterididivisibilit

2.3. Criterididivisibilit
DovesiinsegnaaPythonautilizzareicriterididivisibilit.
Prerequisiti funzioniconparametri, strutturadiselezione:if..else, strutturadiiterazione:while, dati:numeri,stringheeliste. Argomentitrattati icriterididivisibilit, conversionidanumeroastringaeviceversa, costruzionediliste, ricorsione.

Problema Scrivereunalibreriadifunzionicheimplementiicriterididivisibilitdeinumerinaturali.La funzionediv2(n)deveverificarecheilnumeronsiadivisibileper2erestituireTruesenpari eFalsesenonlo.Devopoterdareiseguenticomandiottenendolerispostecorrette: >>> print div2(5) False >>> print div2(613264) True >>> print div5(64343) False ...

Soluzione Ovviamenteperprimacosabisognaconoscereicriterididivisibilit,neriporto,diseguitouna possibiledefinizione,ilibrilispieganomoltomeglio... Divisibilitper2: iseguentinumerisonodivisibiliper2:0,2,4,6,8, unnumerodivisibileper2selasuaultimacifraunnumerodivisibileper2. Divisibilitper4: iseguentinumerisonodivisibiliper4:0,4,8,12,16, unnumerodivisibileper4seloancheilnumerochesiottienetogliendo20


Numeri 77

Criterididivisibilit

unnumerodivisibileper4selesueultime2cifreformanounnumerodivisibileper4. Divisibilitper8: iseguentinumerisonodivisibiliper8:0,8,16,24,32 unnumerodivisibileper8seloancheilnumerochesiottienetogliendo40 unnumerodivisibileper8selesueultime3cifreformanounnumerodivisibileper8. Divisibilitper5: iseguentinumerisonodivisibiliper5:0,5, unnumerodivisibileper5selasuaultimacifraunnumerodivisibileper5. Divisibilitper25: iseguentinumerisonodivisibiliper25:0,25,50,75, unnumerodivisibileper25selesueultime2cifreformanounnumerodivisibileper25. Divisibilitper10: unnumerodivisibileper10selasuaultimacifra0. Divisibilitper100: unnumerodivisibileper100selesueultime2cifreformanoilnumero0. Divisibilitper3: iseguentinumerisonodivisibiliper3:0,3,6,9, unnumerodivisibileper3selasommadellesuecifreunnumerodivisibileper3. Divisibilitper9: iseguentinumerisonodivisibiliper9:0,9, unnumerodivisibileper9selasommadellesuecifreunnumerodivisibileper9. Divisibilitper11: iseguentinumerisonodivisibiliper11:0,11, unnumerodivisibileper11seladifferenzadellasommadellesuecifredipostopariela sommadellesuecifredipostodispariunnumerodivisibileper11. Divisibilitper7: iseguentinumerisonodivisibiliper7:0,7, unnumerodivisibileper7seladifferenzatradoppiodell'ultimacifraeilnumeroformato dallealtrecifreunnumerodivisibileper7. Tutteledefinizionidatesoprasonoricorsive,malefunzionichefaremononutilizzerannoque statecnica.Ilcriteriopisemplicequellodelladivisibilitper2,semplice,marichiededi poterestrarredaunnumero,ilnumeroformatodallasuaultimacifra.Quindi,primadiaffronta reilcriterio,dobbiamoscrivereunafunzionechedatounnumerorestituiscailnumeroformato dallasuaultimacifra,ciochefunzionicos:

>>> print destra1(743843) 3 Unmetodo,puesserequesto:

78

Laboratoriodiinformatica

Criterididivisibilit

trasformo un numero in stringa con il comando str(<numero>) prendo il carattere pi a destra <stringa>[-1] lo trasformo in numero con il comando int(<stringa>) restituisco questo numero con il comando return <valore> Lafunzionepotrebbeessere: def destra1(numero): """destra1(numero) -> ultima cifra del numero.""" numero_in_stringa=str(numero) ultimo_carattere=numero_in_stringa[-1] risultato=int(ultimo_carattere) return risultato Alcuneosservazioni: 1. lafunzionedestra1haunparametrochesichiamanumeroecheconterrilnumeroda cuitrarrel'ultimacifra. 2. Laprimarigadopol'intestazionedellafunzioneuncommentochedovrebbericordare anoi,ospiegareachiusalafunzione,quall'effettodiquestopezzodicodice. 3. Housatoparecchievariabilicercandodidarelorodeinomiabbastanzaespliciti. 4. Ognifunzioneusatamodificailvaloreassegnatoall'ultimavariabile. L'ultimaosservazionepermettediriscrivereilpezzodicodiceprecedenteusandoilparadigma funzionale,qualcosadelgenere: Restituiscilatrasformazioneininterodell'ultimocaratteredellastringaottenutadalnume ro. return int(str(numero)[-1]) Lafunzionediventaquindi: def destra1(numero): """destra1(numero) -> ultima cifra del numero.""" return int(str(numero)[-1]) Dopoavereseguitoilfilechecontienelafunzione(tasto<F5>),nell'ambiente IDLE sipu provarlacondiversivalori: >>> print destra1(65326432) 2 >>> print destra1(8676) 6 ...

Numeri

79

Criterididivisibilit

Oraabbiamolostrumentoperrisolvereilcriteriodidivisibilitper2(equalialtri?).Lafunzio nedovrimplementarequestalogica: sel'ultimacifradelnumero0o2o4o6o8restituisciTruealtrimentirestituisciFalse Lafunzionepotrebbequindiessere: def div2(n): """n e' divisibile per 2.""" if (destra1(n)==0 or destra1(n)==2 or destra1(n)==4 or destra1(n)==6 or destra1(n)==8): return True else: return False Alcuneosservazioni: 1. Lafunzionerispecchialetteralmentequantoprogettato. 2. Lafunzionedestra1(n)vienechiamata5volteperdaresemprelostessorisultato, questononefficiente! 3. Sipufareamenodell'istruzioneif. Perovviarealproblemadelpunto2sipotrebbeusareunavariabileechiamarelafunzionedestra1(n)unasolavolta,migliorerebbel'efficienza.MaPythoncimetteadisposizioneun altrostrumentocherendeilcodiceancorapileggibile: destra1(n) in (0, 2, 4, 6, 8) Cheverificasel'ultimacifradincontenutanellatupla(0, 2, 4, 6, 8).Edatoche questaespressionedcomerisultatounvaloreveroofalso,nonabbiamobisognodiusarel'i struzioneifmabastachelafunzionerestituiscaesattamentequestovalore.Lafunzionediven taquindi: def div2(n): """n e' divisibile per 2.""" return destra1(n) in (0, 2, 4, 6, 8) Nota:laconcisioneelaleggibilitsonocaratteristicheimportantinellaprogrammazione! Percompletarel'operapossiamocostruireunafunzionetestchemettaallaprova div2.La possiamofareinmoltimodidiversi.Iohopensatodiprovarecon5casidinumeridivisibiliper 2e5dinumerinondivisibiliperdue:

80

Laboratoriodiinformatica

Criterididivisibilit

def test(): print "\ndivisibilita' per 2" numeri=[0, 2, 8, 9456546, 10546454674670, 1, 7, 3163, 5*11*7*13, 7*15*19*33] for a in numeri: print "a=%s; div2: %s" % (a, div2(a)) Alcuneosservazioni: 1. Isimboli\nall'internodiunastringasignificano:vaacapo. 2. Quivieneutilizzatounciclofor,lasintassi: for <variabile> in <sequenza>: <blocco di istruzioni> esignificaall'incirca:perognielementodellasequenzaeseguiilbloccodicodice.Nel nostrocaso,perogninumerocontenutoinnumeristampalastringaformattata. 3. Ilcomandoprintseguitodatreoggetti: 1. unastringachecontieneisimboli:%schesonodeisegnaposti, 2. l'operatorediformattazione%, 3. unatuplachecontienetantioggettiquantisonoisegnaposti. Primadistamparelastringa,vengonocalcolatiglioggettipresentinellatuplae inseritiinordinenellastringadovecisonoisegnaposti. Convieneaggiungereinfondoalfilel'istruzione: if __name__ == "__main__": test () Inquestomodoquandovieneeseguitoilprogrammaveneeseguitaautomaticamentelafunzio netest().Mentreseusiamoilprogrammacomelibreriadifunzionitest()nonvieneese guito. Provatu 1. Scrivilefunzionipericriterididivisibilitper5eper10. 2. Aggiungi allaprocedura test lerighenecessarieperverificareilfunzionamento correttodellefunzionicreate Ilcriteriodidivisibilitper4assomigliamoltoaquelloper2,marichiedechesiestraggailnu merocompostodalleultimeduecifre,partiamodaqui.Vistocomeerasemplicelafunzioneper estrarreunacifrapossiamomodificarlaperestrarne2: def destra2(numero): """destra2(numero) -> ultime due cifre del numero.""" return int(str(numero)[-2:])
Numeri 81

Criterididivisibilit

Funziona,seilnumerohapidi2cifremasenehasolouna?Qualcheprovacifavedereche Pythonabbastanzafurboeseglisichiededirestituirepicifrediquellecontenuteinuna stringarestituiscel'interastringa. Possiamooraaffrontareladivisibilitper4.primachiariamoilconcetto: estraggo le ultime 2 cifre del numero, continuo a togliere 20 finch diventa pi piccolo di 20, controllo che quello che ho ottenuto sia un multiplo di 4. InPython: def div4(n): """n e' divisibile per 4.""" n2=destra2(n) while n2>=20: n2-=20 return n2 in [0, 4, 8, 12, 16] Alcuneosservazioni: 1. Lasintassidelciclowhile: while <condizione>: <blocco istruzioni> 2. Seilciclo while deveripetereunasolaistruzioneallorapossibilescriverlasulla stessarigadell'intestazionedopoilduepunti. 3. L'istruzionen2-=20significa:togli20dalnumerocollegatoallaparolan2ecollega ilrisultatoancoraallastessaparola.equivalentean2=n2-20,maunpo'pisinte tico. Provatu 3. Scrivilefunzionipericriterididivisibilitper25,per100. 4. generalizzalefunzionidestra1(numero)edestra2(numero)nellafunzione destran(numero, cifre) inmododapoterestrarrequantecifrevogliamoa destradiunnumero. 5. Scrivilefunzionipericriterididivisibilitper8eper1000. 6. Aggiungi allaprocedura test lerighenecessarieperverificareilfunzionamento correttodellefunzionicreate. Ilcriteriodidivisibilitper3ditipodiverso,noncoinvolgesololapartefinaledelnumero, matuttoilnumero:richiedechesifaccialasommadituttelecifre. Pythonmetteadisposizioneunafunzionechesommaglielementidiunalista,solosequesti
82 Laboratoriodiinformatica

Criterididivisibilit

sononumeri.Abbiamoquindibisognodiunafunzionechetrasformiunnumeroinunalistadi cifre.Losipufareindiversimodi,mausiamounmetodotipicodiPython:lacostruzionedi liste.Nonfacilissimodacapire,masinteticoedelegante. def cifre(numero): """cifre(numero) -> lista delle cifre del numero.""" return list(str(numero)) Sipotrebbetradurrecon: restituisci la lista che contiene la trasformazione in intero di ogni carattere della stringa equivalente al numero. Oppure: Prendi il numero, lo trasformi in stringa, per ogni carattere della stringa, lo trasformi in intero e lo aggiungi alla lista. Aquestopuntoscriverelafunzionecheimplementailcriteriodidivisibilitper3diventauna passeggiata: def div3(n): """n e' divisibile per 3.""" n=sum(cifre(n)) return n in [0, 3, 6, 9] Modifichiamolafunzionetestinmodocheverifichianchelanuovafunzione: def test(): print "\ndivisibilita' per 2" numeri=[0, 2, 8, 9456546, 10546454674670, 1, 7, 3163, 5*11*7*13, 7*15*19*33] for a in numeri: print "a=%s; div2: %s" % (a, div2(a)) ... print "\ndivisibilita' per 3" numeri=[0, 3, 9, 24, 36576798, 1, 7, 3163, 25466737, 5*11*7*13,] for a in numeri: print "a=%s; div3: %s" % (a, div3(a)) Proviamolo...peccatochenonfunzioni:ilnumero36576798nonvienericonosciutocomeun multiplodi3!Comemai?Lasommadellecifredunnumerodiduecifre,quindibisognasom marneancoralecifreeripeterlofinquandolasommaottenutarimanemaggioredi9.Quicivie neinsoccorsoilciclowhile:

Numeri

83

Criterididivisibilit

def div3(n): """n e' divisibile per 3.""" while n>9: n=sum(cifre(n)) return n in [0, 3, 6, 9] Provatu 7. Scrivilafunzioneperilcriteriodidivisibilitper9. 8. Aggiungiallaproceduratest()lerighenecessarieperverificareilfunzionamento correttodellefunzionicreate. Ilcriteriodidivisibilitper11richiedechesommiamolecifredipostoparielecifrediposto dispari.Abbiamogiunafunzioneche,datounnumerorestituiscelalistadellesuecifre,dob biamocostruireunafunzionechedataunalistarestituisceduelistecontenentiglielementidi postopariedipostodispari.Possiamoutilizzareunciclo for conunaparticolareistruzione Pythoncherestituiscenonsolol'elemento,maanchelasuaposizione: enumerate(<sequenza>). Lafunzionedeve: predisporre due liste vuote, p e d, scorrere la lista data e: se la posizione pari: aggiungerla alla lista p, altrimenti: aggiungerla alla lista d, restituire le due liste. def separa(lista): """Separa in due liste gli elementi di posto pari e di posto dispari.""" pari=[] dispari=[] for ind, cifra in enumerate(lista): if div2(ind): p.append(cifra) else: d.append(cifra) return pari, dispari Alcuneosservazioni: 1. Il metodo append aggiunge un elemento in coda ad una lista la sintassi : <lista>.append(elemento). Pu essere usato per costruire liste partendo da unalistavuotaeaggiungendomanmanoglielementi. 2. Adifferenzadialtrilinguaggi,l'istruzionereturnpurestituireanchepielementi. Inquestocaso,restituisce2liste.Chichiamaquestafunzionedevecaricareduevariabi liconilsuorisultato,ades.:postopari, postodispari = separa(c)
84 Laboratoriodiinformatica

Criterididivisibilit

Riassumendo Abbiamovistocomescriverealcunefunzioninonsolofunzionanti,aancheefficienti,sinte ticheefacilmentecomprensibili. Abbiamo costruito assieme le seguenti funzioni di utilit: destra1(numero), destra2(numero),cifre(numero),separa(lista)eiseguenticriterididivisibili t:div2(n),div4(n),div3(n). Hai costruito le seguenti funzioni che traducono le definizioni dei criteri di divisibilit: div5(n), div10(n), div25(n), div100(n), div1000(n), destran(numero, cifre),div8(n),div1000(n),div9(n).

Provatu 9. Scrivilafunzioneperilcriteriodidivisibilitper11. 10. Aggiungiallaproceduratest()lerighenecessarieperverificareilfunzionamento correttodellefunzionicreate. Puoiandareoltre 11. Scrivilafunzionechespezzaunnumeroindueparti,laprimaformatadatuttelesue cifremenol'ultimaelasecondaformatadall'ultimacifra. 12. Scrivilafunzioneperilcriteriodidivisibilitper7. 13. Aggiungiallaproceduratest()lerighenecessarieperverificareilfunzionamento correttodellefunzionicreate. 14. Scrivilafunzionediv16(n). 15. Scrivi le funzioni div6(n), div12(n), div14(n), div15(n), div18(n), div20(n), usandolefunzionigirealizzate. 16. Scrivilefunzionidiv13(n),div17(n),div19(n),usandol'operatore%(resto modulo). 17. Scriviunaprocedurachestampiunatabellaadoppiaentrataconunasequenzadinu merinellaprimacolonnael'indicazionedeivaloripercuiogninumerodivisibile. 18. Riscrivilefunzionichecontengonol'istruzionewhileinmododausarelatecnica dellaricorsioneinvecechedell'iterazione.

Numeri

85

Criterididivisibilit

86

Laboratoriodiinformatica

Divisibilit

2.4. Divisibilit
Cometrovareilmassimocomunedivisoreescoprireseunnumeroperfetto.
Prerequisiti operatori:%e==. funzioniricorsive, strutturadiselezione:if..else, strutturadiiterazione:whileefor, dati:numerieliste. Argomentitrattati massimocomunedivisore, divisoridiunnumero, numeriperfetti.

Problema Scrivereunalibreriafunzionechericerchiinumeriperfetti,inumericiochesonougualialla sommadeilorodivisoritranneilnumerostesso. Soluzione Glielaboratorielettronicipermettonodiaffrontareerisolverealcuniproblemilegatialladivisi bilit.Pythonmetteadisposizionealcunicomandiperquesto.Ilprimodiquestil'operatore: %.Lostessooperatorehasignificaticompletamentediversiasecondadelcontestoincuisi trova.Serveperformattarestringhe: somma=%s % somma,matraduenumeri%nonvie neutilizzatoperqualcosacheriguardalepercentuali,maservepercalcolareilrestodiunadivi sione.Findalleelementaricihannoinsegnatoche13diviso3fa4conilrestodi1.InPython ilrestodiquestadivisionelositrovaconl'espressione:13%3: 13%3>1 15%4>3 55%10>5 457%40>17 ... Macosacentrailrestodelladivisioneconladivisibilit?Inmatematicasidicecheunnumero divisibileperunaltroquandoilrestodelladivisioneugualeazero.Percisidiceche15di visibileper5perchilrestodi15diviso50.Tuttiinumeriparisonodivisibiliper2perchil

Numeri

87

Divisibilit

restodelladivisionetraunnumeroparie2proprio0. L'operatore%chedilrestodiunadivisionepermettedideterminareseunnumerodivideesat tamenteunaltro.Possiamoscrivereunafunzionechetrovaseunnumerodivisibileper3: def div3(num): return num % 3 == 0 Ecosvia,adesempiopercontrollareseunnumerodivisibileper7sipucostruirelafunzio ne: def div7(num): return num % 7 == 0 Unagenericafunzionechecontrollaseilnumerondivisibileperilnumerod,puessere: def divisibile(num, div): return num % div == 0 Invaricasineicalcoliaritmeticinecessariotrovareilminimocomunemultiploeilmassimo comunedivisore.Partiamodaquest'ultimo.L'algoritmodiEuclidediceche: | a se a=b | | altrimenti il mcd tra | la differenza tra a e b e | il pi piccolo tra a e b

il mcd di a e b

TradottoinPythonconunafunzionericorsiva: def mcd1(a, if a==b: elif a>b: else: b): return a return mcd1(a-b, b) return mcd1(b-a, a)

Varialtrialgoritmisonopossibili,tratuttispiccapersemplicitedeleganzailseguente,compo stodatrerighedicodice: def mcd(a, b): '''Massimo Comune Divisore tra a e b''' while b: a, b = b, a%b return a Possiamoscrivereoraunafunzionecherestituiscalalistadeidivisoridiunnumero.Cisono moltimodiperfarlo,un'ideapuessere:

88

Laboratoriodiinformatica

Divisibilit

predisporre una lista vuota, per d che va da 1 a n: se d divide n aggiungi d alla lista restituisci la lista cos ottenuta TradottoinPython: def divisori0(num): '''Restituisce la lista dei divisori di num. Usa un ciclo for e append per popolare la lista.''' result=[] for div in range(1, num+1): if (num % div)==0: result.append(div) return result Lafunzioneprecedenteformatadatreblocchi:l'inizializzazionedellavariabilecheconterrla listadeidivisori,ilciclochepopolaquestalista,l'istruzionecheterminalafunzionerestituendo comerisultatolalistadeidivisori.Pythonmetteadisposizioneunasintassipicompattaper popolareunalista.Lostessorisultatodellafunzioneprecedentepuessereottenutolaunasola rigadiistruzioni: def divisori1(num): '''Restituisce la lista dei divisori di n. Usa la costruzione di liste, list comprehension.''' return [div for div in range(1, num+1) if (num % div)==0] Chepuesseretradottocon: restituisci la lista formata dagli elementi d tali che d appartengono all'intervallo [1, num] e div divisore di num. Lefunzioniprecedentisonopocoefficienti,possibilemigliorarelaricercadeidivisoridiun numeroindiversimodi: 1. Python permettediscriverefunzionicherestituisconopioggetti,inparticolareha unafunzioneprimitivacherestituiscequozienteinteroerestodiunadivisionetrainteri. NellashelldiIDLEfacciamoqualcheprova: >>> print divmod(17, 5) 3, 2 2. Ognivoltachetroviamoundivisore,possiamoconoscerneancheun'altro:sedivdi visoreanchenum/divlo. 3. Tralametdinumenumstessononcisonodivisori,quindipossiamodimezzarel'in tervallodiricerca.
Numeri 89

Divisibilit

4. Anzi,seognivoltacheincontriamoundivisorediv,inseriamoanchenum/div,pos siamofermarcinellaricercaquandodivsuperanum/div. Tenendocontodiquesteosservazionipossiamoscrivereunafunzionepicomplicata,mamoto piefficiente: def divisori(n): result=[] d=1 q=n r=0 while d<=q: if r==0: if d==q: result+=[d] else: result+=[d, q] d+=1 q, r = divmod(n, d) # print d, q, r result.sort() return result Stampareivaloridialcunevariabiliall'internodiunciclo,puaiutareacapirneilsuofunziona mentooascopriredeglierrori.Quandononserve,larigacheproducelastampapuesseretra sformatainuncommentosemplicementeanteponendoilcarattere#alcomando. Unavoltacheabbiamoidivisoridiunnumeropossiamosommarlituttitranneilnumerostesso. Adesempio: Idivisoridi3sono:[1,3],lasommadeidivisoridi3tranne3stesso:1. Idivisoridi4sono:[1,2,4],lasommadeidivisoridi4tranne4stesso:3. Idivisoridi5sono:[1,5],lasommadeidivisoridi5tranne5stesso:1. Idivisoridi6sono:[1,2,3,6],lasommadeidivisoridi6tranne6stesso:6. ... Orainumerichesonougualiaallasommadeilorodivisori,tranneilnumerostesso,sonodetti numeriperfetti. Pythonhaunafunzionecherestituiscelasommadituttiinumericontenutiinunalista;pos siamousarlapercalcolarelasommadeidivisori.UsiamoIDLEperfareunpo'diprovacce.Ad esempiosevogliotrovarelasommadeidivisoridi4odi12possoscrivere >>> print sum([1, 2, 4]) 7 >>> print sum([1, 2, 3, 4, 6, 12]) 28 OpisemplicementepossofarcalcolareaPythonlalistadeidivisori:

90

Laboratoriodiinformatica

Divisibilit

>>> print sum(divisori(4)) 7 >>> print sum(divisori(12)) 28 Peccatochelasommacheciinteressasiaquelladituttiidivisoritrannel'ultimo.Pythonmet teadisposizioneunmetodoperestrarreunasottolistadiunalista,perestrarreunafettadiuna lista.Permaggioriinformazionisipu(ri)guardareilcapitolosulleListeeTuple.Spezzettiamo tutteleoperazionilogichechechiediamoaPythondicompiereinmododarendercicontodi quellochesuccede: >>> # mettiamo in d4 la lista dei divisori di 4 >>> d4=divisori(4) >>> # per sicurezza stampiamo il contenuto di d4 >>> print d4 [1, 2, 4] >>> # bene, ora mettiamo in d4mu il contenuto di d4 meno l'ultimo elemento >>> d4mu=d4[:-1] >>> # ora stampiamo la somma degli elementi di d4mu >>> print sum(d4mu) 3 Orapossiamometteretuttoassieme:stampiamolasommadellafettadeidivisoridi4: >>> print sum(divisori(4)[:-1]) 3 Benepossiamooracreareunafunzionecherestituiscalasommadeidivisoridiunnumero passatocomeargomento: def sommadiv(n): return sum(divisori(n)[:-1]) E,infine,possiamoscrivereunafunzionecherestituisceveroofalsoasecondacheunnu merosiaperfettooppureno: def perfetto(n): return n==sommadiv(n) Possiamousarelafunzioneprecedenteperstamparetuttiinumeriperfettiminoridi100: def perfetti100(): for n in range(2, 101): if perfetto(n): print n, " perfetto", divisori(n)

Numeri

91

Divisibilit

Oppurecreareunaprocedurachevadaavantifinchnonvienepremutoiltasto<Ctrl-c>e checontinuaacercarenumeriperfetti: def perfetti0(): n=2 while True: if perfetto(n): print n, " perfetto", divisori(n) n+=1 Unperfezionamentodiquestaprocedurapermettedipartiredaunnumeroapropriascelta,se nonvieneindicato2,ediandareavantifinchl'utentenondecidediinterrompereilciclo. Quandoilciclovieneinterrotto,premendoiltasto<Ctrl-c>,laprocedura,primaditermina re,stampailvaloreattualedin. def perfetti(n=2): while True: try: if perfetto(n): print n, " perfetto", divisori(n) n+=1 except: print "sono arrivato al numero", n return

Riassumendo L'operatore%restituisceilrestodelladivisionetradueinteri. lafunzionedivmod(n,d)restituisceilquozienteeilreatodelladuivisionetraduenumeri. Sipossonoscriverefunzionichesfruttando,laselezione,l'iterazioneolaricorsione,esplora noproprietlegatealladivisibilitdeinumerinaturali.

92

Laboratoriodiinformatica

Divisibilit

Provatu 1. Scriviunafunzionechericevutidueargomentirestituiscaillorominimocomune multiplo. 2. Unafrazionepuessererappresentatadaunacoppiadinumeriinteri(ades.3/4=(3, 4)doveilprimonumerorappresentailnumeratoreeilsecondorappresentaildeno minatore.Scrivilafunzionedefriduci(a)chericevutaunacoppiacherappresentauna frazionierestituiscalacoppiacherappresentalafrazioneridottaaiminimitermini: es.riduci((18,21))>(6,7). 3. Scriviunafunzionedeffadd(a,b)chericevuteduecoppiecherappresentanofrazioni, restituiscalacoppiacherappresentalalorosomma. 4. Scrivilafunzionedeffmul(a,b)chericevuteduecoppiecherappresentanofrazioni, restituiscalacoppiacherappresentailloroprodotto. 5. Scriviunafunzionecherestituiscaunalistaconidivisoriprimidiunnumeroscritti unasolavolta:es.div(24)>[2,3]. 6. Scriviunafunzioneche,datounnumero,restituiscailnumerodeisuoidivisoriprimi. Puoiandareoltre 7. Scriviunaprocedurachestampilasequenzadeinumeriprimi. 8. ImplementailcrivellodiEratostene.

Numeri

93

Numeriprimi

2.5. Numeriprimi
ComerealizzareilcrivellodiEratostene, Comecercareinumeriprimi.
Prerequisiti operatori://,%,<,e==. funzioniconparametri, strutturadiselezione:if..else, strutturadiiterazione:whileeistruzionebreak, liste. Argomentitrattati crivellodiEratostene, numeriprimi, ottimizzazionedelcodice.

Problema Scrivereunafunzionecherestituiscaunalistadinumeriprimiricavataconilmetododelcrivel lodiEratostene.Eunafunzioneche,partendodaunalistavuota,aggiungamanmanonumeri primi. Soluzione SifarisalireadEratostene,unmetodofurboperindividuareinumeriprimipresentinellase quenzadeipriminumerinaturali: Siscrivonoiprimiennenumerinaturali, Sitoglielozeroel'unochenonsonoprimi Sitieneilprossimonumero(inquestocasoil2)esicancellanotuttiisuoimultipli, Siripetel'istruzioneprecedentefinoadesserearrivatiinfondo. Diseguitoriportoirisultatidelleprimeiterazionidell'algoritmodescrittosopra.

Inunlinguaggiodiprogettoillafunzionepudiventare:

94

Laboratoriodiinformatica

Numeriprimi

def crivello(n): popola una lista con i numeri da 2 a n per ogni elemento della lista, se divide un elemento che lo segue cancella dalla lista quest'altro elemento ..restituisci la lista Perrealizzarel'algoritmocisarbisognodiduecicliannidatiedidueindici,unoperscorrere tuttiglielementidellalista,l'altroperrealizzareilconfrontodiquestielementiconglialtri: def crivello(n): c=range(2, n+1) print "prima dei buchi:\n", c i=0 while i<len(c): j=i+1 while j<len(c): # print c[i], c[j] if c[j] % c[i] == 0: del c[j] j+=1 i+=1 print "\ndopo i buchi:\n", c return c Comeilsolito,qualcheistruzioneprintbenpiazzatapucontribuireacapireilfunzionamen todelcodice,unavoltaesauritalasuafunzione,puesserecommentataocancellata. Ilcrivellofunzionapersottrazione,mettotuttiinumerida2aenneepoieliminoimultipli, possoancheoperareperaddizione,partodaunalistavuotaeaggiungoinumeriprimi.Questa funzionevabenesevoglioavereunalistaconnumeriprimiinferioriaduncertovalore,mase volessigenerarelasequenzadeinumeriprimidovreiprocedereperaddizione.Inpseudocodice: def primi(massimo): preparo un lista vuota per ogni numero da 2 al massimo: se divisibile per un numero compreso tra 2 e il numero stesso: non primo altrimenti: aggiungo questo numero alla lista dei numeri primi restituisco la lista Pertradurrequestoalgoritmoin Python dobbiamopredisporrealcunevariabilierealizzare duecicli,unoannidatonell'altro:

Numeri

95

Numeriprimi

def primi0(massimo): primi=[] num=1 while num<massimo: num+=1 d=2 while d<num: if (num % d)==0: break d+=1 if not d<num: primi.append(num) print num return primi Quandounalgoritmocontienedeicicliannidatibuonanormadubitarechesiaefficiente.Le istruzionicontenutenelciclopiinternoverrannoeseguitemoltevolte.Nellafunzioneprece dentepertrovareinumeriprimiinferioria200,l'operazionechecalcolailrestodelladivisione: num % d,vieneeseguita4424volte.C'spaziopermigliorarel'algoritmo...Intantopossiamo osservarecheaparteilnumero2tuttiglialtriprimisononumeridispariquindi,possiamotrat tare2comecasoparticolareepoicercareiprimisolotrainumeridispariincrementandoilva loredinumdidueinvecechediuno.Chiamiamoil'incremento.Ovviamentenonoccorrerpi verificareseunnumerodivisibileperunnumeropari,quindiancheilpossibiledivisoreandr incrementatodi2: def primi1(massimo): primi=[2] i=2 print 2 num=1 while num<massimo: num+=i d=3 while d<num: if (num % d)==0: break d+=i if not d<num: primi.append(num) print num return primi Quest'altroalgoritmo,nellestessecondizionidellaprovaprecedente,esegue2141voltel'istru zione: num % d.Conquestisemplicicambiamentiabbiamopichedimezzatoleistruzioni eseguitedall'algoritmo.
96 Laboratoriodiinformatica

Numeriprimi

Masipufaredipi.Nessunnumerodivisibileperunvalorecompresotralametdelnume rostessoeilnumerostesso.Adesempionell'intervallo]26;53[nonpossonoessercidivisoridi 53.Quindisenonhotrovatoundivisoretra3eenne/2nonlotroverneppuretraenne/2e enne-1.Quindiquandoildivisoresuperalametdelnumero,possosospenderelaricerca. Cambialacondizionechecontrollailciclowhileecambiadiconseguenzailcontrolloperri conoscereseunnumeroprimo: def primi2(massimo): primi=[2] i=2 print 2 num=1 while num<massimo: num+=i d=3 while d<(num//2): if (num % d)==0: break d+=i if not d<(num//2): primi.append(num) print num return primi Inquestomodo,leoperazionipicritiche(% e //)vengonoeseguite1285volte:ancoraun buonmiglioramento!Mapossiamoridurreancorailnumerodeicontrolli,infattiseosserviamo beneilcomportamentodeinumeripossiamoscoprirechesec'undivisoremaggioredellaradi cequadratadelnumeroalloradeveesserceneancheunominore.Se100divisibileperunnu meromaggioredi10,supponiamo25alloradeveesseredivisibileancheperunnumeroinferio rea10,infattidivisibileper100/25che4.Viceversasenonabbiamotrovatodivisoridienne nell'intervallotra3elaradicequadratadienne,noncenesarannoneppuredopo.ilnostrociclo piinternopuquindifermarsiallaradicequadratadelnumeroinvececheandarefinoalla metdelnumero,unaltrobelrisparmiodicicli.InPython,laradicequadratanonunafun zioneinterna,sitrovanellalibreriamathquindiperpoterlausaredobbiamocaricarelalibreria conl'istruzione:import mathepereseguirladobbiamoscrivere:math.sqrt(num).L'al goritmodiventa:

Numeri

97

Numeriprimi

def primi3(massimo): import math primi=[2] i=2 print 2 num=1 while num<massimo: num+=i d=3 radq=math.sqrt(num) while d<radq: if (num % d)==0: break d+=i if not d<=radq: primi.append(num) print num return primi Poichancheilcalcolodellaradicequadratadiunnumeroun'operazionepesante,invecedi farlaeseguireduevolte,nellacondizionedelciclowhileenell'istruzioneif,hopreferitouti lizzareunavariabile.sommandolechiamateamath.sqrteall'operatorechecalcolailresto delladivisione(%),ottengo448istruzionieseguite.Circaunterzodellaversioneprecedenteeun decimodiquellainiziale!Cambiandounpo'l'algoritmosipumigliorareancora... Leggereunalibreriamatematicapereseguireun'operazione,nonilmassimodell'efficienzae laradicequadratastessaun'operazionepiuttostopesante.Pythoncimetteadisposizioneuna funzioneche,datiundividendoeundivisore,restituisce,comerisultato,ilquozienteeilresto delladivisione.: >>> print divmod(27, 4) (6, 3) perch27equivalea6*4+3.divmod()unafunzionemoltoefficienteepossiamoutilizzarla nelnostroalgoritmo. Dall'osservazionechesedividoenneperunnumeroinferioreallasuaradicequadrataottengo unquozientemaggioredellasuaradicequadrata,possiamotrasformareilciclopiinternoin modochecalcoliquozienteerestodelladivisionetranumedeterminiinunodiquestidue casi:seilrestougualea0,inquestocasonumnonprimo,oseildivisorehasuperatoilquo ziente,inquestocasonumprimo.PerusciredauncicloPythonmetteadisposizionel'istru zionebreak.Quindil'algoritmodiventa:

98

Laboratoriodiinformatica

Numeriprimi

def primi4(massimo): primi=[2, 3] i=2 print 2 print 3 num=3 while num<massimo: num+=i d=3 while True: q, r = divmod(num, d) if r==0: break d+=i if d>q : primi.append(num) print num break return primi Ilcomandowhile True:indicaunciclochecontinuafinchnonvieneeseguitaun'istruzio nebreak.Ilnumerodidivisioni,chiamateallafunzionedivmod()orasono:278,unaltro notevolemiglioramento.Conqualchealtrotruccosipumigliorareulteriormentel'efficienza dell'algoritmo. Riassumendo Percalcolareseunnumerodivisibileperunaltrosipuusarel'operatore%oppurelafun zionedivmod()verificandocheilrestosiazero. Siputerminareunciclousandol'istruzionebreak. Scrivereunprogrammachefunzionailprimopasso,ilprogrammadeveancheessereele ganteedefficiente.

Numeri

99

Numeriprimi

Provatu 1. Provaascrivereunafunzioneprimi5piefficientediprimi4. 2. Scriviunafunzioneprimo(num)cherestituiscailvaloreTrueseunnumprimo, Falseincasocontrario. 3. Scrivi una funzione altroprimo(num) che restituisca il primo numero primo maggiordinum. Puoiandareoltre 4. Scriviunafunzionecherestituiscaidivisoridiunnumero. 5. Scriviunaproceduracheverifichiseiprimi7numeridiMersennesonotuttiprimi.

100

Laboratoriodiinformatica

Inumeridell'orologio

2.6. Inumeridell'orologio
Comeprodurreletabellinedelle4operazioniconleclassidirestomoduloenne.
Prerequisiti operatori:%,<,e==. funzioniconparametri, strutturadiselezione:if..else, strutturadiiterazione:whileeistruzionebreak, funzionedivmod() liste. Argomentitrattati classiresto, visualizzazionediunamatrice,

Problema Scriveredellefunzionichevisualizzinoletabellinedellequattrooperazioniconinumerimodu loenne. Soluzione Quantisonoinumeri?Domandaallaquale,findalleelementari,siimparaarispondere:infini ti!Infatti,aqualunquenumerosiarrivibastaaggiungere1perottenerneunaltro.Questora gionamentofilasepensiamocheaggiungendo1adunnumerosiottengasempreunnumero nuovononpresentenellesequenzadinumerigiincontrati.Sipossonopensare,invece,degli insiemi di numeri nei quali, ad un certo punto, aggiungendo 1 si ottenga di nuovo 0:

0 1 2 3 4 5 .Inquestomodoinumerisiavvolgonosusstessiesiottiene
1 1 1 1 1

uninsiemelimitatodinumeri.Nelcasoprecedentel'insiemecostituitoda6numeri:{0,1,2, 3,4,5}.Poichquestinumeripossonoesserevisticometuttiipossibilirestidelladivisionedi unnumerointeroqualunqueper6,sonoanchedetticlassidirestomodulo6. Ora,sipotrebbepensarecheuninsiemedinumericoslimitatopossarisultaredeltuttoinutile, manoncos.QuestiinsiemifinitidinumerisonostatistudiatidalgrandematematicoC.F. Gauss.possibiledefinirealcuneoperazionisuquestiinsiemidinumeri.Leoperazionidefinite suquestinumerihannodelleproprietmoltointeressantitantoverocheattualmentelacritto grafiaequindituttocicheriguardalasicurezza,nellanostrasociet,basatosuquestepro priet,oltrechesulleproprietdeinumeriprimiedellascomposizioneinfattoriprimi. Messagicos,sipotrebbepensarechequestafaccendariguardisoltantoproblemimoltopi
Numeri 101

Inumeridell'orologio

grandidinoi,invecenoiusiamotuttiigiorniinumeridiquestotipo,precisamentequando guardiamol'orologiooquandofacciamodeiconticonleore:5oredopole9dellamattinasono le2delpomeriggio:9+5=2.Inumeridell'orologiosonoleclassidirestomodulo12omodulo 24asecondadicomeabbiamosettatolanostrasveglia.Perottenereilrisultatodiun'operazione inquestiinsiemidinumeri,possiamoeseguirel'operazionecomeavessimoachefareconinor malinumeriinteriepoidividereilrisultatoperilmodulo(nelcasodelleore:12(o24))etene reilresto: 912+512=resto_della_divisione(9+5, 12) Cio: seallaclassedirestomodulo129aggiungolaclassedirestomodulo125ottengoilresto delladivisionetralasomma9+5e12. Arileggereiltestoinsimilitalianomiparecoscomplicato!Chegrandeinvenzioneisimboli matematici!!! Veniamoanoi,vogliamoscrivereunprogrammachecostruiscaestampiletabellinedelleope razioniconinumericlasserestomoduloenne. Primadituttoprecisiamocomepuessererappresentataall'internodiPythonunatabellaqua dratacomelaseguente: 2 1 4 3 2 3 4 3 2

Possiamousareleliste:unalistadi3numerirappresentaunarigaetrelisterappresentanol'inte ramatrice: matrice=[[2, 3, 4], [1, 2, 3], [4, 3, 2]] Siccomelarappresentazioneconinumeribenschieratipileggibilediunalistadiliste,prima diprocederecicostruiamounafunzionechestampiperbeneunamatriceconunnumeroqua lunquedirigheedicolonne.Inpseudocodice: def printmat(matrice): per ogni riga contenuta nella matrice: per ogni elemento contenuto nella riga: stampa l'elemento senza andare a capo va a capo Datoche inumeridellematricichecostruiremo saranno semprecompresitra0 e99,cio avrannoalmassimo2cifre,perilcomandostampaconvieneusarelastringadiformattazione %2scheproduceunastringachecontieneilnumeroformatasempredaduecaratteri,even tualmenteaggiungendounospazioprimaseilnumerominoredi10.
102 Laboratoriodiinformatica

Inumeridell'orologio

TradottoinPython: def printmat(mat): """Stampa una matrice bidimensionale di numeri di una o due cifre allineando le colonne.""" for riga in mat: for elemento in riga: print "%2s" % elemento, print Notarechelavirgolacheterminailprimocomandoprintstaasignificare:stampasenzaan dareacapo.Dopoaversalvatoilfileeaverloeseguito,proviamoilfunzionamento: >>> m=[[2, 3, 4], [1, 2, 3], [4, 3, 2]] >>> printmat(m) 2 3 4 1 2 3 4 3 2 Orachecisiamofornitidellostrumentoperstampareunamatricedinumericoncentriamocisul problema:vogliamoscrivereunafunzionecheproducalatabellina(matrice)deirisultatidelle operazioniconleclassimodulorestoenne. Iniziamodallamoltiplicazione.Inpseudocodice: def matprod(mod): predisponi una matrice vuota per mod volte: predisponi una riga vuota per mod volte: calcola il prossimo ele. della lista e agg. alla riga aggiungi la riga alla matrice restituisci la matrice Proviamoavedereuncasoabbastanzasempliceepoiageneralizzarlo: x 0 1 2 3 0 0 0 0 0 1 0 1 1 3 2 0 2 0 2 3 0 3 2 1 Leformuleperottenerlosono:
Numeri 103

Inumeridell'orologio

x 0 1 2 3

0*0 mod 4 0*1 mod 4 0*2 mod 4 0*3 mod 4 1*0 mod 4 1*1 mod 4 1*2 mod 4 1*3 mod 4 2*0 mod 4 2*1 mod 4 2*2 mod 4 2*3 mod 4 3*0 mod 4 3*1 mod 4 3*2 mod 4 3*3 mod 4

Perottenereilvalorediunacelladevoprenderel'intestazionedellarigadiquellacella(indice dellariga),moltiplicarlaperl'intestazionedellacolonnadiquellacella(l'indicedellacolonna)e calcolareilrestodelladivisioneper4sestolavorandoconleclassidirestomodulo4. Scegliamounnomepergliindicidellerighe:iyeunnomepergliindicidellecolonne:ix(sa rebbeandatoaltrettantobeneir,icomeglioindice_riga,indice_colonna)eraffiniamol'algorit mocheproducelatabelladellamoltiplicazione: def matprod(mod): predisponi una matrice vuota per iy che indica ogni riga: predisponi una riga vuota per ix che indica ogni colonna: aggiungi alla riga: ix*iy % mod aggiungi la riga alla matrice restituisci la matrice ProvaatradurloinPythonprimadiproseguireconlalettura...Econfrontalocon: def matprod(mod): """Produce la tabellina della molt. dei numeri Zmod. Metodo che utilizza l'iterazione for.""" mat=[] for iy in range(mod): riga=[] for ix in range(mod): riga.append(ix*iy%mod) mat.append(riga) return mat Aggiungendoinfondoalprogrammalerigheseguenti: def main(): printmat(matprod(12)) print if __name__=="__main__": main()

104

Laboratoriodiinformatica

Inumeridell'orologio

edeseguendoilprogramma,sidovrebbeottenerequantovoluto.Cambiandol'argomentopassa toallafunzionesiottengonoletabellinedellamoltiplicazionedellediverseclassidirestomo duloenne. Scrivereunprogrammachefunzionailprimopasso.Ilsecondosistemareilcodiceinmodo chesiapiefficienteopileggibile.Passiamoallasecondafase. Ilsecondociclofor,quellopiinterno,produceunalista.Pythonhaunmeccanismodico struzionediliste(dettolistcomprehension)chepermettediriassumeretutteleinformazioni contenutenelle4righe: riga=[] for ix in range(mod): riga.append(ix*iy%mod) mat.append(riga) inun'unicariga: mat.append([ix*iy%mod for ix in range(mod)]) ChiprogrammaPythonritienechequestomododiprogrammaresiapiPitonico,pisem pliceecomprensibile.Ovviamentebisognafarciunpo'l'abitudine,comeintuttelecose.La funzionealloradiventa: def matprod(mod): """Produce la tabellina della molt. dei numeri Zmod. Metodo che usa l'iterazione for e la costr. di liste.""" mat=[] for iy in range(mod): mat.append([ix*iy%mod for ix in range(mod)]) return mat Aquestopuntoipiscaltriavrannoriconosciutocheilciclofor,el'istruzionechelaprecede, servepercostruireunalista,possiamoapplicareancorailmeccanismodellalistcomprehension edottenereunafunzionecostituitadaunasolariga: def matprod(mod): """Produce la tabellina della molt. dei numeri Zmod. Metodo che usa la costruzione di liste.""" return [[ix*iy%mod for ix in range(mod)] for iy in range(mod)] Uncodicepicompatto,spessopisemplicedaverificareedacorreggere,masonsideve maisacrificarelachiarezzaelaleggibilitperlasintesi:nellascaladeivalori,lasintesiim portante,malaleggibilitlodipi!

Numeri

105

Inumeridell'orologio

Riassumendo Possomemorizzareunamatricerettangolaresottoformadilistadiliste. Possoscrivereunafunzionechestampiinmodoordinatounamatrice. Usandol'operatore%possocalcolareilrestodiunadivisione. InPythonlacostruzionediliste(listcomprehension)permettedisostituireunciclofor sintetizzando4righeinuna. Provatu 1. Scrivilafunzionechecalcolilatabellinadell'addizione. 2. Scrivilafunzionechecalcolilatabellinadellasottrazione. 3. Perchlasottrazionesiasemprepossibiledevointrodurrenumerinegativi?Esiste l'oppostodiogninumero? 4. Cheproblemisorgononelcasodelladivisione?

106

Laboratoriodiinformatica

Scomposizioneinfattoriprimi

2.7. Scomposizioneinfattoriprimi
Comescomporreunnumeroinfattoriprimi.
Prerequisiti operatori:>,e==. funzioniconparametri, funzionedivmod() strutturadiselezione:if..else, strutturadiiterazione:whileeistruzionebreak, listeetuple. Argomentitrattati scomposizionediunnumeroinfattoriprimi, programmazioneguidatadaitest,

Problema Scrivereunafunzionecheproducalascomposizioneinfattoriprimidiunnumero. Soluzione Ilteoremafondamentaledell'aritmeticadicechelascomposizioneinfattoriprimidiunnumero unica.Civuoldirechepossoseguirediversestrade,mailrisultatodipendesolodalnumero enondalpercorsoseguito: 72 = 23 32 / \ 2 36 / \ 6 6 / \ / \ 2 3 2 3 72 = 23 32 / \ 4 18 / \ / \ 2 2 2 9 / \ 3 3 72 = 23 32 / \ 8 9 / \ / \ 2 4 3 3 / \ 2 2

Ilmetodochepreferisco,perscomporreinfattoriunnumero,quellodell'alberobinario:

seilnumeroprimo,giscompostoinfattoriprimi, altrimentidaquestonumeroderivodueramisottocuiscrivoduenumeriilcuiprodottodia ilnumerodipartenza, ripetoiduepassiprecedentiperogninuovonumero.

Numeri

107

Scomposizioneinfattoriprimi

Questometodo,ricorsivo,permetteadognipassodiscegliereidivisoripicomodiequindiin molticasirendepisempliceilcalcolorispettoalmetodochesolitamentesitrovaneilibridelle medie: 3600 1800 900 450 225 75 25 5 1 3600 | | | | | | | | | = 2 2 2 2 3 3 5 5 243252 3600 = 243252 / \ 100 36 / \ / \ 10 10 4 9 / \ / \ / \ / \ 2 5 2 5 2 2 3 3

Amepiaceancheperchnondevoriscrivereilnumerodipartenzaquandohoterminatola scomposizione(lasolitapigrizia).Ilmetodoadalberobinariodiventadeltuttougualealmeto dopropostosuilibri,seognivoltascelgoildivisorepipiccolopossibile: 3600 = 243252 / \ 2 1800 / \ 2 900 / \ 2 450 / \ 2 225 / \ 3 75 / \ 3 25 / \ 5 5 Ilmetodoadalberoprevedechesiamonoiasceglieretratuttiipossibilidivisoridiunnumero qualeutilizzare,ilteoremafondamentaledell'aritmeticaciassicurachequalunquedivisoreva bene.Selasceltalafacciamoconunpo'dibuonsensopossiamorendercipisempliceilcalco lo.Ora,sevogliamorealizzareunafunzioneautomaticachescompongainfattoriunnumero, dobbiamotenerepresenteche,perlemacchine(purtroppospessoancheperipoliticiegliam ministratoriingenere),ilbuonsenso risultamolto difficile,mentrerisultafacileilcalcolo. Quindil'algoritmopudiventarequalcosadisimileaquesto:

108

Laboratoriodiinformatica

Scomposizioneinfattoriprimi

Dividi il num. per il pi piccolo divisore (maggiore di 1!) dividi il quoziente ottenuto per il pi piccolo divisore continua cos finch non hai ottenuto come quoziente 1 Nelcasodelnumero120otteniamo: 120 60 30 15 5 1 | | | | | | 2 2 2 3 5

Abbiamovistochenonilmetodopipraticoquandodobbiamofareamanolascomposizione, mamoltomeccanicoequindipifacilmentetrasformabileinunalgoritmo.Otteniamoquin di 120=2335 . Primadiprocederedobbiamopensareadunastrutturadidatichepermettadirappresentaretutti i possibili risultati delle scomposizioni in fattori: 2 335 ma anche 2 43252 e anche e...Perchscriverepotenzeseparatedaunpuntinocomodoperunessereumano,ma nonlomoltoperuncomputer. Ricordandoche 3=31 , 5=51 ...,ognifattorepuesserevistocomeunapotenza,possia moosservarechelascomposizioneinfattoriprimiformatadaunasequenzadipotenzeinnu merovariabile.In Python lastrutturadidatichevieneutilizzataperconteneresequenzedi lunghezzavariabilelalista,quindilafunzionechescomporrinfattoriunnumerodovr restituirecomerisultatounalistadipotenze:[potenza1,potenza2,potenza3,...]. Unapotenzapuesserevistacomeunacoppiadinumeri:labaseel'esponente.Unacoppiain Pythonpuessererappresentatadaunatupla:23=(2,3),51=(5,1),...Lascomposizione infattoridiunnumeropuesserevistacomeunasequenzadipotenzeedessererappresentata inPythoncomeunalistadituple:larappresentazioneinternadi 2 335 puessere lalistadicoppie:[(2,3),(3,1),(5,1)]chevainterpretatacomedueelevatoallaterzapertre elevatoallaprimapercinqueelevatoallaprima. Oraabbiamotuttiglielementiperaffrontareilproblema:incominciamoascriveilcodice! Ilmetodoseguitodisolitoquellodi: 1. scrivereunaprimafunzione 2. provarlainvaricasi 3. correggerla 4. tornarealpunto2finchnonrisultasufficientementecorretta. Questometodofunziona,madalpuntodivistainformaticomoltomeglio,primascrivereitest delnostroprogrammaepoiilcodicecherisolveilproblema:primadefiniamoglieserciziei risultaticheciaspettiamodiottenereepoiscriviamolafunzionechedovrrisolvereglieserci

2 3

Numeri

109

Scomposizioneinfattoriprimi

zi.Questomododiprocedere,che pusembrarestrano, cosimportantedameritareun nome:programmazioneguidatadaitest,testdriven.Bene,manoall'editoreiniziamoascri vereilnostroprogramma: def fattorizza(numero): """Scomposizione in fattori primi di numero.""" risultato = [] return risultato

def prova(funzione, risultato_atteso): """Esegue la funzione e confronta il risultato con risultato_atteso.""" risultato=eval(funzione) if risultato==risultato_atteso: print "%s -> %s corretto" % (funzione, risultato) else: print "%s -> %s, risultato atteso: %s" \ % (funzione, risultato, risultato_atteso)

def test(): prova("fattorizza(7)", [(7, 1)]) prova("fattorizza(8)", [(2, 3)]) prova("fattorizza(23)", [(23, 1)]) prova("fattorizza(28)", [(2, 2), (7, 1)]) prova("fattorizza(30)", [(2, 1), (3, 1), (5, 1)]) prova("fattorizza(120)", [(2, 3), (3, 1), (5, 1)]) prova("fattorizza(%s)" % (2*2*3*3*3*3*7*11*11), [(2, 2), (3, 4), (7, 1), (11, 2)]) if __name__=="__main__": test() Qualchecommentoalle3funzioni. Laprima,fattorizza(),quellachedobbiamocostruire.definitainmododecisamente stupido:qualunquesial'argomentopassatoallafunzione,emessonelparametronumero,dar comerisultatounalistavuota.Peroravabenecosperchciconcentriamosullefunzioniche servonoperiltest. Lafunzioneprova()lapicomplessa: Ha2parametri,nelprimovienemessalafunzionedaeseguireenelsecondoilrisultatoat teso. Eseguelafunzioneememorizzailrisultato.
110 Laboratoriodiinformatica

Scomposizioneinfattoriprimi

Confrontailrisultatoottenutoconquelloattesoestampaunmessaggioadeguato. L'ultima,test()costituitadaunasequenzadichiamateallafunzioneprova()passandole viaviadiversefunzionidaverificareconirisultatiattesi. Quandoeseguiamoilprogrammal'ultimalineachiamalafunzionetest()eotteniamoilseguente output:

fattorizza(7) -> [], risultato atteso: [(7, 1)] fattorizza(8) -> [], risultato atteso: [(2, 3)] fattorizza(23) -> [], risultato atteso: [(23, 1)] fattorizza(28) -> [], risultato atteso: [(2, 2), (7, 1)] fattorizza(30) -> [], risultato atteso: [(2, 1), (3, 1), (5, 1)] fattorizza(120) -> [], risultato atteso: [(2, 3), (3, 1), (5, 1)] fattorizza(274428) -> [], risultato atteso: [(2, 2), (3, 4), (7, 1), (11, 2)] Aquestopuntopossiamoesseremoderatamentesoddisfatti:ilprogrammanonfaquellochevo gliamo,mafunzionacorrettamente.Unpiccolocambiamentoallafunzionefattorizza()leper metteditrattarecorrettamenteinumeriprimi: def fattorizza(numero): """Scomposizione in fattori primi di numero.""" risultato = [(numero, 1)] return risultato L'output: fattorizza(7) -> [(7, 1)] corretto fattorizza(8) -> [(8, 1)], risultato atteso: [(2, 3)] fattorizza(23) -> [(23, 1)] corretto fattorizza(28) -> [(28, 1)], risultato atteso: [(2, 2), (7, 1)] fattorizza(30) -> [(30, 1)], risultato atteso: [(2, 1), (3, 1), (5, 1)] fattorizza(120) -> [(120, 1)], risultato atteso: [(2, 3), (3, 1), (5, 1)] fattorizza(274428) -> [(274428, 1)], risultato atteso: [(2, 2), (3, 4), (7, 1), (11, 2)] Inumeri7e23vengonoscomposticorrettamenteequestociconfortasulbuonfunzionamento dellefunzioniditestche,oltreariconoscereicasisbagliati,tuttinellaprimaversionedifatto rizza(),riconosconoanchequellicorretti.
Numeri 111

Scomposizioneinfattoriprimi

Aquestopuntoconvieneriprenderegliesempidiscomposizioneinfattoririsolticoncartae penna.chiarochecisonodelleoperazionichevengonoripetutefinquandoilnumeroda scomporremaggioredi1.Ininformaticacisitraduceconunciclowhile: fin quando numero>1: esegui qualcosa Maprimadiiniziareilciclodevoporreildivisoreugualealpibassovalore,cioporreildivi soreugualea2. divisore=2 fin quando numero>1: esegui qualcosa All'internodelciclodevocalcolarequozienteerestodelladivisionedinumeroperdivisoree controllareilresto.Seilrestougualeazero,aggiungounacoppiaeaggiornoilnumero,altri mentiincrementoildivisore: divisore=2 fin quando numero>1: calcolo quoziente e resto di numero / divisore se resto uguale a 0: aggiungo una coppia al risultato aggiorno il numero altrimenti incremento il divisore Leidee,aquestopuntosonoabbastanzachiareperpoteresseretradotteinPython: def fattorizza(numero): """Scomposizione in fattori primi di numero.""" risultato = [] divisore=2 while numero>1: quoziente, resto = divmod(numero, divisore) if resto==0: # numero multiplo di divisore risultato.append((divisore, 1)) # aggiungo una coppia a risultato numero=quoziente # aggiorno numero else: divisore+=1 # incremento divisore return risultato L'esecuzionedelprogrammaproduce:

112

Laboratoriodiinformatica

Scomposizioneinfattoriprimi

fattorizza(7) -> [(7, 1)] corretto fattorizza(8) -> [(2, 1), (2, 1), (2, 1)], risultato atteso: [(2, 3)] fattorizza(23) -> [(23, 1)] corretto fattorizza(28) -> [(2, 1), (2, 1), (7, 1)], risultato atteso: [(2, 2), (7, 1)] fattorizza(30) -> [(2, 1), (3, 1), (5, 1)] corretto fattorizza(120) -> [(2, 1), (2, 1), (2, 1), (3, 1), (5, 1)], risultato atteso: [(2, 3), (3, 1), (5, 1)] fattorizza(274428) -> [(2, 1), (2, 1), (3, 1), (3, 1), (3, 1), (3, 1), (7, 1), (11, 1), (11, 1)], risultato atteso: [(2, 2), (3, 4), (7, 1), (11, 2)] Oraanche30fattorizzatocorrettamente,nonsolo,anchelealtresoluzionisarebberogiustese noiavessimodecisodiaccettare 3333 alpostodi 34 .Rimbocchiamocilemanichee cerchiamodiaggiustarelecose.Nelprecedente algoritmoeffettivamentenon c'tracciadi esponenti.Primadiiniziareilciclooltreaporredivisoreugualea2dobbiamoporrel'espo nenteugualea0eaumentarel'esponenteognivoltachedivisoredividenumero. Quandodivisoredivide numero,invecediaggiungereunacoppia,incrementiamol'espo nente.Lacoppiavieneinveceaggiuntaquandodivisorenondividenumerosolosel'espo nentemaggioredizero: def fattorizza(numero): """Scomposizione in fattori primi di numero.""" risultato = [] divisore=2 esponente=0 while numero>1: quoziente, resto = divmod(numero, divisore) if resto==0: # numero multiplo di divisore esponente+=1 # incremento esponente numero=quoziente # aggiorno numero else: if esponente>0: # se esponente cambiato risultato.append((divisore, esponente)) # agg. una # coppia a ris. divisore+=1 # incremento divisore return risultato Operatelemodifichebastaeseguireilprogramma:

Numeri

113

Scomposizioneinfattoriprimi

fattorizza(7) -> [], risultato atteso: [(7, 1)] fattorizza(8) -> [], risultato atteso: [(2, 3)] fattorizza(23) -> [], risultato atteso: [(23, 1)] fattorizza(28) -> [(2, 2), (3, 2), (4, 2), (5, 2), (6, 2)], risultato atteso: [(2, 2), (7, 1)] fattorizza(30) -> [(2, 1), (3, 2), (4, 2)], risultato atteso: [(2, 1), (3, 1), (5, 1)] fattorizza(120) -> [(2, 3), (3, 4), (4, 4)], risultato atteso: [(2, 3), (3, 1), (5, 1)] fattorizza(274428) -> [(2, 2), (3, 6), (4, 6), (5, 6), (6, 6), (7, 7), (8, 7), (9, 7), (10, 7)], risultato atteso: [(2, 2), (3, 4), (7, 1), (11, 2)] Disastro!Anchequellocheprimafunzionavaoranonvapi!Cosasuccesso?Possiamofare unaprimaosservazione:neinumeriprimiilrisultatounalistavuota,perchfinitoilcicloci rimastainmanounacoppiachedobbiamoaggiungereallalista.Quindi,primadirestituireilri sultatodobbiamoaggiungerel'ultimacoppia: def fattorizza(numero): """Scomposizione in fattori primi di numero.""" risultato = [] divisore=2 esponente=0 while numero>1: quoziente, resto = divmod(numero, divisore) # print numero, divisore, quoziente, resto if resto==0: # numero multiplo di divisore esponente+=1 # incremento esponente numero=quoziente # aggiorno numero else: if esponente>0: # se esponente cambiato risultato.append((divisore, esponente)) # agg. una # coppia a ris. divisore+=1 # incremento divisore risultato.append((divisore, esponente)) # agg. una coppia # a risultato return risultato Orailprogrammaproduce:

114

Laboratoriodiinformatica

Scomposizioneinfattoriprimi

fattorizza(7) -> [(7, 1)] corretto fattorizza(8) -> [(2, 3)] corretto fattorizza(23) -> [(23, 1)] corretto fattorizza(28) -> [(2, 2), (3, 2), (4, 2), (5, 2), (6, 2), (7, 3)], risultato atteso: [(2, 2), (7, 1)] fattorizza(30) -> [(2, 1), (3, 2), (4, 2), (5, 3)], risultato atteso: [(2, 1), (3, 1), (5, 1)] fattorizza(120) -> [(2, 3), (3, 4), (4, 4), (5, 5)], risultato atteso: [(2, 3), (3, 1), (5, 1)] fattorizza(274428) -> [(2, 2), (3, 6), (4, 6), (5, 6), (6, 6), (7, 7), (8, 7), (9, 7), (10, 7), (11, 9)], risultato atteso: [(2, 2), (3, 4), (7, 1), (11, 2)] Qualcosamigliorato:inumericonunsolofattoreprimo,nonimportaconqualeesponente, sonofattorizzatiinmodocorretto,glialtrisonostrampalati.Ilproblemaderivadalfattoche,al l'internodelciclo,quandovieneaggiuntaunacoppiaalrisultato,l'esponentedeveessererimes soazero. def fattorizza(numero): """Scomposizione in fattori primi di numero.""" risultato = [] divisore=2 esponente=0 while numero>1: quoziente, resto = divmod(numero, divisore) if resto==0: # numero multiplo di divisore esponente+=1 # incremento esponente numero=quoziente # aggiorno numero else: if esponente>0: # se esponente cambiato risultato.append((divisore, esponente)) # agg. una # coppia a ris. esponente=0 # rimette a zero esponente divisore+=1 # incremento divisore risultato.append((divisore, esponente)) # agg. una coppia # a risultato return risultato Ilprogrammaoraproduce:

Numeri

115

Scomposizioneinfattoriprimi

fattorizza(8) -> [(2, 3)] corretto fattorizza(23) -> [(23, 1)] corretto fattorizza(28) -> [(2, 2), (7, 1)] corretto fattorizza(30) -> [(2, 1), (3, 1), (5, 1)] corretto fattorizza(120) -> [(2, 3), (3, 1), (5, 1)] corretto fattorizza(274428) -> [(2, 2), (3, 4), (7, 1), (11, 2)] corretto Selanostrabaseditestabbastanzaampiapossiamoritenercisoddisfatti.Nonsolo,sequalche utentedellanostrafunzione,onoistessiciaccorgiamodiunparticolarecasocheproduceuner rore,bastacheloaggiungiamoaicasidaverificareepoimodificarela fattorizza() in modochefunzionicorrettamenteintuttalanostrabasediprove.Questomeccanismopermette dievitarechelacorrezionediunerroreproducaunerroreneicasicheprimafunzionavanocor rettamente. Riassumendo Unbuonmododiscrivereunprogrammaquellodifarsiguidaredaitest.Inparticolarenei programmicomplessi,perderedeltemponellacostruzionediunaadeguatabatteriaditestfa guadagnare,complessivamente,moltotempo. Primadimettersiascrivedelcodicesidevearrivareadareunabuonadescrizioneaparole dell'algoritmochesivuolerealizzare. Sel'algoritmopensatobene,nondifficilecorreggereeventualierrorimagariscovandoli conqualcheistruzioneprintposizionataappropriatamente. Provatu 1. Inseriscinellefunzionidelleappropriateistruzioniprintinmododavisualizzareil funzionamentointerno. 2. Aggiungialcunivaloriditest. 3. Scriviunprogrammadotatodiunaadeguatabatteriaditestconunafunzionechere stituiscalalistadituttiidivisoridiunnumero,

116

Laboratoriodiinformatica

Geometriainterattiva

3. Geometriainterattiva
Inquestasezionesonopresentatideiproblemigeometricidarisolverecon Pythonconl'ag giuntadellalibreriaPyig,lageometriainterattivaconPython.Ilpercorsoquipropostopu esseresvoltoanchecomeintroduzioneallaprogrammazionedatochegliesempiintrodurranno gradualmenteivariaspettidellinguaggio. Perl'installazionedellapibreriaPygraph,checontieneanchePyig,vedil'introduzione.

Geometriainterattiva

117

Geometriainterattiva

118

Laboratoriodiinformatica

Elementifondamentali

3.1. Elementifondamentali
Comecreareglielementifondamentalidellageometria.
Python,cometuttiilinguaggimoderni,formatodaunnucleodifunzionalitdibaseamplia todaunagrandequantitdilibreriechelorendonoadattoarisolvereipisvariatiproblemi.La liberiaPyigpermettedilavorareinunafinestragraficadovesipossonoinserireoggettigeo metriciemuoverlitrascinando,conilmouse,ipuntibase. PossiamoiniziarecostruendoglielementibasedellageometrianellafinestrainterattivadiPython:IDLE.SevogliamochemanmanochescriviamoicomandiinIDLEappaianoanchegli effettinellafinestragrafica,dobbiamoavviareIDLEconilparametro-n. ChiusaLinuxpuavviareIDLEconilseguentecomandoscrittoinunaconsole: $ idle-pithon2.4 -n. ChiusaWindowspurealizzaredueiconeunacheavviaIDLEconilparametro-neunache useremopiavantisenzaquestoparametro. AvviatoIDLEotteniamounashellcaratterizzatadallapresenzadelsimbolo:>>>seguito dalcursorelampeggiante.Quiscriviamoinostricomandicheverrannoeseguitiallapressione deltasto<Invio>. Ilprimocomandochedobbiamodareservepercaricarelalibreriapyigerendercidisponibili tuttiisuoielementi: >>> from pyig import * Alcuneosservazioni: 1. LalibreriapyignonsitrovaassiemeallinguaggioPython,mafapartedelpacchetto pygraph. pygraph unsoftwarelibero,puquindiesserecopiatoeusatolibera mente.Senongiinstallatobisognaprocurarselo,magariscaricandolodaInternet, scompattarlo, copiare la cartella pygraph e il file pygraph.pth nella cartella syte-packagesdellaversionediPythonchestiamousando. 2. Ilcomandofrom pyig import *dicea Pythondiimparareemetterediretta menteadisposizionetuttiglioggettielefunzionipresentinellalibreriapyig. Setuttoandatoabuonfine,dopoquestaistruzionesiapertaunafinestragraficacon,visibili gliassicartesianieunagrigliadiriferimento.All'internodiquestafinestrapossiamoaggiungere oggettigeometrici.Iniziamodaipunti.Peraggiungereunpuntodobbiamoforniglilesuecoor dinate: >>> p0=Point(3, -4) >>> p1=Point(-3.2, 7.5)

Geometriainterattiva

119

Elementifondamentali

QuandoapriamolaparentesichesegueilnomedellaclassePoint,IDLEvisualizzaunastrin gadihelpcheciddelleinformazionisuqualiargomentidobbiamofornireperchPointpos saesseredisegnato: (x, y [visible, color, width, name, internal]) -> Point. xeysonodueargomentiobbligatori,glialtrisonoopzionali,litratteremofrapoco. Provatu 1. Disegna,nelprimoquadranteunafilaorizzontaledipunti. 2. Disegna,nelsecondoquadrante,unafilaverticaledipunti. 3. Disegna,nelterzoquadrante,iverticidiunrettangolo. 4. Disegnanelquartoquadranteiverticidiunquadratoconilatinonparalleliagliassi. Primadiprocederedobbiamoripulireilnostropiano: >>> pyigplane.reset() IpuntisonoglielementibasediognicostruzionePyig,maperrealizzarecostruzionigeome tricheciservonoalcunialtrielementi.Ilprimostrumentousatonellageometrialarigache permetteditracciarelineerettepassantiperduepunti.Oltreallerette,duepuntidefinisconoan chesegmentiesemirette.Pertracciareunarettaciservonoquindiduepunti,dobbiamocrearlie metterliinduevariabiliinmododapoterfareriferimentoadessi: metto in p1 un punto metto in p2 un altro punto creo una linea che passa per p1 e p2 InPython: >>> p1=Point(-2, 4) >>> p2=Point(5, -3) >>> l1=Line(p1, p2) Perquellocheriguardalageometria,potremmoaccontentarci,masiccomeanchel'occhiovuole lesuaparte,vediamosubitocomemodificareicolorieledimensionideglioggettigrafici.Ilco lorerappresentatodaunastringainquestoformato:#RRGGBBdoveRRGGeBBsononu meriesadecimali(compresitra00eff)cherappresentanorispettivamentelecomponenti Rosse,VerdieBludelcolore.Sevogliamoquindidisegnareduepuntigrossicoloratieuna rettapispessacolorataancheleichepassaperquestiduepunti,possiamoscrivere:

120

Laboratoriodiinformatica

Elementifondamentali

>>> p3=Point(2, 6, color="#f0a000", width=8, name="A") >>> p4=Point(-2, -6, color="#00f0a0", width=8, name="B") >>> l2=Line(p0, p1, color="#a000f0", width=4)

Riassumendo Perleggerelalibreriadellageometriainterattivasiusailcomando:from pyig import *. Percreare: unpunto:Point(x, y [visible, color, width, name, internal]). una retta: Line(p0, p1 [visible, color, width, name, internal]). unsegmento: Segment(p0, p1 [visible, color, width, name, internal]). unasemiretta: Ray(p0, p1 [visible, color, width, name, internal]). unangolo: Angle(p0, p1 [visible, color, width, name, internal]). Provatu 5. Pulisciilpianoedisegna4puntietuttelepossibilirettechelicontengonoaduea due. 6. Pulisciilpianoedisegnaunpuntoinogniquadrantee4segmenti(Segment)che forminounquadrilateroconvesso.Trascinaipuntiinmodocheilquadrilaterodiventi concavopurmantenendounverticeperogniquadrante.Muovituttoilquadrilatero nelsecondoquadrante. 7. Pulisciilpianoedisegnaunpentagonodelimitatodasemirette(Ray). 8. Disegnaunangolo(Angle).Disegnaancheisuoilati. 9. Illustragraficamenteladefinizionediangoloconcavoeconvessovisualizzandoin mododiversoilatidell'angoloeisuoiprolungamenti.

Geometriainterattiva

121

Circonferenzeeintersezioni

3.2. Circonferenzeeintersezioni
Comedisegnarecirconferenzee usareintersezionitraoggetti.
Lageometriagrecausavaduestrumenti:lariga,nongraduata,eilcompasso:pyigpermettedi tracciarecirconferenzedatiilcentroeunpunto. >>> centro=Point(2, 3) >>> p0=Point(-2, 1) >>> c0=Circle(centro, p0) Seilnostroprogrammanonhabisognodiusareulteriormenteiduepuntiusatiperindividuare lacirconferenza,possiamousareunaltrometodoperdisegnarla.Ripuliamoloschermo: >>> pyigplane.reset() Possiamocrearelacirconferenzacreandoalvoloiduepuntinecessari,senzaassegnarliavaria bili: >>> c0=Circle(Point(2, 3), Point(-2, 1)) Ipuntisarannocomunquevisibilielisipotrannotrascinarenelloschermo. Provatu 1. Disegna,unacirconferenzacheabbiaspessoreecolorediversidaquellipredefiniti. 2. Disegnaduecirconferenzeconcentriche. 3. Disegnaduecirconferenzeconunpuntoincomune. L'operazionefondamentaleconleretteelecirconferenzequelladitrovareleintersezioni.Co struiteduerette,leintersezionisitrovanoconilcomandoLineLineIntersection: >>> pyigplane.reset() >>> r0=Line(Point(-6, -6), Point(3, -6)) >>> r1=Line(Point(-3, -2), Point(0, 4)) >>> i=LineLineIntersection(r0, r1, width=8, color="#a6a646", name="I") Possiamotrascinareipuntibaseefarmuovereleretteediconseguenzalalorointersezione. Ilpuntocostrovatopuvenirusatoinqualunquepostodoveservaunpunto,peresempiopu essereilcentrodiunacirconferenzapassanteperl'origine: >>> circ=Circle(i, Point(0, 0), color="#b6b616")

122

Laboratoriodiinformatica

Circonferenzeeintersezioni

Cosasuccedeseleduerettedipartenzasonoparallele? L'intersezionetraunarettaaunacirconferenzacomplicatadalfattoche...cenesonodue. Dobbiamosegnalareapyigqualedelledueintendiamo.Losifapassandoalcostruttoredel l'oggetto LineCircleIntersection unterzoargomentoobbligatoriochepuassumere soloivalori1o-1: >>> i1=LineCircleIntersection(r0, circ, -1, width=8, color="#f6a666") >>> i2=LineCircleIntersection(r0, circ, +1, width=8, color="#66a6f6") Leintersezionii1ei2possonoessereusatecometuttiglialtripuntipercostruirealtrioggetti geometricicomesegmenti,rette,circonferenze,... Provatu 4. Conriferimentoaglielementicostruitiprecedentemente,disegnaiduesegmentiche hannounestremonelpunto(9, 0)eglialtriestremiini1ei2. 5. Muovendounpuntobasedellarettar0cosasuccedealleintersezioni? 6. Comedevonoessereipuntibasedellarettaperchesistanosempreleintersezioni? 7. Quandoun'intersezionenonesiste,cosasuccedeaglielementichedipendonodaque sta? Anchetraduecirconferenzeleintersezionipossonoesseredueequindianchel'oggettointerse zionetraduecirconferenzehabisognodell'argomentochepermettadidistinguerle.Vistoil nomedatoalleintersezionitraretteetraunarettaeunacirconferenzanondifficileimmagina requellosceltoperl'intersezionetraduecirconferenze...Ripuliamoloschermoedisegniamo duecirconferenze,lelorointersezionieilsegmentochehaperestremiquestiduepunti. >>> pyigplane.reset() >>> c0=Circle(Point(-3, 2), Point(1, 2)) >>> c1=Circle(Point(3, -2), Point(-1, -2)) >>> i0=CircleCircleIntersection(c0, c1, 1, width=8, color="#999999") >>> i1=CircleCircleIntersection(c0, c1, -1, width=8, color="#999999") >>> s=Segment(i0, i1, color="#99ff99") Bene,conquestielementi,sipuincominciarearisolverequalcheproblemageometrico,ma primaconvieneprendereunpo'lamanoconqualcheesercizio.

Geometriainterattiva

123

Circonferenzeeintersezioni

Riassumendo pyigmetteadisposizionetreclassipercostruireintersezionitraoggetti: Trarette: LineLineIntersection(line0, line1 [, visible, color, width, name, internal]). Traunarettaeunacirconferenza: LineCircleIntersection(line, circle, which [, visible, color, width, name, internal]). Traduecircnferenze: CircleCircleIntersection(circle0, circle1, which [, visible, color, width, name, internal]). Provatu 8. Disegnaunacirconferenza,unasemirettaconl'originenelcentrodellacirconferenza eilpuntodiintersezionedellasemirettaconlacirconferenza. 9. Disegnaunacirconferenza,unsegmentononvisibileconunestremonelcentrodella circonferenzaeilpuntodiintersezionedelsegmentoconlacirconferenza. 10. Disegna: 1. duecirconferenzec0ec2, 2. duesegmentis0es1invisibiliconunestremoincomuneel'altrocoincidente conicentridellecirconferenze, 3. ilsegmentochehaperestremileintersezionideiduesegmenticonleduecircon ferenze.

124

Laboratoriodiinformatica

Lacongruenza

3.3. Lacongruenza
Comedisegnareuntriangoloequilatero comerealizzareiltrasportodisegmenti.
Innanzituttociponiamoilproblemadidisegnareuntriangoloequilatero.Avendoglistrumenti perrealizzarecirconferenzeeintersezioni,ilproblemanonpresentaparticolaridifficolt: - disegno due punti e il segmento che li congiunge, - disegno le circonferenze centrate negli estremi del segmento che hanno per raggio il segmento stesso, - il terzo vertice del triangolo una delle intersezioni di queste due circonferenze, - disegno gli ultimi due lati. InPython: >>> from pyig import * >>> a=Point(-3, -1, width=8, color="#50f050", name="A") >>> b=Point(1, -3, width=8, color="#50f050", name="B") >>> l1=Segment(a, b) >>> c0=Circle(a, b, width=1) >>> c1=Circle(b, a, width=1) >>> c=CircleCircleIntersection(c0, c1, 1, width=8, color="#f050f0", name="C") >>> l2=Segment(b, c) >>> l3=Segment(c, a) Oraabbiamotuttiglistrumentipertrasportareunsegmentoinmodocheunestremocoincida conundatopunto. Ripuliamoilpianoedisegniamounsegmento: >>> >>> >>> >>> from pyig import * a=Point(-3, 2, width=6, color="#a0f050", name="A") b=Point(0, 1, width=6, color="#a0f050", name="B") s=Segment(a, b)

Disegnamooraunpuntochesarl'estremodiunnuovosegmentocongruenteas: >>> c=Point(2, 4, width=6, color="#a0f050", name="C") Beneoratroviamoilterzovertice(v)diuntriangoloequilateroconunlatougualeabc(trac ciando,comeprima,leduecirconferenzeel'intersezione):

Geometriainterattiva

125

Lacongruenza

>>> circ_bc=Circle(b, c, width=1) >>> circ_cb=Circle(c, b, width=1) >>> v=CircleCircleIntersection(circ_bc, circ_cb, 1, color="#f050a0", name="V") Oratracciamoduesemiretteconorigineinvepassantiperbeperc: >>> semir_vb=Ray(v, b, width=1) >>> semir_vc=Ray(v, c, width=1) Orapossiamoriportarelalunghezzadiabsullasemirettavb(puntoa1)elalunghezzadique st'ultimosegmentosullasemirettavc(puntod): >>> circ_ba=Circle(b, a, width=1) >>> a1=LineCircleIntersection(semir_vb, circ_ba, 1, color="#f050a0", name="A'") >>> circ_va1=Circle(v, a1, width=1) >>> d=LineCircleIntersection(semir_vc, circ_va1, 1, width=6, color="#f050a0", name="A'") Ilsegmentocdcongruenteadab: >>> s1=Segment(c, d) Possiamochiedereapyigdimostrarcilalunghezzadisedis1: >>> t0=VarText(6, -7, "lunghezza di AB=%s", (s.length(),)) >>> t1=VarText(6, -8, "lunghezza di CD=%s", (s1.length(),)) GliargomentiobbligatoriinVarTextsono: ascissaeordinatadellaposizionedovevogliamovengavisualizzatoiltesto, stringadiformatoconlapartefissaedeisegnaposti("%s")perlapartevariabile, unatuplacontenentetantioggettiquantisonoisegnaposti.Sec'unsolooggettoob bligatoriaquellastranavirgolaprimadelleparentesichiuse. Riassumendo Conpunti,segmenti,circonferenzeeintersezionipossibilecostruiretriangoliequilateri. Usandoiltriangoloequilateropossibiletrasportareunsegmentoinmododamantenerne lalunghezza. Usaregliattributideglioggettipermettedirendereildisegnopicomprensibile.Inpartico lareutilecheipuntibaseabbianouncolorechelidistinguadaglialtrioggetti. possibileinserirenellafinestragraficadellescrittedalcontenutofissoovariabile. LasintassidiText:
Laboratoriodiinformatica

126

Lacongruenza

Text(x, y, text [, visible, color, width, name, internal])

LasintassidiVarText: VarText(x, y, text, var [, visible, color, width, name, internal])

Provatu 1. Modificalaposizioneinizialedeitrepunti. 2. Modificailcoloreelospessoredelsegmento. 3. Coloraingrigiolelineedicostruzione. 4. Sceglil'altraintersezionedelleduecirconferenze,lacostruzionefunzionaancora? 5. Scriviuntitolousandol'oggettoText. 6. Spostalescrittet0et1. 7. Modificailtestopresenteinquesteduescritte. 8. Scrivileistruzionipertrasportareun segmentosuuna semirettainmodo cheun estremocoincidaconl'originedellasemiretta.

Geometriainterattiva

127

Triangoloequilateroeprocedure

3.4. Triangoloequilateroeprocedure
Comescrivereunaprocedurachedisegniuntriangoloequilatero.
Quandoiprogettidiventanotroppocomplessi,lostrumentocheabbiamousatofinora,l'ambien tedisviluppoIDLE,presentapiinconvenientichefacilitazioni.convienescrivereprogrammi autonomi. importanted'orainpoiavviareIDLEsenzailparametro-n(seaquestopuntoquestafaccen dadel -n noncidicenienteconvieneriguardarsiilprimocapitolodellasezioneriguardante pyig!). Dalmenufileapriamounanuovafinestra(File-New Window).Salviamoquestofilecon nome(File-Save As),prestiamobeneattenzionedoveandiamoasalvarlo:devetrovarsiin unanostracartellapersonale.ancheimportantecheilnomedelfilerispecchiilsuocontenuto echeterminiconl'estensione.py. Bene,abbiamorealizzatoilnostroprimoprogramma...sconsolatamentevuotoadireilvero! Nonc'problema,incominciamoariempirlo.Leprimeistruzionichedobbiamoscrivere,in ogniprogramma,sonodelleistruzioniche...nonfannoniente!Dobbiamosempreiniziareun programmacondeicommentichedianoalcuneinformazioniessenzialipercapirecosafaccia senzabisognodianalizzaretuttoilcodice.Leinformazioniminimechedevonoesserepresenti nelnostroprogrammasono: 1. Nomedelfile 2. TitoloBrevedescrizione 3. Data 4. Autore 5. Licenza InPythoncisonomoltimodiperscriveredeicommenti,quellocheusiamoquiconsistenell'i niziarelarigaconilcaratteredicancelletto:#: # # # # # triangolo.py Costruzione di poligoni regolari 06-10-06 Daniele Zambelli Licenza GPL

Aquestopuntoilprogrammanonfaancoraniente,macidicequalcosa.Aggiungiamodue istruzionifondamentali: from pyig import * pyigplane.mainloop() Unavoltascrittotuttocinelfiletriangolo.pypossiamoeseguirloconilcomandoRun128 Laboratoriodiinformatica

Triangoloequilateroeprocedure

RunModuleopremendoiltasto<F5>.Comeeffettodiquestoprogrammaapparelasolitafi nestragraficacongliassicartesianielagriglia,manonc'alcunoggettografico.Abbiamogi vistoqualicomandiservonoperdisegnareuntriangoloequilatero,oraraggruppiamoquestico mandiinunafunzione.Unafunzioneunbloccodicodiceassociatoadunnome.Vogliamo chealnometriequisianoassociateleistruzioninecessarieperdisegnareiltriangolo.Questa funzionehabisognodidueinformazioni:idueestremidelprimolatodeltriangolo.Questein formazionisichiamanoargomentidellafunzioneesonomemorizzateneiparametri.Lasintassi perladichiarazionediunafunzionelaseguente: def <nome della funzione>(<elenco di parametri>): <istruzioni> Pereseguireunafunzionebastascrivere: <nome della funzione>(<elenco degli argomenti>) Recuperiamoleistruzionidelcapitoloprecedenteescriviamolafunzione: def triequi0(p0, p1): """Costruisce un tri. equi. dati due vertici p0 e p1.""" c0=Circle(p0, p1, visible=False) c1=Circle(p1, p0, visible=False) p2=CircleCircleIntersection(c0, c1, 1, width=8, color="#f050f0") l0=Segment(p0, p1) l1=Segment(p1, p2) l2=Segment(p2, p0) Perprovarladobbiamoscrivereletreistruzioni: a=Point(3, 5, width=8, color="#a0f050") b=Point(6, 4, width=8, color="#a0f050") triequi(a, b) Possiamoaggiungereunparametrochepermettadivisualizzareomenolelineedicostruzionee usareunnuovooggetto,Polygon,checostruiscaunpoligonodatiivertici: def triequi(p0, p1, costruzione=False): """Costruisce un tri. equi. dati due vertici p0 e p1.""" c0=Circle(p0, p1, visible=costruzione, width=1) c1=Circle(p1, p0, visible=costruzione, width=1) p2=CircleCircleIntersection(c0, c1, 1, width=8, color="#f050f0") p=Polygon((p0, p1,p2))

Geometriainterattiva

129

Triangoloequilateroeprocedure

Ilparametrocostruzioneopzionale.senonvienescrittounargomentoprendeautomati camenteilvaloredatodidefault,inquestocasoFalse. Riassumendo Unprogrammaundocumentoditestochepuessereinterpretatoattraversounlinguaggio edeseguitodaunesecutoreautomatico. Inogniprogrammasonoimportantissimideicommenticheesplicitinocosafailprogram maecosafaognisuaparte. InPythonsonocommenti: leporzioniditestocheseguonoilcaratterecancelletto:#, Lestringheliberedelimitatedatrecaratteridiapicesiadoppichesingoli. Lasintassiperdefinireunaprocedura: def <nome della funzione>(<elenco di parametri>): <istruzioni>

Provatu 1. Disegnatrecoppiedipuntietretriangoliequilateri. 2. Disegnailsimbolodipericoloradioattivo. 3. Modificalaproceduratriequiinmodochesipossascegliereilcoloreelospesso redeilatideltriangolo. 4. Scrivilaproceduraesagonochedisegniunesagonoregolare. 5. Disegnauntriangoloqualsiasi.Suognilatocostruisciuntriangoloequilatero.

130

Laboratoriodiinformatica

Poligoniregolariefunzioni

3.5. Poligoniregolariefunzioni
Comescrivereunafunzionechediacomerisultatounoggetto.
NelcapitoloprecedenteAbbiamoscrittounaprocedurachedisegnauntriangoloequilatero.Ma potrebbeesserciutileavereunpezzodicodicechenonsolodisegniunoggetto,malodiacome risultato.L'istruzionechepermettediterminareunafunzionerestituendounrisultatoilco mandoreturn <espressione>. Creiamounanuovafinestradieditoresalviamolaconilnomepoligoni.py,scriviamoiso liticommentidiintestazioneconleinformazioniessenzialiescriviamoiduecomandidibase perlagraficainterattiva(from pyig import *epyigplane.mainloop()).Traque stiduecomandidobbiamoscrivereilnostroprogramma.Riprendiamoquellogiscrittomamo difichiamolafunzionetriequiinmodocherestituiscailtriangoloequilaterodopoaverlodi segnato,aggiungiamoancheleistruzioniperprovarelafunzione.Ilprogrammadiventa: # # # # # poligoni.py Costruzione di poligoni regolari 10-10-06 Daniele Zambelli Licenza GPL

from pyig import * def triequi(p0, p1, costruzione=False): c0=Circle(p0, p1, visible=costruzione, width=1) c1=Circle(p1, p0, visible=costruzione, width=1) p2=CircleCircleIntersection(c0, c1, 1, width=8, color="#f050f0") return Polygon((p0, p1,p2)) a=Point(3, 5, width=8, color="#a0f050") b=Point(6, 4, width=8, color="#a0f050") t=triequi(a, b, True) pyigplane.mainloop() Finquiabbiamocambiatobenpoco,maconvienecomunqueprovareilfunzionamentodelpro gramma: proviamo ad eseguirlo con il comando Run-Run Module o premendo il tasto <F5>.Setuttofunzionarimbocchiamocilemanicheeiniziamolacostruzionedelquadrato(al trimenticorreggiamoglierrorieriproviamoilprogramma).Primadiiniziareascriverecodice ciconvienerealizzarelacostruzioneconrigaecompasso.dandounnomeatuttiglioggettidi segnatieriportandounasinteticalegenda.TradottaconcommentiPythonpotrebbeessere:
Geometriainterattiva 131

Poligoniregolariefunzioni

def quadrato(p0, p1, costruzione=False): """Quadrato dati gli etremi di un lato, se costruzione==True si vedono gli elementi di costruzione.""" # c0 la circonferenza di centro p0 e passante per p1 # c1 la circonferenza di centro p1 e passante per p0 # i1 il punto di intersezione delle due circonferenze # c2 la circ. con centro in i1 e passante per p0 e p1 # i2 l'intersezione tra questa circ. e la circ. c0 # c3 la circonferenza di centro i2 e passante per p0 # i3 l'intersezione tra le circonferenze c2 e c3 # r la retta passante per p0 e i3 # p3 l'inter. tra r e c0, il quarto vert. del quadrato # c4 la circonferenza di centro p3 passante per p0 # p2 l'inter.e tra le circ. c4 e c1, il terzo vertice # il ris il poligono che ha per vert.: (p0, p1, p2, p3) Unavoltacompletataladescrizionesipuiniziareasostituireunarigadicommentoallavolta provandoognivoltal'effettodelleaggiunteecontrollandobenechefaccianoesattamentequello chedesideriamo.Inparticolaredobbiamocontrollarecheleintersezionitralecirconferenzesia noquellegiuste.Perprovareilprogrammadobbiamoancheaggiungere,primadelcomando pyigplane.mainloop()trerighesimiliaqueste: c=Point(-6, 2, width=8, color="#a0f050") d=Point(-3, 3, width=8, color="#a0f050") q=quadrato(c, d, True) Leprimesostituzionideicommentiproduconolaseguentefunzione:

132

Laboratoriodiinformatica

Poligoniregolariefunzioni

def quadrato(p0, p1, costruzione=False): """Quadrato dati gli etremi di un lato, se costruzione==True si vedono gli elementi di costruzione.""" c0=Circle(p0, p1, visible=costruzione, width=1) c1=Circle(p1, p0, visible=costruzione, width=1) i1=CircleCircleIntersection(c0, c1, 1, visible=costruzione) # c2 la circ. con centro in i1 e passante per p0 e p1 # i2 l'intersezione tra questa circ. e la circ. c0 # c3 la circonferenza di centro i2 e passante per p0 # i3 l'intersezione tra le circonferenze c2 e c3 # r la retta passante per p0 e i3 # p3 l'inter. tra r e c0, il quarto vert. del quadrato # c4 la circonferenza di centro p3 passante per p0 # p2 l'inter.e tra le circ. c4 e c1, il terzo vertice # il ris il poligono che ha per vert.: (p0, p1, p2, p3) Conunpo'dipazienzaognitesseradelpuzzlevaapostoeotteniamolafunzionedesiderata. importanteprovarespessol'effettodeicambiamentiodelleaggiunte,nonscoraggiarsipergli errori:correggereiproprierrorilaprincipaleattivitdichiprogramma. Riassumendo Unafunzionepurestituireunqualunqueoggetto,possiamoquindiscriverefunzioniche dannocomerisultatounpoligono. Ilcomandocheterminaunafunzioneenerestituisceunrisultatoreturn,lasuasintassi : return <espressione> Provatu 1. Aggiungiallafunzionequadratoiparametriperdefinireilcoloredellasuperficie,del bordo,lospessoredelbordoeseilpoligonovisibileoppureno. 2. Scrivilafunzionechecostruisceeriportaunesagonoregolarepartendodaduevertici consecutivi. 3. Scrivilafunzionechecostruisceeriportaunottagonoregolarepartendodadueverti ciconsecutivi. 4. Scrivilafunzionechecostruisceeriportaunpentagonoregolarepartendodaduever ticiconsecutivi.

Geometriainterattiva

133

Unalibreriadifunzioni

3.6. Unalibreriadifunzioni
Comescrivereunaraccoltadifunzioniutili.
Lafunzioneperdisegnareunquadratorisultapiuttostopesante:unadozzinadirighedispostein sequenzasenzaunabenprecisastruttura.Selaanalizziamo,scopriamocheleprime8righeser vonoperdisegnarelarettaperpendicolarealsegmentoABpassanteperA.Sarebbecomodo avereunafunzionecherestituiscaquestaretta,lacostruzionedelquadratoneverrebbedecisa mentesemplificata. Lageneralizzazionediquestaidea,ininformatica,haportatoallacostruzionedilibreriedifun zioni,opiingenerale,dioggetti.VediamocomesifaarealizzareunalibreriaperPython,ci poniamol'obiettivodirealizzarealcunistrumentigraficiutiliperlacostruzionedinuovefigure. Comeilsolitopartiamodallacreazionediunnuovofilechechiameremoattrezzi.py.Nel leprimerighediquestofilescriviamoalcunicommentichenedescrivonoilcontenuto,ad esempio: # # # # # # attrezzi.py Funzioni che producono oggetti da utilizzare in altri progetti 20-10-06 Daniele Zambelli Licenza GPL

Datochevogliamolavorareconlageometriainterattiva,aquestopuntodobbiamocaricarelali breriapyig: from pyig import * Ilbuonsensodirebbe,aquestopunto,diiniziareascriverelefunzionidellalibreria,masembra miglioreunaltroapproccio:scriviamo,prima,unafunzionecheusilefunzionichenonabbia moancorascrittoecheservadaverificadellorofunzionamento: def test(): # test della funzione ortoseg a=Point(-6, 2, width=8) b=Point(-3, 3, width=8) q=ortoseg(a, b, True) Eaggiungiamounarigacheesegualafunzione test() solosequestofileeseguitocome programmaenonsecaricatocomelibreria:

134

Laboratoriodiinformatica

Unalibreriadifunzioni

if __name__=="__main__": test() pyigplane.mainloop() Bene,seeseguiamoilprogrammafinquiscritto,sidevefermareconunerrore:lafunzioneortosegnondefinita. Aquestopuntopossiamocostruirelafunzioneortosegestraendoleprimerighedellafunzione quadrato: def ortoseg(p0, p1, costruzione=False): """Retta perp. al segmento p0 - p1, passante per p0.""" c0=Circle(p0, p1, visible=costruzione, width=1) c1=Circle(p1, p0, visible=costruzione, width=1) i1=CircleCircleIntersection(c0, c1, 1, visible=costruzione) c2=Circle(i1, p0, visible=costruzione, width=1) i2=CircleCircleIntersection(c0, c2, 1, visible=costruzione) c3=Circle(i2, p0, visible=costruzione, width=1) i3=CircleCircleIntersection(c2, c3, -1, visible=costruzione) return Line(p0, i3, visible=costruzione, width=1) Eseguendoadessoilprogrammaattrezzi.pysiottienelarettadesiderata,altrimentisiav viailsolitociclodidebug. Oralafunzione quadrato pudiventaremoltopisemplice,modifichiamoilprogramma precedente: import attrezzi def quadrato(p0, p1, costruzione=False): """Quadrato dati gli etremi di un lato, se costruzione==True si vedono gli elementi di costruzione.""" r=attrezzi.ortoseg(p0, p1, costruzione) c0=Circle(p0, p1, visible=costruzione, width=1) p3=LineCircleIntersection(r, c0, 1, visible=costruzione, width=1) c1=Circle(p3, p0, visible=costruzione, width=1) c2=Circle(p1, p0, visible=costruzione, width=1) p2=CircleCircleIntersection(c1, c2, 1, visible=costruzione, width=1) return Polygon((p0, p1, p2, p3))

Geometriainterattiva

135

Unalibreriadifunzioni

Unavoltacorrettiglieventualierrori(questanonl'hoprovata),otteniamoilnostroquadrato.Il comandoimport attrezzicaricatuttalalibreriaattrezzi;comedettosopra,conque stocomando,nonvieneeseguitalafunzionetest().Pereseguireunafunzionepresentenella libreriasidevescrivereilnomedellalibreriaseguitodaunpuntoedalnomedellafunzione: r=attrezzi.ortoseg(p0, p1, costruzione) Capitoilmeccanismoaggiungiamoaltrefunzioniallalibreria.Incominciamodaunafunzione cherestituiscal'assediunsegmento.Comeprima,incominciamoscrivendoilcodiceperiltest: def test(): # test della funzione ortoseg a=Point(-6, 2, width=8) b=Point(-3, 3, width=8) q=ortoseg(a, b, True) # test della funzione asse a=Point(-8, -7, width=8) b=Point(-6, -6, width=8) s=Segment(a, b) a=asse(a, b, True) Poi,rifacendociallatecnicacheusarigaecompasso: def asse(p0, p1, costruzione=False): """(p0, p1) -> asse del segmento p0, p1.""" c0=Circle(p0, p1, visible=costruzione, width=1) c1=Circle(p1, p0, visible=costruzione, width=1) i0=CircleCircleIntersection(c0, c1, 1, visible=costruzione) i1=CircleCircleIntersection(c0, c1, -1, visible=costruzione) return Line(i0, i1) Capitoilmeccanismopossiamorealizzarelanostracassettadegliattrezzicontuttelefunzioni checiservonoperrenderepisemplicelasoluzionediproblemigeometrici. Riassumendo Unalibreriadifunzioniunfilechecontieneladefinizionedifunzioni. Puesserecaricatoconilcomandoimport <nome_libreria>esifariferimentoad unafunzioneeffedellalibreriaelleconilcomandoelle.effe(...).Lasintassi: <nome_libreria>.<nome_funzione>(<argomenti>)

moltoutilescriveredeitestperognifunzionepresenteinunalibreria.Ilcomando: Laboratoriodiinformatica

136

Unalibreriadifunzioni

if __name__=="__main__": test() eseguetestsoloseilfileeseguitocomeprogrammaenonsecaricatocomelibreria. Provatu 1. Aggiungiallalibrerialefunzionicherestituiscano: 1. ilpuntomediotraduepunti; 2. ilpuntomediodiunsegmento; 3. ilterzoverticediuntriangolorettangolo,datiiprimiduevertici; 4. labisettricediunangolo; 5. ... 2. Modificalefunzioniprecedentiinmodochesipossaspecificareilcoloreelospesso redell'oggettorestituito. 3. possibilescrivereunaversionefunzionaledellafunzionequadrato,cioscrivere quadratosenzausarealcunaassegnazionedivariabile.Conunadeguatousodiacapo ediindentazionisiriescearenderediscretamentecomprensibileanchequestocodi ce...

Geometriainterattiva

137

Unalibreriadifunzioni

138

Laboratoriodiinformatica

Geometriaanalitica

4. Geometriaanalitica
Inquestasezionevengonopropostialcuniproblemidigeometriaanalitica.OltreaPythonvie neusatalalibreriaPyplotdiPygraph.Pyplotmetteadisposizioneunafinestrachecon tieneunpianocartesianoconlapossibilitdidisegnaregliassiedifardisegnarefunzionidel tipoy=f(x),x=f(y)opolari:ro=f(th). Perl'installazionedellalibreriaPygraph,checontieneanchePyplot,vedil'introduzione.

Geometriaanalitica

139

Geometriaanalitica

140

Laboratoriodiinformatica

Punti,segmenti,poligoni

4.1. Punti,segmenti,poligoni
Comedisegnarealcunielementigeometricinelpianocartesiano.
Lageometriaanaliticaunostrumentochepermettedicollegareduebranchedellamatematica: l'algebraelageometria.Permettequindidiaffrontareproblemialgebriciconmetodigeometrici oviceversaproblemigeometriciconstrumentialgebrici.Lostrumentochepermettedifareci ilriferimentocartesiano.LalibreriapycartforniscealcunelaclassePlanedotatadialcuni metodichepermettonodidisegnarepunti,segmenti,poligoni,oltreagliassicartesiani. Possiamoiniziaredall'ambienteIDLEpervederecomeattivarelefunzionalitdiPycart.In nanzituttodobbiamocaricarel'oggettoPlanedallalibreria: >>> from pycart import Plane Aquestopunto,setuttoandatobene,nondeveesseresuccessoniente.Seinveceappaiono dellescritterosse,vuoldirechequalcosaandatostorto,bisognaleggereilmessaggiodierrore ecercarediporrerimedio.Inparticolarebisognaesseresicuridiaverinstallatocorrettamentela libreria Pygraph.Poidobbiamocreareunpianocartesianosucuidisegnare.Tecnicamente istanziamounoggettodellaclassePlane: >>> p=Plane() Questavolta,setuttoandatobene,appareunafinestragraficavuota.LaclassePlanehadi versimetodiequindipossiamodareall'oggettopdiversicomandi.Incominciamoconchiedere apditracciaregliassicartesiani: >>> p.axes(True) Avendopassatol'argomentoTrue,oltreagliassi,verrdisegnataancheunaschieradipuntini. Orapossiamoassegnareaduevariabililecoordinatediduepunti: >>> p1=(2, 4) >>> p2=(-4, 3) Levariabilip1ep2sonoassociateoraadueoggettituplacheinPythonrealizzanosequen zeordinateimmutabili,nelnostrocaso,dellecoppieordinatedinumeri.Oracheabbiamole coordinatedeipuntichevogliamotracciarenoncirestachedireall'oggetto p didisegnarei puntipropriol: >>> p.drawpoint(p1) >>> p.drawpoint(p2) Ipuntivengonodisegnatidoverichiesto,mapudarsichecisembrinotroppopiccolieinsigni ficanti.Possiamodecideredimensioniecolore.Incominciamoripulendoilpianocartesiano:
Geometriaanalitica 141

Punti,segmenti,poligoni

>>> p.reset() Oltreacancellaretuttoquellochec'nellafinestragrafica,resetsipremuradiridisegnaregli assi.Orapossiamocambiareledimensionieilcoloredeglioggettigraficicheverrannodise gnati: >>> p.setwidth(3) >>> p.setcolor("#5050a0") Ilcolorenelformato:#RRGGBBdoveRR,GG,BBsonotrenumeriinformatoesadecimale cherappresentanorispettivamentelecomponentideitrecolorifondamentali:rosso,verde,blu. Orapossiamodisegnareiduepunti: >>> p.drawpoint(p1) >>> p.drawpoint(p2) Aquestopuntosevogliamodisegnareunsegmento,magarigiallino,possiamodarealpianopi comandi: >>> p.setcolor("#a0a050") >>> p.drawsegment((-6, 8), (5, 7)) Danotarecheilmetododrawsegmentrichiedelecoordinatediduepunti,cioduecoppiedi numeri.Nelpianocartesianounpoligonopuessereindividuatodallecoordinatedeisuoiverti ci.L'istruzione: >>> poligono1=((-7, -5), (4, -7), (2, -2), (-3, -1)) assegnaallavariabilepoluigono1unasequenzadicoppiedinumeri,pernoi,unasequenzadi coordinate.Perdisegnareunpoligonoverdinopossiamousareilmetododrawpoly,dopoaver cambiatoilcoloredellapenna: >>> p.setcolor("#50a050") >>> p.drawpoly(poligono1) drawpolyrichiedecomeargomentounasequenzadicoppiedinumeri,inquestocaso,lase quenzacontenutanellavariabile poligono1,maavremmoanchepotutopassarladiretta mentescrivendo: >>> p.drawpoly(((-7, -5), (4, -7), (2, -2), (-3, -1))) Inquestomodobisognasolofareunpo'pidiattenzionealnumerodiparentesi.Lacoppiadi parentesipiesternacontienegliargomentipassatialmetodo,lasecondacontienelalistadi punti,lealtrecontengonolecoordinate.

142

Laboratoriodiinformatica

Punti,segmenti,poligoni

Riassumendo Ilpianocartesianopresentenellalibreriapygraphmetteadisposizionevarimetoditracui: setcolor( #rrggbb )doverr,gg,bb,sononumeriesadecimalidi2cifre, setwidth(<numero>) axes([True]) drawpoint(<coordinate>) drawsegment(<coordinate>, <coordinate>) drawpoly(<sequenza di coordinate>) Provatu 1. Disegnaiverticidiunquadratoconilcentronell'originedegliassieconunvertice nelpunto(5,0). 2. Disegnaiverticidiunquadratoconilcentronell'originedegliassieconunvertice nelpunto(5,5). 3. Disegnaiverticidiuntri.equilateroconilcentronell'originedegliassieconunver ticenelpunto(5,0). 4. Disegna3segmenticonunestremonell'originedegliassi. 5. Disegna3segmenticonsecutivididiversocolore. 6. Disegna3segmentiadiacentididiversocolore. 7. Disegnaunquadratoconilatinonparalleliagliassi. 8. Disegnaunrettangoloconilatinonparalleliagliassi. 9. Disegnaunromboconunlatoparalleloall'assex. 10. Disegnauntrapeziorettangoloconlebasiparalleleall'assey. 11. Disegna10puntidiordinataparia5apartiredall'ascissa4distantiunaunitl'uno dall'atro. 12. Disegnausandosegmentilafunzionescala. 13. Disegnausandosegmentilafunzioneadentidisega. 14. Disegnalafunzionesegno.

Geometriaanalitica

143

Trasformazioni

4.2. Trasformazioni
Cometrasformarepoligoni.
Nelpianocartesianounpoligonopuessereindividuatodaisuoivertici.Poichpossiamorap presentareunpuntoconunacoppiadinumeri,unatupladidueelementi,unpoligonopues sere rappresentato da una sequenza di coppie di numeri. Iniziamo a scrivere la procedura test() checreaunpianocartesiano,unpoligonoelodisegna.Ovviamenteperprimacosa dobbiamocaricaredallalibrerialaclassePlane:

from pycart import Plane

def test(): # crea un ogg. della classe Plot e disegna gli assi piano=Plane("Trasformazioni", 600, 600, 15, 15) piano.axes(True) # predispone un pol. da cui partire per le trasformazioni poligono=((3, 4), (1, 5), (2, 3), (3, 3), (5, 1)) # modifica spessore della penna e colore piano.setwidth(2) piano.setcolor("#a0a020") # disegna il poligono piano.drawpoly(poligono) if __name__ == "__main__": test () L'ultimarigadiceaPythonchesequestofilevieneeseguitodirettamente,noncaricatocome libreria,alloradeveessereeseguitalafunzionetest(). Eseguendoilprogramma(<F5>)vienetracciatoilpoligonodivertici:(3, 4), (1, 5), (2, 3), (3, 3), (5, 1)conspessoredellapennaparia2edicoloreverdemarcio.A questopuntoaffrontiamoletrasformazionigeometriche.Laprimatrasformazionechesistudia disolitolatraslazione.Incominciamodaquesta.Pertraslareuninteropoligono,bastatraslare isuoivertici,quindiiniziamocostruendounafunzionechericevutidueargomenti,unpuntoe unatraslazionerestituiscailpuntotraslato.Tutteleprossimefunzionivannoscrittetral'istru zione:from pycart import Planeelalinea:def test():.Uncommentoche metteinevidenzalasezionerelativaallatraslazionepuessereutile.Sexpeypsonolecoordi natedelpuntoexteytsonolecomponentidellatraslazione,lecoordinatedelpuntotraslato sono:xp+xteyp+yt.InPython,permettereidueelementidiunacoppiainduevariabili, possibileusaregliindici:

144

Laboratoriodiinformatica

Trasformazioni

xp=punto[0] yp=punto[1] oppureusareunasintassipidirettae,amioavviso,piespressiva: xp, yp = punto Aquestopuntopossiamorealizzarelafunzionetraslapunto(punto, traslazione): ##### # Traslazione ### def traslapunto(punto, traslazione): xp, yp = punto xt, yt = traslazione return xp+xt, yp+yt Quisonoandatoincrisi,buonanormacorredaretuttelefunzionidiopportunicommenti,ma nonsonoriuscitoatrovarequalchefrasechepotessechiarireilsignificatopidiquantogifac ciailcodice. Ilpassosuccessivoscrivereunafunzioneche,dataunasequenzadipuntieunatraslazione,re stituiscaunasequenzachecontengaipuntitraslati.AncheinquestocasoPythonmetteadi sposizioneduemetodi.Conilprimosipartedaunalistavuotaresulte,perognielemento dellasequenzapoligono,siaggiungeilsuotraslatoallalistaresult: def traslapoli(poligono, traslazione): result=[] for vertice in poligono: result.append(traslapunto(vertice, traslazione)) return result LostessoeffettopuessereottenutoconuncostruttotipicodiPython:lacostruzionediliste: ilrisultatolalistachehaperelementiitraslatiinbasea traslazionedeglielementidi poligono: def traslapoli(poligono, traslazione): return [traslapunto(vertice, traslazione) for vertice in poligono] Moltosintetica,maunavoltachecisiabitua,anchemoltoespressiva. Aquestopuntononcirestacheaggiungereallafunzionetest()leistruzioniperdisegnareilpo ligonotraslato.Dopolarigapiano.drawpoly(poligono)scriveremo:

Geometriaanalitica

145

Trasformazioni

# Traslazione piano.setcolor("#20a0a0") piano.drawpoly(traslapoli(poligono, (-10, 5))) Oraabbiamotuttiglistrumentiperrealizzarelealtretrasformazionicheconosciamo. Riassumendo Unpuntopuessererappresentatodaunacoppiadinumeri. Unpoligonopuessererappresentatodaunasequenzadicoppiedinumeri. PycartmetteadisposizionelaclassePlainche,traglialtri,haimetodi: axeschedisegnagliassicartesiani, drawpolychedisegnaunpoligono. Latrasformazionediunpoligonopuessererealizzatainduepassi: latrasformazionediunpunto, l'applicazionedellatrasformazioneatuttiipuntidelpoligono.

Provatu 1. Realizzalasimmetriarispettoall'assey:scrivilafunzionecherestituisceilsimmetri codiunpunto,scrivilafunzionecherestituisceilsimmetricodiunpoligono,aggiun giallafunzionetest()lelineenecessarieperdisegnare,conuncolorediverso,il simmetricodipoligono. 2. Realizzalasimmetriarispettoall'assex. 3. Realizzalasimmetriarispettoall'origine. 4. Realizzal'omotetia. 5. Realizzalasimmetriarispettoadunarettaparallelaall'assex 6. Realizzalasimmetriarispettoadunarettaparallelaall'assey.

146

Laboratoriodiinformatica

Rette,parabole,cubiche...

4.3. Rette,parabole,cubiche...
Comedisegnarerettecheattraversanoilnostropianocartesiano.
L'attivitsvoltaneicapitoliprecedenti,usaimetodidellaclassePlaindefinitanellalibreria pycart.Se vogliamodisegnareil graficodifunzioni,dobbiamo usareimetodifornitida un'altraclassedefinitanellalibreriapyplot.QuestanuovaclassePlotchefornisceimeto di che permettono di tracciare funzioni di una variabile del tipo y=f(x) con il metodo xy("<funzione in x>")ox=f(y)usandoilmetodoyx("<funzione in y>"). Sevogliamotracciareunarettapossiamousareunodeiduemetodiprecedenti.L'equazione esplicitadellaretta:y=mx+q.quest'equazionepermetteditracciarequasituttelerettedelpia no...nerestanoesclusesoloinfinite,tuttequelleparalleleall'assey. Pertracciarelarettadiequazione: y= 1. caricarelalibreriapyplot, >>> from pyplot import * 2. predisporreilpianocartesiano, >>> p=Plot() 3. possotracciaregliassi,chefannosemprecomodo, >>> p.axes(True) 4. inviarealpianoilcomandodirappresentarelaretta: >>> p.xy("2/3*x+4") Vienetracciataunaretta...peccatochenonsiaquellacheciaspettiamo,seilcoefficienteango lare2/3,nondovrebbeessereparallelaall'assex!IlfattochePython,quandoesegueuna divisionetranumeriinteri,calcolailquozientetroncandoilnumerosenzaidecimali.Ilcalcolo 2/3inPythondcomerisultato0perottenereilnumerorazionale2/3devoriscriverel'e spressioneinmodocheoilnumeratoreoildenominatoresiaunnumeroditipofloat: >>> p.xy("2./3*x+4") Perpotertracciareunarettaparallelaall'asseydevousareilmetodochepermetteditracciare funzionideltipox=f(y),quindiperdisegnarelarettadiequazionex=4bastadareilcoman do: >>> p.yx("4")

2 3

x4 devo

Geometriaanalitica

147

Rette,parabole,cubiche...

Perpoteraffrontareproblemipisignificativi,utileunafunzionechedatiduenumeri,ilcoef ficienteangolareeilterminenoto,producalastringachecontienelafunzionedellaretta.La possiamorealizzareconilmeccanismodellacostruzionedistringheusandoisegnaposto%s comespiegatocondiversiesempineiprimicapitolisullaprogrammazioneinPython. >>> def retta(m, q): return "%s*x+%s" % (m, q) Facciamounaprovastampandolastringaottenuta: >>> print retta(3./5, 6) 0.6*x+6 Possiamoorausarequestafunzionepertracciareunasequenzadiretteconilcoefficientecheva da0a10.Innanzituttoripuliamoilpianodalleretteprecedenti: >>> p.reset() poiavviamounciclochedisegnitutteleretterichieste: >>> for m in range(11): p.xy(retta(m, 4)) Sevolessimodisegnareleretteconcoefficienteangolare1/2,1/3,1/4,...1/10,lafaccendasa rebbeunpochinopicomplicataperduemotivi: BisognacostringerePythonafareladivisioneinvirgolamobileenontroncandoilrisul tato, Ilprimovalorediizeroequandonelciclositentadieseguireladivisione1/isiottie neunerrore. Lasoluzionealprimoproblemasiottienescrivendo1./iinveceche1/i.Perrisolvereilse condoproblema,bisognamodificareilcicloinmodocherangerestituiscagliinteriapartire da1anzichda0:range(1, 11): >>> for num in range(1, 11): p.xy(retta(1./num, 4)) Lafunzionepassatacomeargomentoalmetodoxy()ovviamente,puesserecostruitaafanta sia,bastacherispettilasintassidiPython.Seilpolinomiodisecondogradootterremouna parabolaconl'asseparalleloall'assey: >>> p.xy("0.5*x*x-2./3*x+4") Anchequi,perinostriesperimenticonvienecostruireunafunzionechedatiitrecoefficientidel trinomiodisecondogradorestituiscalastringachelorappresenta:

148

Laboratoriodiinformatica

Rette,parabole,cubiche...

>>> def parabola(a, b, c): return "%s*x*x+%s*x+%s" % (a, b, c) epossiamoprovarlastampandoilsuorisultato: >>> print parabola(-.5, -1, 3) -0.5*x*x+-1*x+3 ochiedendoapyplotdidisegnarlaperpunti: >>> p.reset() >>> p.xy(parabola(-.5, -1, 3)) Aquestopuntopossiamocostruirciglistrumentipertracciareparabolecubicheopolinomidi 4,5,6,...gradoosservandocomecambialaformadelgraficoalvariaredeicoefficienti. Riassumendo Ilmetodo xy(<funzione>) dellaclasse Pyplot permetteditracciareunaqualunque funzionedatanellaformay=f(x). Lafunzionepassataalmetodocomeargomentodeveessereunastringa. Lastringapuesserescrittapariparidatastieraoppurepuesserecostruitausandoimetodi messiadisposizionedaPython. Provatu 1. Disegnaunafamigliadirettediversesoloperilcoefficienteangolare. 2. Disegnaunafamigliadirettediversesoloperilterminenoto. 3. Qualilsignificatodelterminenoto? 4. Qualilsignificatodelcoefficienteangolare? 5. Cambialospessoredelgrafico. 6. Disegnagraficididiversocolore. 7. Disegnadellefamigliediparabolevariandounoallavoltaicoefficienti. 8. Individuailsignificatogeometricodei3coefficientidell'equazionedellaparabola. 9. Ingeneralequantegobbehaunafunzionedigradoenne? 10. Facendodiverseproverispondi:quanteintersezionipuavereunarettaconl'asse dellex?eunaparabola?eunaparabolacubica?eingeneraleunacurvadigrado enne? 11. Qualelcaratteristicacheaccomunaigraficidituttelefunzionibinomialideltipo: y=ax^n+b(ades.y=0.2*x**4 +7)?

Geometriaanalitica

149

RetteedestensionedellaclassePlot

4.4. RetteedestensionedellaclassePlot
Comerisolvereproblemidigeometriaanalitica ecomeampliarelecapacitdeigipotentistrumentimessiadisposizionedaPygraph.
FinoraabbiamopasticciatoscrivendocomandinellafinestrainterattivadiIDLE,oragiuntoil momentodiscrivereunprogramma.Scriviamoilprogrammacherisolvauntipicoproblemadi geometriaanalitica:calcolarel'equazionedellarettapassanteperduepuntiedisegnarla. PrimadiaffrontareiproblemiperdecidiamocomerappresentareinPythonunaretta.Laso litaequazioneinduevariabiliinformaesplicitay=mx+qoimplicita:ax+by+c=0non comoda:complicatoestrarreleinformazionidaunastringascrittainquestomodo.Comeper rappresentareunpuntousiamounacoppiadinumeri,cospossiamousareunacoppiadinumeri (m, q)perrappresentareunaretta.Dalcapitoloprecedentepossiamorecuperarelafunzione retta(m, q)che,datiiduecoefficientiproducal'espressioneeseguibiledellafunzioneret ta. Altraosservazione.SarebbecomodocheglioggettidellaclassePlotavesserolacapacitdi disegnare rette, ma purtroppo non cos, hanno il metodo drawpoint, drawsegment, drawpoly,manonunmetododrawline.Pythonpermettediestenderefacilmenteleca pacitdiunoggetto.Possiamocostruireunaclassechederivatuttelecaratteristichedellaclasse Plot eaggiungeadessailmetodo drawline(retta).Lanuovaclasselachiameremo Mioplot.Unaconvenzione,accettatadatuttiipitonisti,prevedecheinomidelleclassiinizi noconlaletteramaiuscolaenoiciadeguiamovolentieri,perrenderepicomprensibileilno strocodice.PerdireaPythonchevogliamocreareunanuovaclassecheestendelecapacitdi un'altrapreesistente,possiamousarelaseguentesintassi: class Nuovaclasse(vecchiaclasse): <nuovi metodi> Noncirestacheincominciareascrivere.Predisponiamounnuovofile,salviamoloconilnome rette.py,scriviamoalcunerighedicommentoconlesoliteinformazioni:autore,data,contenuto delfile,... Poichlanostranuovaclassederivadallaclasse Plot contenutanellalibreria pyplot.py dobbiamoinnanzituttofarcaricarequestaliberiaconilcomando: from pyplot import Plot Orasiamoprontipercrearelanuovaclasse: class Mioplot(Plot): LaclasseMioplothatuttelecaratteristicheelecapacitdellaclassePlot,manoivogliamo estenderlecondeinuovimetodi.Ilprimoservepertrasformarelacoppiadinumericherappre
150 Laboratoriodiinformatica

RetteedestensionedellaclassePlot

sentaunarettainun'espressionelineareinterpretabiledaPython.Imetodidiunaclassehanno sempre,comeprimoparametrounavariabilecheconterrilriferimentoall'oggettosucuiilme tododevelavorare.Perconsuetudineaquestoparametrovienedatoilnomeself.Quindiil metodorettadevefarprecedereidueparametri:coefficienteangolareetermine notodalparametroself: def retta(self, r): """Restituisce la stringa che contiene la funzione di una retta.""" return "%s*x+%s" % r L'altrometodocheaggiungiamoaPlotserveperdisegnarelarettarappresentatadaunacop piadipunti: def drawline(self, r): """Disegna una retta dati (coeff.angolare, termine noto).""" self.xy(self.retta(r)) Benenoncirestachescriverelafunzionechecalcolalarettaperduepuntiepoiprovaretutto. Recuperiamodaqualcheparteilmodopercalcolarecoefficienteangolareeterminenotodiuna rettachepassiperduepunti,qualcosacome: m=

ybya xbxa

e q=yamxa :

def retta2p(a, b): """Restituisce m e q della retta passante per a e b.""" xa, ya = a xb, yb = b m=float(yb-ya)/(xb-xa) q=ya-m*xa return m, q Edorapossiamoscrivereuntestperlenostrefunzioni:

Geometriaanalitica

151

RetteedestensionedellaclassePlot

def test(): piano=Mioplot() # Crea un oggetto della classe Mioplot piano.axes(True) # chiede a piano di disegnare gli assi p0=(-4, -5) # Associa alle var. p0, p1, p2 tre p1=(4, -7) # coppie ordinate rappr. tre punti p2=(-4, 5) piano.setwidth(3) # aumenta le dim. degli ogg. disegnati piano.drawpoint(p0)#disegna i tre punti piano.drawpoint(p1) piano.drawpoint(p2) piano.setwidth(1) # riporta a 1 la dim. della "penna" piano.drawline(retta2p(p0, p1)) # disegna le tre rette piano.drawline(retta2p(p1, p2)) piano.drawline(retta2p(p2, p0)) Quandoeseguiamoquestoprogrammavogliamochevengaeseguitaautomaticamentelafunzio netest,aggiungiamo,infondoalfile,lariga: if __name__ == "__main__": test () Benedopotuttaquestaattivitdicodinggodiamociilfunzionamentodelprogramma:pre miamo<F5>,correggiamoglieventualierroridisintassi,senonsuccedenientecontrolliamoil testodelprogramma,setuttova,vengonodisegnatiitrepuntieletrerette. No,accidenti,nontrerette,masolodue,alpostodelleterzaapparenellashellunmessaggiodi errore.(Seappareunmessaggiodierroremanonappaionoitrepuntieleduerettenellafine stragrafica,bisognacercaredicapire,trovareecorreggereglierroriconfrontandoilprogramma eseguitoconquellodescrittosopra.) Leggiamoleultimerighedelmessaggio: File "/mnt/dati/daniele/06-07/scuola/materiali/informatica/pyplot/rette.py", line 49, in retta2p m=float(yb-ya)/(xb-xa) ZeroDivisionError: float division cidannoimportantiinformazionisull'erroreriscontrato.L'ultimarigaciinformacheilnostro codicehachiestoaPythondieseguireunadivisioneperzero,cosanonbuona...Lapenultima rigariportal'istruzioneincuisiverificatoilfattaccio,laterzultimailnumerodirigaelafun zioneincuiscrittoquestocomando.Cerchiamodicapirecosanonvainquestafunzione. Ilproblemanondisintassienonunproblemainformaticomageometrico.Veramentesesi sceglieun'altraternadipuntimagariilprogrammafunzionasenzaerrori.unerrorelogico,gli errorilogicisonoipidifficilidaindividuareedacorreggere,perchsimanifestanosoloin particolaricondizioninonsemprefacilidariprodurre.Nelnostrocasolarettapassanteperp0e p2parallelaall'asseyenonsipurappresentareconun'equazioneesplicita,nonpossibile
152 Laboratoriodiinformatica

RetteedestensionedellaclassePlot

calcolareilsuocoefficienteangolare.Primadieseguireladivisioneconvienecontrollarechele ascissedeiduepunti,xaexbnonsianouguali.Modifichiamoquindilafunzioneretta2p.Dopo averspacchettatolecoordinatediaeb,controlliamosexaugualeaxb.Inquestocasolacop piarestituitaconterrcomeprimoelemento,alpostodelnumerocherappresentailcoefficiente angolare,l'oggettoNone.Seinvecexaexbsonodiversi,procedeesattamentecomeprima: def retta2p(a, b): """Restituisce m e q della retta passante per a e b.""" xa, ya = a xb, yb = b if xa==xb: return None, xa else: m=float(yb-ya)/(xb-xa) q=ya-m*xa return m, q Oradobbiamomodificareancheimetodidellaclasse Mioplot inmodochetenganoconto dellapossibilitcheilcoefficienteangolareinvecediessereunnumerosial'oggettoNone.In questocasoilmetodorettarestituirilvaloredell'ascissadiunpuntoqualunquedellaretta,la partedestradell'equazione:x=xa,cioilsecondoelementodellacoppiarappresentantela retta: def retta(self, r): """Restituisce la stringa che contiene la funzione di una retta.""" m, q = r if m==None: return "%s" % q else: return "%s*x+%s" % r Ilmetodochedisegnalarettadevechiamareilmetodoxy()nelcasodiunafunzioney=f(x) eilmetodoyx()nelcasodiunafunzionex=f(y),quindianchequestometododevecontrol lareilvaloredelprimoelementodellarettaechiamareiltracciatoredifunzioniadatto: def drawline(self, r): """Disegna una retta dati (coeff.angolare, termine noto).""" m, q = r if m==None: self.yx(self.retta(r)) else: self.xy(self.retta(r))
Geometriaanalitica 153

RetteedestensionedellaclassePlot

Finalmenteilproblemadipartenzacompletamenterisolto,nonsolo,abbiamoancheestesole capacitdell'oggettoPlotpresentenellalibreriaPygraph.Forsesipotrebbescrivereall'auto redellalibreriaperinvitarloadaggiungerequestanuovafunzionalitalmodulopyplot.py;) Riassumendo Conunacoppiadinumeripossiamorappresentarequasituttelerettedelpianocartesiano. Utilizzandoancheunvalorenonnumericoperilprimoelementodellacoppia,possonoesse rerappresentatetuttelerette. possibilemodificareleclassigidefinitenellelibrerieestendendonelefunzionalit. Ognimetododiunaclassehacomeprimoparametrounriferimentoall'oggettostessonor malmentechiamatoself. Abbiamo derivato dalla classe Plot la classe Mioplot che aggiunge due metodi: retta()edrawline(). Abbiamocostruitolafunzionechedateduecoppie,lecoordinatediduepunti,restituisce unacoppia,larettapassanteperiduepunti. Provatu 1. Modificacoloriespessorideglielementigraficidisegnatiinquestocapitolo. 2. Aggiungilafunzionechecalcolalarettapassanteperunpuntoeperpendicolarea unarettadata.Modificaanchelafunzione test() inmodochedisegnilealtezze deltriangolo. 3. Aggiungilafunzionechecalcolalarettapassanteperunpuntoeparallelaaunaretta data.Modificaanchelafunzionetest()inmodochenedisegni,inunaltrocolore leparalleleailatipassantiperiverticiopposti. 4. Aggiungilafunzionechecalcolal'intersezionetraduerette,modificaanchetest() inmodocheevidenziipiedidellealtezze. 5. Aggiungi la funzione che calcola la distanza tra due punti. Modifica la funzione test()inmodochecalcolil'areadeltriangolousandolaformula:baseperaltezza divisodue. 6. AggiungilafunzionecheimplementalaformuladiEroneeverificailcalcolodell'a reaprecedente. 7. L'equazionediunarettapuessereespressainformaimplicita:ax+by+c=0.Questa equazionerappresentatuttelerettedelpiano,compresequelleparalleleall'assey.In questomodononc'bisognodiutilizzarelostranovaloreNonenellefunzioni.Ri scrivi,inunaltrofile,lefunzionieimetodiusandolafunzioneimplicita(unaternadi numeri)invecechequellaesplicita(unacoppiadinumeri).

154

Laboratoriodiinformatica

Geometriadellatartaruga

5. Geometriadellatartaruga
Inquestasezionevengonopropostialcuniproblemidigeometriadellatartaruga.Oltrea PythonvieneusatalalibreriaPyturtlediPygraph.Pyturtlemetteadisposizioneunter ritorioincuiabita(inizialmente)unatartaruga.Latartarugaunanimalettociberneticoche possiedeunapennaedcapacedimuoversinelsuospazioobbedendoadalcunisemplicico mandi.Quandosimuoveelapennaabbassatalasciaunatraccia. Perl'installazionedellalibreriaPygraph,checontieneanchePyturtle,vedil'introduzione.

Geometriadellatartaruga

155

Geometriadellatartaruga

156

Laboratoriodiinformatica

Avanti,indietro,destra,sinistra

5.1. Avanti,indietro,destra,sinistra
ComeconvincereuntriangolinodettoTartarugaaadisegnarelineesulloschermo.
La geometria della tartaruga caratterizzata dall'avere un riferimento intrinseco invece che estrinseco:descrivelefiguredalpuntodivistadichilestadisegnandomuovendosisuunasu perficiesensibilepiuttostochedalpuntodivistadichileguardadall'alto. Perquestionistoricheilcursoregraficodettotartarugadatocheleprimerealizzazionidique stageometriautilizzavanounpiccolorobotaformadisemisferachemuovendosisuungrande fogliolasciavaunatracciaconunapenna. Iprincipalicomandidellageometriadellatartarugasono:leistruzioniperfarlamuovereoruo tare.Lasintassidiquesticomandi: <tartaruga>.forward(<passi>) <tartaruga>.back(<passi>) <tartaruga>.left(<gradi>) <tartaruga>.right(<gradi>) Macomefarepercreareunatartarugaalnostroservizio?Primadituttodobbiamocaricarela classeTurtledallalibreriapyturtle.pyconl'istruzione: from pyturtle import Turtle poiistanziareunoggettodellaclasseTurtle conl'istruzione: tarta=Turtle() BisognaosservarechePythondistinguemaiuscoleominuscolepercuinonlostessoscrive reTurtleoturtle. Altraosservazione:lacoppiadiparentesicheseguel'identificatore Turtle nelsecondoco mandoindicaaPythonchedevecreareunoggettodiquestaclasseecollegarloall'identifica torecheprecedel'uguale.Lasecondaistruzionecorrispondealcomando: CreaunoggettodellaclasseTurtleeassocialoalnometarta. D'orainpoil'identificatoretartaassociatoadunparticolareoggettodellaclasseTurtle. OranoncirestachesperimentareilfunzionamentodeimetodidellaclasseTurtle,magariri solvendoilfamosoprobleminodellateoriadeigrafi:disegnaunacasettaconunacrocedentro senzasollevarelapenna:

Geometriadellatartaruga

157

Avanti,indietro,destra,sinistra

>>> >>> >>> 16 >>> >>> 17 >>> >>> 18 >>> >>> 19 ...

from pyturtle import Turtle tarta=Turtle() tarta.forward(100) tarta.left(90) tarta.forward(100) tarta.left(90) tarta.forward(100) tarta.right(135) tarta.forward(50*1.4142)

Ognivoltachevieneeseguitouncomandochetracciaunalineasulloschermo,inIDLEappare unnumeroprogressivo,nonpreoccupiamoci.Questonumeropuessereusatoinproblemipi complessi(sivedaladocumentazionedipygraph),manoninterferisceconiproblemicheaf fronteremo. Cercandodirisolverequestoproblema,lepersonenormalifannodiversierrori.Questalibreria nonpermettedicancellarel'effettodell'ultimocomando,quandosicommetteunerroreconvie neusareilcomando <tartaruga>.reset(),cancellaretuttoeridisegnaretuttodaccapo. Pernonperdereunmucchioditempoinscrittura, possibilesfruttareunacaratteristicadi IDLE:perriscrivereuncomandobastaposizionareilcursoresullarigadaripetereepremere <Invio>,larigaverrriscritta.Oralasipumodificareomantenereinvariata,premendodi nuovo<Invio>vieneeseguita. AltriduemetodiimportantidellaclasseTurtlesono: <tartaruga>.up() <tartaruga>.down() L'effettodiquestiduecomandi,rispettivamente,quellodisollevarelapennaeriabbassarela penna:dopoilcomando up() latartarugasimuovesenzalasciaretraccia,dopoilcomando down()riprendeadisegnare.Adesempioperdisegnareunquadratocentratonell'attualeposi zioneditartapossodareiseguenticomandi:

158

Laboratoriodiinformatica

Avanti,indietro,destra,sinistra

>>> >>> >>> >>> >>> >>> 43 >>> ...

tarta.reset() tarta.up() tarta.back(100) tarta.right(90) tarta.down() tarta.forward(100) tarta.left(90)

Senonviriescealprimocolpo,nonpreoccupatevi,iohofatto5tentativiprimadiottenereesat tamenteildisegnocheavevoprogettato. Riassumendo IlmodulopyturtlemetteadisposizionelaclasseTurtle.Percaricarequestaclassesi devedareilcomando: from pyturtle import Turtle Percreareunatartarugasidevedareilcomando: t=Turtle() dovedobbiamostareattentiallamaiuscolaeallacoppiadiparentesi.Alpostoditpossiamo usareunqualunquealtronome. Iprincipalicomandidellageometriadellatartarugasono: <tarta>.forward(<passi>),<tarta>.back(<passi>), <tarta>.left(<passi>),<tarta>.right(<passi>), <tarta>.reset(<passi>),<tarta>.up(<passi>), <tarta>.down(<passi>). Provatu 1. Disegnaunabandierinaconildrapporettangolare. 2. Disegnaunabandierinaconildrappotriangolare. 3. Disegnaduebandierineconleastedisposteav. 4. Disegnaunafreccia. 5. Disegnaunalberellostilizzato. 6. Disegnaunacasettastilizzata. 7. DisegnalaletteraA.

Geometriadellatartaruga

159

Camminidell'ubriacoetartarugaacolori

5.2. Camminidell'ubriacoetartarugaacolori
Comeripetereistruzioniemodificaredimensioneecoloredeltratto.
Sevogliamomandareaspassotartalungounpercorsocasuale,invecechefarlerealizzareun disegnobenpreciso,possiamocaricarelafunzione randrange dalmodulo randomedare unaseriedicomandi: >>> >>> >>> >>> 25 >>> 26 ... from pyturtle import Turtle tarta=Turtle() from random import randrange tarta.forward(randrange(50)); tarta.left(120) tarta.forward(randrange(50)); tarta.left(120)

possibilescriverepiistruzioniPythonsullastessariga,bastasepararleconunpuntoevir gola;.Ingeneralenonunabuonacosascriverepiistruzionisullastessariga,diregolanon vafatto,macomeogniregolahadelleeccezioni.Inquestocasoinvecediriscriveretuttalariga ognivoltachevogliamorieseguirla,bastacheconlafrecciadellatastieraoconilmouseripor tiamoilcursoresuquellarigaepremiamoiltasto<Invio>.Inquestomodolarigadiistruzio niverrriscrittasuunalineavuota,potremomodificarla,sevogliamo,edeseguirlapremendo ancorailtasto<Invio>.Quattrotastiinvecechequaranta! AncheseilmeccanismodiIDLEchecipermettediricopiareunarigacomodosevolessiese guirequelledueistruzioniper500volteo1000volteillavoroeilconsumodellatastieradiven terebbeinaccettabile.Datochegliinformaticisonotragliesseriumani(?)pipigricheesista no,hannoinventatounmeccanismochepermettediripetereunbloccodiistruzioniquantevol tevogliamospecificandosemplicementeilnumero.Questomeccanismo,ininformatica,prende ilnomediciclo.Esistonodiversitipidiciclo,inquestocapitoloutilizzeremoilciclofor. Sevogliamocheilnostroubriacoesegua300trattidelsuocamminostrampalato,possiamo scrivere: >>> tarta.reset() >>> for contatore in range(300): tarta.forward(random.randrange(50)); tarta.left(120) SecidfastidiocheIDLEvisualizziquellalungasequenzadinumeripossiamoeliminareque stocomportamentoindesideratocatturandoquestivaloriinunavariabile:

160

Laboratoriodiinformatica

Camminidell'ubriacoetartarugaacolori

>>> for contatore in range(300): a=tarta.forward(random.randrange(50)); tarta.left(120) Lasintassidelcomandofor: for <variabile> in <sequenza>: <istruzioni> Neicasiprecedentilasequenzageneratadallafunzionerange(<numero>),mapotrebbe essereanchecreataafantasiadall'utente,lavariabileassumeadognicicloundifferentevalore dellasequenza: >>> for elemento in ['Et', 'telefono', 'casa', 123]: print elemento Et telefono casa 123 Iprimitempifaciledimenticarsiiduepunti:cheterminanolalineacheiniziaconfor.Le istruzionichesivuolesianoripetutedevonoessereindentate. Pudarsicheilcolorenerodellapennadellatartarugacisembripiuttostonoioso,possiamo modificarlousandoilmetodo<tartaruga>.setcolor(<colore>). Adesempiosevogliamochevengadisegnataunaraggieradilineerosse: >>> tarta.reset() >>> tarta.setcolor("red") >>> for cont in range (72): a=tarta.forward(100) a=tarta.back(100) tarta.left(5) Primaosservazione:leistruzionidaripeterenonoccorrechesitrovinosullastessariga,separa tedaun;,devonocostituireunbloccocioesseretutterientraterispettoall'istruzionefor. Questorientro,ininformaticasichiamaindentazione.Devonocioessereindentaterispettoal l'istruzione for etrovarsitutteallostessolivellodiindentazione.Altrilinguaggiusanoaltri metodiperidentificareunbloccodiistruzioni: C,C++,Java,...usanoleparentesigraffe:{e}. Pascal,Ruby,...usanoleparolebegineend. ... IlcomandoprecedentediceaPythondieseguireper72volteleistruzioniseguentichesitro

Geometriadellatartaruga

161

Camminidell'ubriacoetartarugaacolori

vanoindentate. L'argomentocheindicailcoloreunastringachepucontenereilnome(ininglese)diuncolo reoppureunastringanelformato: #rrggbb doverr,gg,bbsono3numeriinesadecimale (numericompresitra00eff)cheindicanolecomponentidei3coloriprimariinemissione, cio: rosso, verde e blu. Combinando questi 3 numeri possiamo ottenere un colore tra 256*256*256possibilicolori(16.777.216possibilicolori).Adesempioperottenereilgiallo dobbiamomescolareilrossoalverde: #ffff00 perottenereilmagentasimescolailrosso alblu: #ff00ff perottenereilcianosimescolailverdealblu: #ff00ff . Ancheledimensionideltrattodellapennaedellatartarugastessapudarsichenonciaggradi no,inquestocaso,ilmetodo<tartaruga>.setwidth(<numero>)permettedimodifi carle: >>> >>> >>> >>> tarta.reset() tarta.setwidth(5) tarta.setcolor("pink") for cont in range(4): tarta.forward(100) tarta.left(90)

Riassumendo InIDLEpossiamorichiamareunaistruzionescrittaprecedentementeportandoilcursoresu quellarigaepremendo<Invio>. Ilcicloforpermettediripeterequantevoltevogliamounbloccodiistruzioni. Caricandolalibreriarandompossiamoutilizzarenumeripseudocasuali. Possiamomodificareilcoloredellatartarugaedellasuapenna. Possiamomodificarelagrandezzadellatartarugaedeltrattolasciatodallasuapenna. Provatu 1. Disegnadiversicamminidell'ubriacocambiandol'angolodirotazione. 2. Disegnadiversicamminidell'ubriacocambiandolospostamentomassimo. 3. Disegnadeicamminiincuicasualelarotazionementrerimanecostantelosposta mento. 4. Disegnapercorsiincuicambiaancheilcoloreelospessoredellapenna.

162

Laboratoriodiinformatica

Poligoni

5.3. Poligoni
ComeinsegnareaPythonaeseguirecomandinuovi.
Finoraabbiamousatocomandidefinitiall'internodiPythonodiunasualibreria.Adesempio perdisegnareunquadrato,dopoavercaricatolalibreriapyturtleecreatounatartarugadi nometinadovevamoscrivere: tina.forward(50) tina.left(90) tina.forward(50) tina.left(90) tina.forward(50) tina.left(90) tina.forward(50) tina.left(90) oppure: for cont in range(4): tina.forward(50) tina.left(90) Questomododilavorarevabenefinchiprogettisonopiccoli,masedovessiscrivereunpro grammaincuiiquadratisonotanti,sirivelerebbepiuttostoscomodo.Nonsolo.Icomandidati nellashellvannopersiquandoescodaIDLE,sedevoabbandonareametunlavoroespegnere ilcomputer,lavoltaseguentedovrripartiredacapo.Cinonvaaffattobene!Iprogrammatori hannoinventatodeimodi: persalvareipropriprogrammisiafinitisiainfasedicostruzione, perdareunnomeaunbloccodicodiceinmododapoterloeseguirescrivendounaparola inveceche3,8,o800lineedicodice. Vediamocomefareci. Innanzitutto,unavoltaavviatoIDLE,diamoilcomando:menu-File-NewWindow.Siaprir unanuovafinestradieditorvuota.Primaancoradiincominciareariempirla,lasalviamo,nella nostracartelladilavoroconilnome:01poligoni.py.Osservazioni: Persalvareundocumentoconunaltronome:menu-File-SaveAs.... Ilfilevasalvatonellanostracartelladilavoro,magariinunasottocartelladoveteniamoi lavoridiinformatica. Perchunnomecosstrano: 01perchquestoaiuterilsistemaoperativoatenereinordineinostriprogrammi, poligoniperchinquestoprimoprogrammainsegneremoatartarugaadisegnare deipoligoniregolari,
Geometriadellatartaruga 163

Poligoni

.pypersegnalarealsistemaoperativochequestofilecontieneunprogrammascritto nellinguaggioPython. Oranellabarradeltitolodellafinestradieditordovrebbeapparireilnomedelfileassociato. Possiamoiniziareascrivereilnostroprogramma.PerprimacosascriviamoqualcosachePythonnonconsidereraffatto:deicommenti.Ogniprogrammadeveiniziarecondeicommenti chedevonocontenerealmenoleseguentiinformazioni:titolo,autore,data. Pythonconsiderauncommentotuttocichesegueilcaratterecancelletto#.Ilnostropro grammaquindiinizierconalcunerighecheassomiglierannoaqueste:

# # # #

Poligoni regolari con la grafica della tartaruga Funzioni Daniele Zambelli febbraio 2007

L'editordiIDLEsiaccorgechesonocommentiecoloraquesterighedirosso.Secinonavvie necontrollatecheilnomedelfileabbiaesattamentel'estensione.py. BenefinalmentepossiamoincominciareascriveredeicomandidafareseguireaPython.In cominciamoconiduecomandipercaricarelalibreriaepercreareunatartaruga: from pyturtle import Turtle tina=Turtle() Quandopremiamoiltasto<Invio>nonvieneeseguitoniente,vienesoloinseritouncarattere difinelineaeilcursorediinserimentovaacapo.Pereseguireilprogrammasidevepremereil tasto<F5>oppuredareilcomandomenu-Run-Run Module.IDLEprimadieseguirequa lunquecosavorrsalvareilcontenutodell'editor.Poi,senonabbiamointrodottoerrori,verr caricatalalibreriaecreataunatartaruga.DallashelldiIDLEpossiamodareicomandichevo gliamoallanuovatartaruga. Oravogliamodareunnomeadunbloccodicodice.Vogliamoscrivereleistruzioniperdise gnareunquadratoefarleeseguirescrivendolaparolaquadrato().Notareanchequi(come inTurtle)lacoppiadiparentesitondecheindicanoaPythonchedeveeseguirequalcosa.Il bloccodiistruzioniprecedutodalnomesichiamafunzione.Lafunzionequadratosipuscri verecos: def quadrato(): for cont in range(4): tina.forward(50) tina.left(90) lasintassi: def <nome della funzione>(): <istruzioni>
164 Laboratoriodiinformatica

Poligoni

Notareanchequileparentesitondeeilcarattereduepunti:. Pereseguireilprogrammabastapremereilta sto<F5>oeseguireilcomandomenu-RunRun Module. Viene caricata la libreria, creatalatartarugaedis...NO,nonvienedise gnatounquadrato.Conicomandiprecedenti abbiamoinsegnatoa Python adisegnareun quadrato,manongliabbiamodettodidise gnarlo.Spostiamocinella Shell di IDLE e diamo il comando: quadrato()... ora il quadratoapparenellafinestragrafica. cosamoltobuonaaveretuttiglielementiin vistaquandosiprogramma:quindidisponile finestreinmododaaverelafinestragraficainaltoasinistra.AbbassaShelldiIDLEinmodo dafarlastaresottoallafinestragraficaerestringil'editordi01poligoni.pyinmododafar lostareadestra.Inquestomodohaisempreinvistatuttoquellocheservepercapirelasituazio ne. Riassumendo Unprogrammaunfileditestodovesonoscritteleistruzionichel'interpretePythondeve eseguire. Unafunzioneassociaadunnomeilbloccodiistruzionidaeseguire. Lasintassiperdefinireunafunzione: def <nome>(): <istruzioni> Pereseguireunafunzionebastachescrivailnomedellafunzioneseguitodaunacoppiadi parentesitonde. Provatu 1. Aggiungialprogramma 01poligoni.py lefunzioniperdisegnarealtripoligoni regolari. 2. Aggiungilafunzionetutti()chedisegnituttiipoligonidefiniti. 3. Scriviunaltroprogrammadinome011stelle.pychedisegnidelleraggierecon diversonumerodiraggi. 4. Modificailprogramma011stelle.pyinmodochelediversestelleabbianoan checolorediverso.

Geometriadellatartaruga

165

Quadratini,quadratoni...quadrati!

5.4. Quadratini,quadratoni...quadrati!
Comedisegnaremillequadratidiversiconun'unicafunzione.
Creiamounanuovafinestradieditoresalviamolaconilnome 02quadrati.py.All'inizio delprogrammascriviamoisoliticommenti,qualcosadisimilea: # # # # Quadrati con la grafica della tartaruga Parametri Daniele Zambelli febbraio 2007

Orascriviamolesoliteduerighechecaricanolalibreriaecreanounatartarugaepoiriscrivia molafunzionechedisegnaunquadrato: from pyturtle import * tina=Turtle() def quadrato(): for cont in range(4): tina.forward(50) tina.left(90) Eseguiamoilprogrammaesalviamolo(tasto <F5>).Dopoaverdispostolefinestreinmodo chesianotuttetrebenvisibilisulloschermo,dallaShelldiIDLEdiamoilcomandoquadrato() inmododaverificarechefunzionicorrettamente.Bene,sefinquituttofunziona possiamoprocedere.Neiprossimiprogrammiavremobisognodiquadratigrandiediquadrati piccoli.Nonunproblemascrivereunafunzionequadratinoeunafunzionequadratone,ad esempio: def quadratino(): for cont in range(4): tina.forward(5) tina.left(90)

def quadratone(): for cont in range(4): tina.forward(200) tina.left(90) Osservazione:traduefunzionilasciatesempreunalineavuota,miglioralaleggibilitdelcodi ce.


166 Laboratoriodiinformatica

Quadratini,quadratoni...quadrati!

Provateleduefunzionifannoillorodovere,manonsiamosoddisfatti,perchseavessibisogno diunquadratinodilato7odilato9.2odilato...dovreiandareamodificareladefinizionedel lafunzioneoppuredovreiriempireilmioprogrammadifunzioniquasideltuttouguali.Mettia moinevidenzainchecosasonodiverseleduefunzioniprecedenti: def quadratino(): for cont in range(4): tina.forward(5) tina.left(90)

def quadratone(): for cont in range(4): tina.forward(200) tina.left(90) L'unicacosachecambiadaunaall'altraunnumero.Possiamosostituirequelnumeroconun parametro,ciunavariabilecheunavoltavalga5unavolta200equandomiserveunquadrato dilato25.6valgaesattamente25.6!Ilparametrodeveesseredichiaratoall'internodelleparente sicheseguonoilnomedellafunzioneedeveavereunnomechesiasignificativo,nelnostro casounbuonnomeperilparametropuesserelato: def quadrato(lato): for cont in range(4): tina.forward(lato) tina.left(90) Lasintassicompletadiunafunzionedunque: def <none>([<parametri>]): <istruzioni> Orasetentodieseguirelafunzionequadratoconilcomando: >>> quadrato() Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> quadrato() TypeError: quadrato() takes exactly 1 argument (0 given) ...invecedellafiguraottengounmessaggiodierrore.L'ultimarigacidicequaledifficolthain contratoPythonneltentaredieseguireilnostrocomando:lafunzionequadrato()richiede esattamenteunargomento,noiglieneabbiamodatizero.
Geometriadellatartaruga 167

Quadratini,quadratoni...quadrati!

Dobbiamodireaquadratoquantograndelovogliamo: >>> quadrato(25.6) Questavoltafunzionaeconquestaunicafunzionepossiamodisegnarequadratiditutteledi mensioni.Ilnumeropostotraparentesivieneassociatoallaparolalatoequandovienedato allatartarugailcomandodiandareavantilevienedettodiandareavantiesattamentediquella quantit. Riassumendo possibiledefiniredellefunzioniconalcunivalorivariabili,ilnomedellevariabilivanno inserititralacoppiadiparentesichesegueilnomedellafunzione.Lasintassiperdefinire unafunzione: def <nome>([<parametri>]): <istruzioni> Iparametrisonozeroopinomieventualmenteseparatidavirgole. Almomentodell'esecuzionesidevemetteretraleparentesicheseguonoilnomedellafun zionetantiargomentiquantisonoiparametri: <nome>([<argomenti>]) Gliargomentisonozeroopioggettieventualmenteseparatidavirgole. Provatu 1. Aggiungialprogramma02quadrati.pylafunzionequadrati()chedisegniunasequen zadiquadratididiversadimensione. 2. Aggiungilafunzionefila()chedisegnideiquadratididiversadimensioneunodise guitoall'altro.Ricordatichelatartarugavariportataalpuntodipartenza. 3. Aggiungilafunzionecoda()chedisegniunasequenzadiquadraticonunapiccolaro tazionetral'unoel'altro(ricordatidirimettereapostolatartaruga). 4. Realizzaunprogramma021triangoli.pychelavoriinmodosimilea02quadrati.pyma conmodulitriangolari.

168

Laboratoriodiinformatica

Poligoniditutteleformeedimensioni

5.5. Poligoniditutteleformeedimensioni
Comedisegnareconun'unicafunzionepoligonidiogniformaedimensione.
Unavoltausatiiparametriperdisegnarequadratigrandiepiccoli,possiamogeneralizzareil meccanismo.Inunnuovofiledinome poli.py,scriviamoledueprocedureperdisegnare quadratietriangolidilatovariabile... # # # # Poligoni con la grafica della tartaruga Due parametri Daniele Zambelli febbraio 2007 lati from pyturtle import * tina=Turtle() def quadrato(lato): for ii in range(4): tina.forward(lato) tina.left(90) def triangolo(lato): for ii in range(3): tina.forward(lato) tina.left(120) 2 3 4 5 6 7 angolo ? 120 90 72 60 ??

Evidenziamoledifferenzetraunafunzioneel'altracenesonodue:ilnumerodilatiovviamente ilquadratoneha4eiltriangolo3,el'ampiezzadell'angoloesterno,90perilquadrato,120per iltriangolo,...proviamoacercareunarelazionecheleghiilnumerodilatiall'ampiezzadell'an goloesterno.Quandoilatiaumentanogliangolidiminuiscono...ilprodottotralatieangolo semprelostesso...Alpostodi90,possiamoscrivere360/4ealpostodi120,360/3 def quadrato(lato): for ii in range(4): tina.forward(lato) tina.left(360/4) def triangolo(lato): for ii in range(3): tina.forward(lato) tina.left(360/3) Aquestopuntodobbiamofareun'osservazionerelativaadunaparticolaritdiPython.Ladi visioneinPython,finoallaversione2seoperasuduenumeriinteridcomerisultatounnu
Geometriadellatartaruga 169

Poligoniditutteleformeedimensioni

merointero: >>> print 10/3 3 Sealmenounodeidueoperandiunnumeroinvirgolamobile,ilrisultatosarinvirgolamobi le: >>> print 10./3 3.33333333333 Dallaversione3ilcomportamentodiPythoncambier:ladivisionetraduenumeriinteridar comerisultatounnumeroinvirgolamobile.Anoiservecheladivisionediaunrisultatoabba stanzapreciso.possiamoquindifareinmodocheunodeidueoperandisiaunnumeroinvirgola mobile,oppureimportareilcomportamentodellafutureversionidiPython: >>> from __future__ import division >>> print 10/3 3.33333333333 Sescegliamoquestosecondometodolafunzionediventa: from __future__ import division def poli(num, lato): for ii in range(num): tina.forward(lato) tina.left(360/num) Oralafunzionepoli(num,lato)puessereusataall'internodialtrefunzioniadesempiosevo gliochevengadisegnatalasequenzadipoligonitutticonlostessolatomacondiversonumero dilati: def poligoni(): for numlati in range(3, 13): poli(numlati, 50) Definendolafunzionepoli(num,lato)abbiamoinsegnatoaPythonariconoscereedeseguire unnuovocomandochepermettedidisegnarequalunquepoligonoregolare. Riassumendo possibiledefiniredellefunzioniconpiparametri.Aumentareilnumerodiparametriper mettedirenderelafunzionepielastica,ma,incompenso,purenderepidifficilecapireil suocomportamento.
170 Laboratoriodiinformatica

Poligoniditutteleformeedimensioni

Quandosivuoleeseguireunafunzione,sideveporreall'internodelleparentesicheseguono ilnomedellafunzionestessa,tantiargomentiquantisonoiparametripresentinelladefini zionedellafunzione.Adesempio,selafunzioneha2parametriavrbisognodi2argomenti. Unavoltadefinitaunafunzione,puessereeseguitadallashellodall'internodiun'altrafun zione. Provatu 1. Usalafunzionepoli()perdisegnarepoligonisimiliunodentrol'altro. 2. Disegnaunafiladipoligonisimili.Ricordadiriportarelatartarugaalpuntodipar tenza. 3. Disegnaunacodadipoligoniincuicambiasialadimensionedellato,siailnumero dilati. 4. Scriviunafunzionechedisegni,sparpagliatiacaso,50poligonididiversadimensio ne,conundiversonumerodilati,cambiandoancheilcoloreeladimensionedella penna. 5. Inunaltroprogramma,stelle.py,Scrivilafunzionestella(numraggi,lungraggio)ela funzionechedisegni100stellinedidiversaformaecoloreinposizionicasualidella finestragrafica.

Geometriadellatartaruga

171

Unorribileragno

5.6. Unorribileragno
Comeaffrontareerisolvereunproblemacomplesso.
Abbiamovistocomescriverefunzionisemprepiflessibili,maingenerechiprogrammasitro vaadoverrisolvereproblemipicomplessi,ciocostituitidapipartimesseinrelazionetradi loro.Laprimaattivitdacompierequandosiaffrontaunproblemacomplessoquelladiana lizzareilproblema.Analizzareunproblemasignificascomporloinproblemipisempliciindi candoancheilcollegamentotralevarieparti.Oraciponiamoilproblema:scriverelefunzio nicherealizzinoildisegnodiunorribileragno: Lostrumentocheusiamoperl'analisiilgrafoadalbero.Ilgraforichiamaunpo'lastruttura diunalberorovesciato:laradiceinaltoelefoglieinbasso.Nellaradicevienemessoilrisultato finale,quellochevogliamoottenere.Daquestapartonodueramicheconduconoadeinodiche contengonoduepartididisegno,chemesseassiemeproduconoilrisultatofinale.Alorovolta, questepartivengonoscomposteinpartifinoadarrivareadelementiabbastanzasemplicidaes seredisegnatidaunasolafunzione.Inognunodiquestielementideveessereindicatalaposi zionedipartenzaediarrivodellatartarugaeunnome:

Aquestopuntopossiamopassareascrivereilcodice:unnuovofile,salvarloconunnomeadat to,lesoliterighedicommentochedannoleinformazionidibase...Utilizziamoilmetododetto
172 Laboratoriodiinformatica

Unorribileragno

topdown,dalgeneralealparticolare,partiamoconlafunzionechedisegnatuttoilragno: from pyturtle import * tina=Turtle() def ragno(dim): corpo(dim) tina.up() tina.forward(dim) tina.down() testa(dim/2) tina.up() tina.back(dim) tina.down() Ilragnocostituitodalcorpo,daunospostamentosenzalasciaresegno,dallatestaedaunaltro spostamento,perrimetterelatartarugaalsuoposto.<F5>pereseguireilprogrammaepoidal lashell: >>> ragno(50) Nonvieneprodottoalcundisegno,maotteniamounmessaggiocheterminaconlaseguente riga: NameError: global name 'corpo' is not defined Pythongiustamenteprotestachenongliabbiamoancoradettocomefattoilcorpodelra gno...L'addomedelragnopuesseredisegnatoutilizzandoilmetodo ccircle(raggio, estensione)chepermettedidisegnareunacirconferenzadiraggiodatoounarcodicircon ferenzadatiraggioeampiezzadell'arco. def corpo(dim): tina.ccircle(dim) tina.left(90) zampes(dim) tina.left(180) zamped(dim) tina.left(90) <F5>pereseguireilprogrammaepoidallashelldiamoilcomando:ragno(50).Questa voltaqualcosavienedisegnato:ilpancionedelragno,maPythonsiinterrompeancoraconun errore: NameError: global name 'zampes' is not defined

Geometriadellatartaruga

173

Unorribileragno

Bene,vuoldirecheoradiscriverelafunzionezampes(dim).chedovrdisegnarelezampe sinistre: def zampes(dim): tina.right(30) for cont in range(4): zampas(dim) tina.left(20) tina.right(20*4-30) FacendociguidaredaglierrorichemanmanoPythonrileva,procediamoascrivereilrestodel codice.Inparticolarelatestausailmetodoccircle(raggio,estensione)pertracciareunarcodi 210gradi: def testa(dim): tina.right(105) tina.ccircle(dim, 210) tina.right(105) tina.right(30) antenna(dim, +60) tina.left(60) antenna(dim, -60) tina.right(30)

Riassumendo Primadiaffrontareunproblemacomplesso,bisognasuddividerloinpartifacendoneun'ac curataanalisi. Possiamorisolvereunproblemaconilmetodotopdownciopartiredallafunzionepi generaleerealizzaremanmanmanolefunzionichesonorichiestedalprogramma,control landoognivoltacheilprogramma,finoaquelpuntofunzionicorrettamente. Possiamorisolvereunproblemaconilmetodobottomupciorealizzareprimagliele mentipisemplici,controllandochefunzioninocorrettamenteemetterlipoiassiemeper realizzareporzioniviaviapicomplessedelproblema Provatu 1. Completaildisegnodelragno. 2. Realizzaunsemplicedisegno,fannel'analisi,traducil'analisiinunprogramma.

174

Laboratoriodiinformatica

Fogliodicalcolo

6. Fogliodicalcolo
Cosa c' in questa sezione.
Inquestasezionesonovieneintrodottobrevementel'usodelfogliodicalcolo.Gliesempiei terminiusatisiriferisconoalfogliodicalcolopresentenelpacchettoOpenOffice.org,maipro blemiaffrontatielefunzioniusatesonoabbastanzasemplicidapermetterel'usodiunqualun queprogrammadifogliodicalcolo.

Fogliodicalcolo

175

Fogliodicalcolo

176

Laboratoriodiinformatica

Celle,colonne,righe...ilfogliodicalcolo

6.1. Celle,colonne,righe...ilfogliodicalcolo
Cos',ecomeusarelefunzionidibasediunfogliodicalcolo.
UnFogliodiCalcoloun'immensatabellacompostadaalcunemigliaiadirigheealcunecenti naiadicolonnechegeneranounagrandequantitdicelleneiloroincroci.L'elementobasedi unFogliodiCalcolo,dunquelacella.Ognicellaha:unindirizzo,uncontenutoeunformato: 1. indirizzo Comenellabattaglianavalel'indirizzodiognicellacompostodaunaletteraseguitadaunnu mero,ades.B3lacellachesitrovaall'incrociodellasecondacolonnaconlaterzariga.Poi chleletteresonosolo26enoi,avolte,abbiamobisognodipicolonne,arrivatiallalettera ZproseguiamoconAA,AB...ecosvia. Nellabarradellaformula,inaltoasinistravienevisualizzatol'indirizzodellacellaincuicitro viamo.Cliccandoindiversecellesipuosservarel'indirizzochecambia. 2. contenuto Ognicellapuavereuncontenutocheunodiquesti3oggetti: Parole,unastringaqualunque. Numerichepossonorappresentareanchepercentuali,oreodate. Formule,espressionicheinizianoconunuguale.Quandositerminadiinserireunaformula, nellacellavienemostratoilrisultatodelcalcolo,mentreiltestodellaformulaapparenella partealtadelloschermonellabarradiimmissione.Glioperandidelleformule,possonoes serenumerioindirizzidicelle.Quandovienemodificatoilcontenutodiunacella,tuttele formulechecontengonoilsuoindirizzovengonoricalcolate. 3. formato Ognicellahadiversiattributicheriguardanoilsuoformatooquellodelsuocontenuto.Cisono decinediaspettichepossonoesseremodificaticonilformatodellacella: coloredisfondo; bordo; dimensioni; font,colore,dimensionedeicaratteri; formatodeinumeri; allineamentodelcontenuto; ... Possiamoapplicarequesteprimeinformazioniperrealizzareunformulariodigeometriache calcoliperimetrieareedivaripoligoni. Apriamounnuovofogliodicalcolo.primaancoradiincominciareariempirlolosalviamocon nome: Menu-File-Salva Come.Convienesalvarleildocumentoinunanostracartellae

Fogliodicalcolo

177

Celle,colonne,righe...ilfogliodicalcolo

darlepernomequadrilateri.Persalvareunfilebastaanchecliccaresull'iconaconundischet to,disolitoterzadasinistra. L'obiettivoavereunfoglionelqualeinserirealcunidatirelativiaiquadrilaterinotevoliecal colarealtreinformazionirelativeallafigura.Possiamodistinguereconuncoloredisfondole cellenellequaliinseriredatieconunaltrocolorequellecheconterrannoirisultati.Dovremo adattarelalarghezzadellecolonneasecondadellospaziooccupatodalcontenuto.Potrebbean cheessereutilegraficamenteseparareivariproblemiriquadrandoconunbordolerelativecel le. Cella A1 A3 A5 A6 B6 A7 B7 A8 B8 A9 B9 A1:B9 Perimetro =B6*4 Area =B6^2 Diagonale =B6*sqrt(2) Coloredisfondo:azzurro MenuFormatoCellaBordo:contorno Coloredisfondo:azzurro Contenuto Formulariodigeometria:iquadrilateri ProblemisulQuadrato Formato Dimensioneecoloreafantasia Grassetto,colorato

Datoillatotrovoperimetro,areaediago Grassetto,corsivo naledelquadrato Lato: allineamentoadestra Coloredisfondo:verde allineamentoadestra Coloredisfondo:azzurro

Primadiprocedereconilformularioconvieneprovareinserendonellacella B6diversivalori numericiprimasemplicipercontrollarecheilfoglioeseguacalcolicorretti,poipistrani,con lavirgola,moltograndiomoltopiccolieosservareicorrispondentirisultati.Unavoltarisolti eventualiproblemiriscontratipossiamopassareaiproblemiinversiosualtrefigure. Riassumendo Unfogliodicalcolocompostodaungrannumerodicelleorganizzateinrigheeco lonne Ognicellacaratterizzatada: unindirizzo,compostodaunaletteraogruppodilettereeunnumero;
Laboratoriodiinformatica

178

Celle,colonne,righe...ilfogliodicalcolo

uncontenuto,chepuessere: unafrase, unnumero, unaformula; unformato

Provatu 1. Aggiungileformuleinversedelquadrato. 2. Aggiungileformulediretteeinversedelrettangolo. 3. Aggiungileformulediretteeinversedelrombo. 4. Aggiungileformulediretteeinversedelparallelogramma. 5. Aggiungileformulediretteeinversedeltrapezio. 6. Inunnuovodocumento,triangoli,scriviunformularioperiltriangolo. 7. Scrivideiformulariperlefiguresolide.

Fogliodicalcolo

179

Formatieordinamenti

6.2. Formatieordinamenti
Comeselezionareunbloccodicelle,sommareidatidiuninteroblocco, modificarelalarghezzadiunacolonna,disegnaregriglie, ordinareidati.
Spessoneifoglidicalcolosidevonoinserireformuleconmoltioperandiomolteformulechesi assomigliano. I fogli di calcolo forniscono degli strumenti per Popolazione scrivere formule applicate a Nome Area(km) (milioni) grandiquantitdidatioscrivere, Asia 43810000 3736 in modo efficiente e veloce, Africa 30370000 832 molteformulechesiassomiglia Americasettentrionale 24490000 306 no. Americameridionale 17840000 524 Come primo esempio partiamo Antartide 13720000 0 dai dati relativi alla superficie Europa 10400000 730 deicontinentieallaloropopola Oceania 9010000 31 zione,macerchiamodiragiona repensandodiavereachefare concentinaiadirighedidatiinvececheconsoloquestesette. Avviamounnuovofoglioesalviamoloconilnomecontinenti. Poieseguiamoleseguentiistruzioni: Cella A1 Contenuto Formato Datirelativiallapopolazioneeallasuperfi Dimensioneecoloreafantasia ciedeicontinenti

A3:C10 Ricopiamoidatidellatabellariportataso pra Nondifficilericopiarelatabellaprecedente,siincontraqualchedifficoltnellecelleB3eC3. LacellaB3contieneuncaratterepostoaindice,comeottenerlo?Innanzituttosiscrivonotuttii caratterichevogliamoappaiano:Area(km2),poiconilmouseselezioniamonellarigadiim missioneilsolocarattere2edaMenuFormatoCaratterePosizionescegliamoapice.Con fermandoconinviootteniamoilrisultatodesiderato. Lacella C3contieneunascrittatroppolungacheescedaibordidellacellastessa,vorremmo chefossespezzatasuduerighe.PoniamociinC3emodifichiamoilformatodellacella:Menu FormatoCelleAllineamentoAcapoautomatico. Oravogliamocheilcontenutodiquestecellesiavisualizzatoingrassettoesiacentrato:dopo averselezionatolecelle,traleiconechesitrovanonellabarradiformattazionetroviamoipul
180 Laboratoriodiinformatica

Formatieordinamenti

santigiustidacliccareperottenerequestieffetti.Possiamoripeterequesteoperazioniperognu nadellecelleoppure... Gliinformaticisonoestremamentepigri(addiritturapideimatematici),poichodianoripetere lestesseoperazionieglistessigestihannoinventatodellemacchinebravissimearipeterestupi deoperazioni.Invecechemodificarepertrevolteilformatodiunacellapossibileselezionare letrecelleeaggiustarneilformatoinunsolocolpo.Perselezionareungruppodicellecontiguo erettangolarebastacliccaresullacellainaltoasinistrae,tenendopremutoiltastosinistrodel mouse,trascinareilcursorefinoallacellainbassoadestra.Quandosirilasciailtastodelmou seilcoloredellecelleselezionateapparirinvertito. Oravogliamoaggiungereunarigachecontengaitotalidellasuperficieedellapopolazione: Cella B11 C11 Contenuto =somma(B4:B10) =somma(C4:C10) Grassetto Grassetto Formato

SeoraeffettuiamoundoppioclicnellacellaB11civieneevidenziatalaformulaelazonadi cellesucuilavora. Datochelasommadiungruppocontiguodicellemoltofrequente,cisonomoltimodiperim metterequesteformule.Proviamoavederle,poi,asecondadeicasiuseremoquellopicomo do.CancelliamoilcontenutodellecelleB11:C11.CiriportiamonellacellaB11e: iniziamoascriverelaformula:=somma( selezioniamoconilmouselecelleB4:B10, chiudiamolaparentesitondaeconfermiamoconiltasto<Invio> PerlacellaC11proviamoadusareunaltrometodo.UnavoltaportatinellacellaC11,clicchia mol'iconadellasommatoriachesitrovainaltoasinistradellacaselladiinserimentoselescel tediCalccivannobene,confermiamolaformulaconiltasto<Invio>. Inumeri,quandosonotroppolunghi,sonodifficilidaleggereevalutare,perfacilitarequesto compitosiseparanoagruppidi3condeipuntiniiseparatoridellemigliaia(dellevirgolepergli anglosassonicheusanoinveceilpuntopersepararelaparteinteradaquelladecimale).Selezio niamolecelledaB4aC11edaMenuFormatoCelleNumerisciegliamoilnumeroconilse paratoredellemigliaiaesenzacifredecimali. Aquestopuntopusuccedereuneffettospiacevole,nellacellaB11,doveprimac'eraunnume roneoraappaionotrecancelletti:###.Cosasuccesso?Modificandoilformatodelnume ro,oralacellanonpiabbastanzagrandepercontenerlotutto.Poichnonaccettabilecheun numerovengavisualizzatosoloinparte,quandononpuesserecontenutoinunacella,viene sostituitodaunsimboloconvenzionale:###.Pervederedinuovoilnostronumeropossiamo seguireunadelleseguentistrade: 1. togliereipuntinidellemigliaia, 2. diminuireledimensionidelcarattere,
Fogliodicalcolo 181

Formatieordinamenti

3. allargarelacella. Lasoluzionepiadattanelnostrocasolaterza.Clicchiamoconiltastodestrodelmousesul l'intestazionedellacolonnadaallargareedalmenuatendinacheapparescegliamolavoce: Larghezzacolonna.Nelcampodiinserimentoalpostodi2,62scriviamo3econfermiamo.La colonnasisarallargataunpochinoeilnumeroverrdinuovovisualizzato. Avoltepuessereutileavereidatiordinatirispettoaduncertocriterio.Seicontinentifossero decineocentinaia,pertrovareidatirelativiadunodiquestisarebbecomodoaverliscrittiinor dinealfabetico.Maquestoordinenonmiservirebbepertrovareilpigrandeoilpipopolato. Possiamodirealfogliodicalcolodiordinarelerighechevogliamoinbasealcontenutodiuna colonna. SevogliamoottenereicontinentiinordinealfabeticoselezioniamoilbloccodicelledaA4a C10eattraversoilMenuDatiOrdinascegliamocomeprimocriteriolacolonnaA.Conferman dootteniamolerigheordinate,inordinealfabeticodall'Africaall'Oceania. Sevogliamoicontinentiordinatidalpipopolatoalmenopopolato,sempredopoaverselezio natotuttelecellechecontengonoidatidaordinare,scegliamodalMenuDatiOrdinacomepri mocriteriolacolonnaCecomeordinequellodiscendente.Inunbatterd'occhioritroveremoi nostridatiordinatiperpopolazione. Riassumendo

Conilmousepossibileselezionareunbloccodicelle. possibileassegnareunformatoatuttelecellediunblocco. possibilecalcolarelasomadeinumericontenutiinblocchidicelle. possibiledisegnareicontornidellecelle. Sipuordinareunbloccodicelleinbaseadiversicriteri. Spessocisonomoltimodidiversipereseguirelastessaoperazione.importantesaperusarneuno, poiglialtrisiimparanoconiltempoeconl'uso.

Provatu 1. Trovaidatirelativiallasuperficieepopolazionedelleregionid'Italiacompletalicon itotalieformattalicomenell'esempioprecedente. 2. Eseguilestesseoperazioniriguardoalleprovinceitaliane. 3. Procuratiidatirelativiall'altezzaealpesodeituoicompagnidiclasse,odeicompo nentidellatuafamiglia,poicalcolalemedieedlorounformatoinmododarenderli facilmenteleggibili. 4. Ordinaidatideiprecedentieserciziinbaseadiversicriteri.

182

Laboratoriodiinformatica

Copiareinmodointelligente

6.3. Copiareinmodointelligente
Comericopiareformuleusandoindirizzirelativieassoluti.
Riprendiamoidatigiusatinelcapitoloprecedente,condellesempliciformulepossiamootte neredelleinformazioninuove. Possiamo,adesempio,farcalcolareladensitdipopolazionepermezzodellaformulapopola zione/superficie. Cella D3 D3 D3 D4 D5 D6 =C4*1000000/B4 =C5*1000000/B5 ...
Densitab/km2

Contenuto (Selezionarenellarigadiinputilsolo2)

Formato Centrato,grassetto Formatocarattereposizioneapice Formatocellaallineamentoacapoau tomatico Formatocellenumerizerodecimali Formatocellenumerizerodecimali ...

Datocheicontinentisonosolo7nonungrandeproblemascriverele7formulediverseuna sottol'altra,mainunfogliodicalcolononinfrequentedoverscriverecentinaiaomigliaiadi formulesiliaqueste!Chihaprogettatoilfogliodicalcolohaprevistodeglistrumenticheper mettonodiricopiarevelocementedelleformule.PonendocinellacellaD4,apparenell'angoloin bassoadestra,dellacellastessa,unquadratinonero;conilmousetrasciniamoquestoquadrati noversoilbassofinoacopriretuttelecelleincuivogliamoricopiarelaformula.Nonsoloil programmaharicopiatolaformulamahaancheaggiustatogliindici,propriocomeciserviva. Danotarechequandovienericopiataunaformulavengonoanchericopiatiiformatidellacelle incuilaformulastatascritta. Un'altrainformazioneinteressantechepossiamoricavaredaipochidatiinnostropossessola percentualerappresentatadallasuperficiediuncontinenterispettoallasuperficietotaledelle terreemerse.Lapercentualenonaltrocheunrapporto,ilquozientetralasuperficiediuncon tinenteeiltotale.Procediamoconillavoro: Cella E3 E4
Perc.Sup.

Contenuto =B4/B11

Formato Centrato,grassetto

Ilrisultatodiquestocalcolo0,29,noncertolapercentualecercata,selavoriamosullacarta, pertrasformarequestonumeronellapercentualebastamoltiplicarloper100.Neifoglidicalco
Fogliodicalcolo 183

Copiareinmodointelligente

lobastaindicarenelformatodellacellachequelnumerodeveessereintesocomeunapercen tuale: Cella E4 E5 ... =B4/B11 =B5/B11 ... Contenuto Formato Formatocellenumeripercentuale Formatocellenumeripercentuale ...

Anchequipossiamosfruttareilmeccanismodifarricopiarelaformulaversoilbasso.Dopoes serciposizionatinellacellaE4,prendiamoilquadratinoetrasciniamoloversoilbassoinmodo dacoprirelecelledituttiicontinenti.Questavoltal'effettononquellodesiderato:otteniamo unaseriedierrori!Comemai?Osserviamounadellecelleincuicomparsol'errore,lacella E5contienelaformula =B5/B12.Percapiremegliolaformulaselezioniamolacellaconun doppioclic.Vengonoevidenziateinrossoeblulecellechesonoutilizzatenellaformulastessa. Ora,B5vabene,maB12dovevaessereB11!NellacellaB12nonc'nienteeilfogliodical colosegnalagiustamenteunerroredidivisioneper0. Noivogliamoche,nelricopiareleformule,l'indicenumericodiB4vengamodificatomaquello diB11rimangacostante.NeiterminideifoglidicalcolosidicecheB4deveessereunindiriz zorelativo,B11unindirizzoassoluto.PeresserepignolianoinonoccorrechetuttoB11riaas soluto,siccomevogliamoricopiarelaformulaversoilbassocibastachesiaassolutalaparte numericadell'indirizzo:l'11. Percomunicarequestidesiderialfogliodicalcolosimettedavantialriferimentochevogliamo siaassolutoilcaratteredollaro:$.Questofasicheilprogrammaquandoricopialeformule nonnemodifichiilriferimento.Aggiustiamolenostreformule: Cella E4 =B4/B$11 Contenuto Formato Formatocellenumeripercentuale

Oraricopiarelacellaversoilbassoproducel'effettodesiderato!NellacellaE5cisarlaformu la=B5/B$11,nellacellaE6laformula=B6/B$11,ecosvia. L'elaborazionenumericadeinostridaticompleta,disegniamounagrigliaancheattornoalle nuovecellecheabbiamoriempitoottenendocosunlavoropresentabile. Riassumendo


Sipossonoricopiareformuletrascinandoilquadratinocheappareinbassoadestradiunacellase lezionata. Quandoricopiamounaformulaverticalmentegliindicirelativiallariga,inumeri,vengonomodifi cati. Quandoricopiamounaformulaorizzontalmentegliindicirelativiallacolonna,lelettere,vengono Laboratoriodiinformatica

184

Copiareinmodointelligente modificati. Sevogliamoche,nelricopiareunaformula,unindicenonvengamodificato,bastachelofacciamo precederedalcarattere:$.

Provatu 1. Neidatirelativialleregionid'Italia,calcolaladensitelapercentualedellasuperficie rispettoaltotaleedellapopolazionerispettoaltotale. 2. Eseguilestesseoperazioniriguardoalleprovinceitaliane. 3. Procuratiidatirelativiall'altezzaealpesodeituoicompagnidiclasse(odeicompo nentidellatuafamiglia,poicalcolal'indicedimassacorporeaequantoognicompo nentesidiscostadallamedia.

Fogliodicalcolo

185

Diagrammi

6.4. Diagrammi
Comerappresentaregraficamenteidati.
Spessoungraficodunapiimmediatacomprensionediunfenomenorispettoadunalistadi numeri.Ifoglidicalcolopermettonodidisegnaregraficididiversaforma.Riprendendoilfo gliodeicontinentivogliamoaggiungereduegraficiperrappresentarelasuperficieelapopola zione. Apriamoilfogliosucuiabbiamolavoratofinoraselezioniamolecellechecontengonoidati chevogliamorappresentare.Iniziamocostruendoungraficoatortacheriportilasuperficiedei diversicontinenti. 1. SelezioniamolecellecompresetraA4eB10. 2. DamenuscegliamoInserisciDiagramma,vienecosapertaunafinestradidialogoche ciguidanelladefinizionedeldiagramma. 3. ControlliamochesiaselezionatalacasellaPrimacolonnacomedidascaliaepremia moAvanti. 4. Nellasecondapaginadiquestodialogoselezioniamo:Rappresentaoggettinell'antepri ma.escegliamoilgraficoatortaeseriedidatiinColonne. 5. Nellaterzapagina,scegliamonormale. 6. Nell'ultimapaginascriviamoiltitolo(ades.Superficie)econfermiamocliccandosul bottoneCrea. Aquestopuntovienecreatoundiagramma.Unclicsuldiagrammaloselezioneefaapparirele manigliedidimensionamentochepermettonodimodificarneledimensioni.Quandoselezio natopossiamoanchespostarlodovevogliamocheappaianellanostrapagina.Posizioniamolo subitosottoaidati. Questounbuonmomentopersalvareillavorofatto. possibilemodificareidatirappresentatineldiagrammacliccandoconiltastosinistrosuldia grammastessoescegliendo,dalmenucontestuale,lavoceModificaareadati. Sevgliamocheildiagrammasiariquadratodaunbordo,dopoaverdatoundoppioclicsuldia gramma,scegliamodalmenucontestualelavoceAreadeldiagramma. Sevogliamomodificarepiprofondamenteildiagrammaappenacreatopossiamoeffettuareun doppioclicsuldiagrammastesso.Ilmenuprincipaledelfogliodicalcolocambiaecambiano ancheimenucontestuali(quellilegatialtastosinistro)asecondadicosavienepuntatodal mouse.DalmenuInserisciscegliamoLegendaetogliamoilsegnodispuntasuVisualizza. LaLegendascompare,maadessoildiagrammadidifficileinterpretazione,operiamodunque un'altramodifica:sempredalmenuInserisciscegliamoEtichetteechiediamochecivengano mostratiivaloricomepercentualeeancheleetichetteditesto.Etichettetroppolunghesbilan cianolarappresentazioneconvieneabbreviarle,nellatabellamodifichiamoAmericasettentrio naleinAmericasett.eAmericameridionaleinAmericamer..Allaconfermadiquesti

186

Laboratoriodiinformatica

Diagrammi

cambiamentiancheleetichetteneldiagrammasarannoautomaticamentemodificate.Oraseil diagrammarisultatroppopiccoloenonriempiebenelospazioasuadisposizionepossiamo cliccarevicinoallatortaeallargarloagendosullemaniglieverdicheappaiono. Questounbuonmomentopersalvareillavorofatto. Orasevogliamoundiagrammachecontengaidatirelativialnumerodiabitantidobbiamosele zionareinomideicontinentieivaloridellapopolazione.Purtroppoquestivalorinonsonocon tigui,perfarlodobbiamousareuntrucco:selezioniamoconilmouselecelledallaA4allaA10 epoiselezioniamolecelledalla C4 alla C10 tenendopremutocontemporaneamenteiltasto <Ctrl>.Iltasto<Ctrl>permettedieffettuareselezionimultiplesublocchirettangolarinon contigui.Dopoaverselezionatol'areacontenenteidati,dalmenuInsersciscegliamolavoce Diagramma. Questavoltainvececheundiagrammaatortavogliamounistogramma.Comeprimaassicuria mocichesiaselezionatalavocePrimacolonnacomedidascalia,nellapaginaseguentesele zioniamoRappresenta oggetti nell'anteprima. Possiamo cosaccorgerciche la legenda, in questocasononhasenso.Nell'ultimapaginaScriviamoiltitolodeldiagramma:Popolazione edeselezioniamolavoceLegenda.Aquestopuntopossiamocreareildiagramma.Posizionia moloinfiancoalprecedente. Vogliamooradisegnargliunriquadroattorno:doppioclic,menuFormatoAreadelDiagram ma,...Vogliamoanchecheleetichettedell'assexvenganoscritteinverticaleinmododanon esserespezzate:menuFormatoAssiAsseXelmodifichiamoleetichettemettendolarotazio nea90selezionandoSovrapponiedeselezionandoAcapo. Questounbuonmomentopersalvareillavorofatto. Oraidiagrammisonocomelivolevamo,Primadiconsiderarefinitoillavorodobbiamoper controllaredipoterlostampareinun'unicapagina. Clicchiamofuoridaidiagrammi,inunacellaqualunque,poidaMenuVisualizzascegliamo Interruzionidipagina.Unalineabludelimitericontornidellevariepagine,modifichiamole dimensionideidiagrammiospostiamoliinmododafarlirientraretuttiinun'unicapagina,as siemeaidati.Selascaladellavisualizzazionesitropporidottapossiamocliccareconildestro sullapercentualepresentenellabarradistato(inbasso)escegliereilvalore100%.Possiamo ancheagiresulformatodellapagina:MenuFormatoPaginadovepossiamoagiresull'orienta mentodellapagina(verticaleoorizzontale),suimargini(possiamoridurliperlasciarepiposto aicontenuti)sull'intestazioneosulpidipagina:togliamol'intestazioneemodifichiamoilpi dipaginascrivendoasinistraladataeadestrailnostronome. Un'occhiataallavorosvoltoconl'anteprimadistampapurassicurarcichetuttodispostoper benenellapagina.Sesiamosoddisfattipossiamoconsiderarefinitoillavoro,altrimentichiudia mol'anteprimaemodifichiamogliaspettichenoncipiacciono. Salviamoancoraunavoltaillavoroedeventualmentestampiamolo.

Fogliodicalcolo

187

Diagrammi

Riassumendo

Ilmodopisempliceperrealizzareundiagrammaquellodiselezionareidatichevogliamorap presentareepoiscegliereMenuInserisciDiagramma. Neldialogodicostruzionediundiagrammapossiamosceglierediversecaratteristiche: etichette, tipoesottotipo,assi,legenda,titoli,... Unavoltacostruitoundiagrammapossibilemodificarlousandoilmenucheapparedopoaveref fettuatoundoppioclicsuldiagrammastesso. Importantesalvarespessoilpropriolavoro. Lavistaconinterruzionidipaginapermettediimpaginareinmodoefficaceilnostrolavoro. IlmenuFormatoPaginapermettediinterveniresull'orientamento,ledimensioni,imargini,leinte stazioni,ipidipagina,...

Provatu 1. Disegnaalcunidiagramminelfogliorelativoalleregionid'Italia. 2. Disegnaalcunidiagramminelfogliorelativoalleprovinceitaliane. 3. Disegnaalcunidiagramminelfogliorelativoalledimensionicorporee.

188

Laboratoriodiinformatica

Indiceanalitico

7. Indiceanalitico
float............................................................................................................................................11 for...............................................................................................................................................20 idle...............................................................................................................................................8 IDLE............................................................................................................................................8 int...............................................................................................................................................11 istruzioni.......................................................................................................................................8 istruzioni........................................................................................................................................ print.........................................................................................................................................8 math............................................................................................................................................11 newline........................................................................................................................................9 sqrt..............................................................................................................................................11 \n..................................................................................................................................................9 Questolofarconcalma... Finalmentesonoarrivatoalterminediquestolavoro...terminesifaperdire.Moltoaltrosi potrebbescrivereesipotrebberoproporremoltialtriesercizi. Anchelaformapotrebbeesseremoltomigliorata:nonsonocertoespertoinimpaginazione! Nonostantelacurachehomessonelcontrollarecontenutoeforma,moltierrorimisaranno sfuggiti,ringraziochiunquemelisegnali. Ringraziochiavravutolaforzadileggerequestotestoo,magari,ilcoraggiodiusarlonelladi dattica,coscome,osoloinparteo,adattatoalleproprieesigenze.

MogoKelenTeSiraBe!

DanieleZambelli

Indiceanalitico

189

Potrebbero piacerti anche