2  Dæmi um Python forrit

2.1  Tafla yfir veldi

Eitt af því sem tölvur eru góðar í er að framkvæma sömu hlutina aftur og aftur. Ein einfaldasta leiðin til að endurtaka skipanir í Python er að nota for-skipun. Hér er dæmi um Python-forrit sem reiknar og skrifar út önnur og þriðju veldi talnanna 1 til 5:

Forrit 2.1 Veldatafla
print(" k  k²   k³")
print("–––––––––––")
for k in range(1,6):
   print(f"{k:2} {k**2:3} {k**3:4}")

Þetta forrit kynnir fleira til sögunnar, t.d. svonefnda f-strengi til að stjórna sniði þess sem er prentað og virkjann ** sem gefur veldi.

Æfing: Veldatöfluforrit prófað

Ýmsar vefsíður bjóða upp á keyrslu Python forrita, t.d. ideone.com og online-python.com Afritið (eða sláið inn) forritið Veldatafla inn í aðra hvora af þessum síðum og keyrið það. Prófið að breyta forritinu (finnið t.d. fleiri veldi).

2.2  Collatz-runur

Collatz-runur eru reiknaðar þannig að byrjað er með einhverja tölu \(n_0\) og svo er næsta tala reiknuð aftur og aftur skv.

\[\begin{split}n_{k+1} = \begin{cases} \displaystyle\frac{n_k}{2} \text{ ef $n_k$ er slétt tala}\\ 3n_k+1 \text{ ef $n_k$ er oddatala} \end{cases}\end{split}\]

Ef nýja talan \(n_{k+1} = 1\) þá er hætt.

Ef við byrjum t.d. með \(n_0=5\) þá fæst runan 5, 16, 8, 4, 2, 1. Runurnar heita eftir þýska stærðfræðingnum Lothar Collatz (1910–1990) sem setti fram þá tilgátu árið 1937 að það sé sama hvaða \(n_0\) er byrjað með, runan muni alltaf að lokum lenda í 1 og hætta. Enn hefur engum tekist að sanna tilgátuna, og reyndar virðast jafnvel færustu stærðfræðingar ekki hafa hugmynd um hvernig ætti að byrja.

2.3  Forrit fyrir Collatz-runur

Eftirfarandi Python forrit finnur og prentar út Collatz-runur sem byrja á 2, 3,…, 7:

Forrit 2.2 Collatz
# COLLATZ ÆFING
def næsta(x):
    # skilar næstu tölu á eftir x í Collatz-runu
    if x % 2 == 0:
        f = x//2
    else:
        f = 3*x + 1
    return f

def collatz_runa(n):
    # finnur og skrifar út Collatz-runu sem byrjar á n
    print('runa: ', end='')
    while n > 1:
        print(n, end=', ')
        n = næsta(n)
    print(n)

# Forrit sem prentar út Collatz-runur sem byrja á 2, 3,...,7:
print('Nokkrar Collatz-runur')
for n0 in range(2,8):
    collatz_runa(n0)

2.4  Python atriði sem koma fyrir í forritinu Collatz

  • Ný föll má skilgreina með því að byrja á def og nöfn þeirra mega hafa íslenska stafi (og líka gríska). Á eftir def-línunni er hefð fyrir að setja annaðhvort athugasemd (comment) sem byrjar á # eða skjölunarstreng (doc-string) innan þrefaldra gæsalappa, sem lýsir því hvað fallið gerir. Nánar tiltekið er ritað:

    def nafn(stiki1, stiki2... ):    eða:  def nafn(stiki1, stiki2... ):
       # lýsing-á-hvað-fallið-gerir           '''lýsing-á-hvað-fallið-gerir'''
       skilgreining-falls                     skilgreining-falls
    
  • Ef-setning hefur ekki sviga utan um skilyrðið, öfugt við mörg forritunarmál (t.d. C og Java). Sniðið er svona:

    if skilyrði:
        skipanir
    elif skilyrði:
        skipanir
    else:
        skipanir
    

    Það má líka sleppa eða hafa fleiri elif kafla og/eða sleppa else kafla.

  • While-lykkjur hafa snið

    while skilyrði:
        skipanir
    
  • For-lykkjur hafa snið

    for k in range(b,e):
        skipanir
    

    k tekur þá gildi b, b+1,…, e–1. range(e) jafngildir range(0,e), og svo má taka stærri skref: range(b,e,d) hleypur í gegn um k = b, b + d, b + 2d,… og hættir ef k ≥ e.

  • Athugasemdir (comments) byrja á #

  • Virkinn % gefur afgang úr deilingu (mod)

  • // gefur heiltöludeilingu (og ef útkoman er brot er hún lækkuð niður í átt að 0)

  • Eins og í flestum forritunarmálum er „=“ gildisgjöf (assignment) og „==“ samanburður

  • Föll sem skila gildi enda oftast á return gildi

  • Inndráttur er notaður til að sýna hvar blokkir enda (þ.e.a.s. blokkir sem def, if, else, while o.fl. skilgreina). Skipanir sem byrja slíkar blokkir enda alltaf á tvípunkti (þ.e.a.s. :)

  • Strengi má búa til með því að setja einfaldar gæsalappir utan um þá, en líka má nota tvöfaldar, t.d. "strengur".

  • Til að kalla á fall er notað nafn(viðföng) (t.d. næsta, collatz_runa og innbyggða fallið print)

  • Fallið print fer sjálfkrafa í næstu línu eftir prentun, nema ef viðbótin end=… er með.