Projekt Pronal Projekt Pronal

Kazalo:
Sofinasiranje projekta
Starejši - učbenik...
Tekmovanja...
Tekmovanja - dopolni...
Tekmovanja - Parsons...
Tekmovanja - popravi...
Starejši - zbirka nalog
Funkcije
If stavek
Izpisi
Množice
Nizi
Pisanje in popravljanje programa
Seznami in nizi
Slovarji
Spoznajmo Python
Uvod v funkcije
Zanka for
Zanka while
Funkcije

Funkcije


Posoda z vodo

Matevž v posodo, ki ima obliko kvadra , na dnu pa obliko kvadrata, in je do vrha napolnjena z vodo, polaga predmete različnih oblik, pri čemer ga zanima, koliko litrov vode ostane v posodi, po tem ko vanjo položi nek predmet.

Volumen take posode lahko izračunamo po formuli: $volumen(kvader) = širina * širina * višina$, pri tem pa moramo upoštevati tudi enote, v katerih so podane dimenzije posode. Ker želimo dobiti razliko volumna posode in izbranega predmeta v litrih, upoštevamo zvezo: $1 dm^3 = 1 liter$. Da jo lahko uporabimo, moramo enote v katerih so podane dimenzije posode in izbranega predmeta, najprej pretvoriti v decimetre.

1. podnaloga

Matevž v posodo najprej položi kroglo z radijem $5 cm$.

Spodnja funkcija za sirino in visino posode, podanima v cm

import math
def koliko_vode_ostane(sirina, visina):
   """Na tri decimalke natančno vrne, koliko litrov vode je ostalo v posodi."""
   volumen_krogle = 4 / 3 * math.pi * (5 / 10)**3   # 5 cm pretvorimo v 0.5 dm
   volumen_posode = (sirina / 10) ** 2 * (visina / 10)   # vrednosti stranic v cm pretvorimo v dm
   ostanek_vode = round(volumen_posode - volumen_krogle, 3)
   return ostanek_vode

izračuna, koliko litrov vode ostane v posodi po tem, ko vanjo položimo kroglo s polmerom $5 cm$.

Spremenite to funkcijo v koliko__vode_ostalo(sirina, visina, polmer), ki izračuna koliko litrov vode ostane v posodi, če vanjo položimo kroglo s polmerom polmer, prav tako podanem v cm. Zgled:

>>> koliko_vode_ostalo(10, 10, 3)
0.887

Namig: Volumen krogle izračunamo po formuli: $volumen(krogla) = \frac{4}{3}\pi r^3$.

Uradna rešitev

import math
def koliko_vode_ostalo(sirina, visina, polmer):
    """Na tri decimalke natančno vrne, koliko litrov vode je ostalo v posodi."""
    volumen_krogle = 4/ 3 * math.pi * (polmer / 10)**3
    volumen_posode = (sirina / 10) ** 2 * (visina / 10)
    ostanek_vode = round(volumen_posode - volumen_krogle, 3)
    return ostanek_vode

2. podnaloga

Matevž v posodo sedaj položi stožec, katerega premer je enak širini posode, višina pa enaka globini posode.

Napišite funkcijo koliko_ostalo_stozec(sirina, visina, n), ki izračuna koliko litrov vode je ostalo v posodi ter vrne rezultat, zaokrožen na n decimalk. Funkcija sprejme širino in višino posode v cm. Zgled:

>>> koliko_ostalo_stozec(10, 10, 3)
0.738

Namig: volumen stožca izračunamo po formuli:

$volumen(stozec) = \frac{1}{3} volumen(valj)$,

volumen valja pa po formuli:

$volumen(valj) = \pi r^2 l$,

kjer $l$ v tem primeru predstavlja kar višino posode, $r$ pa polovico njene širine.

Uradna rešitev

import math
def koliko_ostalo_stozec(širina, višina, n):
    """Na n decimalk natančno vrne, koliko litrov vode je ostalo v posodi."""
    volumen_stozca = (1 / 3) * math.pi * ((širina / 10) / 2)**2 * (višina / 10)
    volumen_posode = (širina / 10)**2 * (višina / 10)
    ostanek_vode = round(volumen_posode - volumen_stozca, n)
    return ostanek_vode

Varčevanje na obroke

Pri varčevanju na obroke na začetku vplačamo nek znesek, nato pa vsak mesec doplačujemo mesečne obroke. Zaradi enostavnosti predpostavimo, da so vplačila vedno prvi dan v mesecu, vrednost varčevalnega računa pa se vedno računa ob koncu meseca. Denar, ki ga imamo na varčevalnem računu, se obrestuje po fiksni obrestni meri.

1. podnaloga

V bančništvu pogosto navajamo letno obrestno mero, obrestujemo pa mesečno. Zato je pred računanjem potrebno obrestno mero primerno spremeniti.

Napišite funkcijo mesecna_obrestna_mera(letna_obrestna_mera), ki kot parameter sprejme letno obrestno mero v odstotkih, vrne pa ustrezno mesečno obrestno mero kot decimalno število. Zgled:

>>> mesecna_obrestna_mera(12)
0.01

Uradna rešitev

def mesecna_obrestna_mera(r):
    """Vrne mesečno obrestno mero v decimalni obliki."""
    return r / 12 / 100

2. podnaloga

Pri enostavnem obrestovanju s fiksno letno obrestno mero $r$ se vedno obrestuje samo glavnica, ne pa tudi obresti. Tako je vrednost na računu pri začetnem pologu $A_0$ po $n$ mesecih podana s formulo $$A = A_0 * (1 + m * n)\text{,}$$ kjer je $m$ pripadajoča mesečna obrestna mera.

Sestavite funkcijo enostavno_obrestovanje(polog, letna_obrestna_mera, st_mesecev), ki za enostavno obrestovanje izračuna vrednost denarja na računu pri danem začetnem pologu, letni obrestni meri in številu mesecev.

Primeri:

>>> enostavno_obrestovanje(100, 10, 0)
100
>>> enostavno_obrestovanje(100, 12, 1)
101
>>> enostavno_obrestovanje(100, 10, 12)
110

Uradna rešitev

def enostavno_obrestovanje(polog, letna_obrestna_mera, st_mesecev):
    """Vrednost obrestovanega denarja pri enostavnem obrestovanju."""
    return polog * (1 + mesecna_obrestna_mera(letna_obrestna_mera) * st_mesecev)

3. podnaloga

Pri obrestno obrestnem računu s fiksno letno obrestno mero $r$ se zraven glavnice obrestujejo tudi obresti. Za glavnico $A_0$ je vrednost po $n$ mesecih podana s formulo $$A = A_0(1 + m)^n\text{,}$$ kjer je $m$ pripadajoča mesečna obrestna mera.

Sestavite funkcijo obrestno_obrestovanje(polog, letna_obrestna_mera, st_mesecev), ki izračuna vrednost denarja na računu pri danem začetnem pologu, letni obrestni meri in številu mesecev, pri čemer se obresti računajo po obrestno obrestnem računu.

Primeri:

>>> obrestno_obrestovanje(100, 10, 0)
100.0
>>> obrestno_obrestovanje(100, 10, 1)
100.83333333333333
>>> obrestno_obrestovanje(100, 12, 12)
112.68250301319698

Uradna rešitev

def obrestno_obrestovanje(polog, letna_obrestna_mera, st_mesecev):
    """Vrednost obrestovanega denarja pri obrestno obrestnem obrestovanju."""
    return polog * (1 + mesecna_obrestna_mera(letna_obrestna_mera))**st_mesecev

Alarm

Tomaž je začel trenirati košarko. Sestavite funkciji, ki mu bosta pomagali, da ne bo nikoli zamudil svojih treningov.

1. podnaloga

Ura je 13. Čez natanko 7 ur se začne trening. Sestavite funkcijo alarm(ura_sedaj, koliko_h), ki sprejme trenuten čas ter število ur do pričetka naslednjega treninga in pove ob kateri uri dneva (dan sam nas ne zanima) se bo sprožil alarm. Ko se sproži alarm, mora Tomaž takoj na trening. Tomaž se mora na trening odpraviti eno uro pred njegovim začetkom.

Na primer:

>>> alarm(13, 7)
19
>>> alarm(6, 47)
4

Namig: Ne pozabite, dan nas ne zanima.

Uradna rešitev

def alarm(ura_sedaj, koliko_h):
    """Funkcija pove, ob kateri uri se moram odpraviti na trening."""
    return (ura_sedaj + koliko_h - 1) % 24

2. podnaloga

Sestavite funkcijo alarm2(ura_sedaj, koliko_h), ki dela podobno kot zgornja funkcija, le da poleg ure dneva, ko mora Tomaž na trening, pove tudi, čez koliko dni se bo treba odpraviti. Funkcija torej vrne urejen par števil. Prvo število je število dni, drugo število je ura dneva. Na primer:

>>> alarm2(13, 7)
(0, 19)
>>> alarm2(6, 47)
(2, 4)

Uradna rešitev

def alarm2(ura_sedaj, koliko_h):
    """Funkcija vrne urejen par števil - prvo pove čez koliko dni se moram
       odpraviti na trening, drugo pa ob kateri uri tega dneva se moram odpraviti."""
    return (ura_sedaj + koliko_h - 1) // 24, (ura_sedaj + koliko_h - 1) % 24

Mirko in Slavko

Mirko in Slavko sta partizanska kurirja iz jugoslovanskega stripa Mirko in Slavko. Po stripu so posneli tudi film.

1. podnaloga

Prevara s čekom

Kurirji so iznajdljivi, sploh pa Mirko in Slavko. V roke sta dobila ček, kjer banka prinositelju izplača vrednost na njem napisanega tromestnega zneska. Vendar Mirko ne bi bil Mirko, če ne bi kaj hitro ugotovil, da lahko s spretnostjo in ostrim nožičem ček neopazno spremeni tako, da premeša števke na znesku. A kaj, ko je Mirko bolj slab v matematiki, rad pa bi ček popravil tako, da bo dobil kar se da veliko. Potoži se Slavku, ta pa odvrne: "Ah, to pa ja ni problem. Poglej spodnjo funkcijo. Malo jo spremeni, pa boš dobil največje možno število."

def kaj_delam(n):
    """Pozor, n je obvezno tromestno naravno število
       Spremenljivke imajo namenoma čudna imena.
    """
    a = n - n % 10
    b = a // 10  % 10
    c = n - a
    d = n // 100
    e = max(b, c, d)
    f = min(b, c, d)
    g = b + c + d - e - f
    return f, g, e

Premislite, kaj funkcija počne, in na osnovi ideje v njej namesto Mirka sestavite funkcijo naj_tromestno(n), ki iz danega tromestnega števila sestavi največje možno tromestno število.

>>> naj_tromestno(137)
731
>>> naj_tromestno(625)
652

Uradna rešitev

def naj_tromestno(n):
    """Iz števk danega tromestnega števila sestavi največje možno število."""
    enice = n % 10
    desetice = n//10 % 10
    stotice = n // 100
    najmanjse = min(enice, desetice, stotice)
    najvecje = max(enice, desetice, stotice)
    srednje = enice + desetice + stotice - najmanjse - najvecje   # srednje po velikosti
    return najvecje * 100 + srednje * 10 + najmanjse

2. podnaloga

Mirko in Slavko ob pomoči Dimnjačare pečeta palačinke

Mirko in Slavko sta v uspešni akciji zaplenila velike količine moke in jajc, zato bosta za celo vas Glavuša na Kozari napekla palačinke.

Ampak kaj, ko ne vesta koliko! Dimnjačara jima je zato napisal funkcijo, vendar mu je, tik preden je odšel, izpod listov trpotca, ki jih je imel na čelu namesto obveze, padlo par kapelj krvi in sedaj funkcija izgleda tako:

def koliko_palacink(stevilo_odraslih, stevilo_otrok):
    """Vrne število palačink, potrebnih, da nasitijo vse povabljene."""
    PACKA
    PACKA
    palacinke_odrasli = stevilo_odraslih * odrasel
    palacinke_otroci = stevilo_otrok * otrok
    palacinke_skupaj = palacinke_odrasli + palacinke_otroci + PACKA   # še malo za rezervo
    return palacinke_skupaj

Na srečo pa so ostali trije Dimnjačarini zapiski, ki prikazujejo delovanje funkcije. Pomagajte Mirku in Slavku in dopolnite funkcijo, da se bo obnašala kot prej, če so zapiski:

  • Koliko je odraslih: 1 Koliko je otrok: 0 Napeči je treba 12 palačink.

  • Koliko je odraslih: 0 Koliko otrok: 1 Napeči je treba 9 palačink.

  • Koliko je odraslih: 10 Koliko otrok: 15 Napeči je treba 87 palačink.

Uradna rešitev

def koliko_palacink(stevilo_odraslih, stevilo_otrok):
   """Vrne število palačink potrebnih, da nasitijo vse povabljene."""
   odrasel = 5
   otrok = 2
   palacinke_odrasli = stevilo_odraslih * odrasel
   palacinke_otroci = stevilo_otrok * otrok
   palacinke_skupaj = palacinke_odrasli + palacinke_otroci + 7   # še malo za rezervo
   return palacinke_skupaj

3. podnaloga

Slavko peče torte

Po velikem uspehu s peko palačink, se je Slavko spravil peči torte. Po receptu za torto potrebujemo $0.8 kg$ margarine, $2 kg$ moke in $1.5 kg$ sladkorja. Sedaj Slavka zanima, kakšno je, glede na količine sestavin, ki jih ima na razpolago, največje možno število tort, ki jih lahko naredi.

Slavku sestavite funkcijo koliko_tort(margarina, moka, sladkor), ki glede na dani recept določi največje možno število tort. Zgled:

>>> koliko_tort(5, 7, 3.5)
2

Namig: Funkcija min vrne najmanjšega izmed svojih parametrov.

Uradna rešitev

def koliko_tort(margarina, moka, sladkor):
    """Maksimalno število tort, ki jih lahko spečemo iz danih sestavin."""

    recept_margarina = 0.8   # količina margarine po receptu
    recept_moka = 2   # količina moke za eno torto po receptu
    recept_sladkor = 1.5   # količina sladkorja po receptu

    # koliko tort glede na posamezno sestavino
    iz_moke = int(moka / recept_moka)
    iz_margarine = int(margarina / recept_margarina)
    iz_sladkorja = int(sladkor / recept_sladkor)
    torte = min(iz_moke, iz_margarine, iz_sladkorja)
    return torte

4. podnaloga

Mirko in smučarski skoki

Medtem, ko Slavko peče torte, je Mirko organiziral tekmovanje v smučarskih skokih.

Pri smučarskih skokih so točke skoka vsota:

  • točk za daljavo in
  • točk sloga (ki jih določijo sodniki).

Vsak od petih sodnikov lahko skakalcu dodeli največ 20 točk, ki so odvisne od položaj smuči med letom, ravnotežja med letom, položaja telesa, pristanka ipd. Točke sloga so vsota točk posamičnih sodnikov, pri čemer se najboljša in najslabša ocena ne upoštevata.

Mirko ima več kot dovolj dela z iskanjem primernih sodnikov (pa še z njegovo matematiko je bolj tako, tako...). Zato mu pomagajte in sestavite funkcijo tocke_slog(oc1, oc2, oc3, oc4, oc5), ki za danih 5 ocen določi točke za slog. Zgled:

>>> tocke_slog(14, 15, 16, 17, 18)
48

Namig: Poleg funkcije min Python pozna tudi funkcijo max, ki se obnaša podobno.

Uradna rešitev

def tocke_slog(oc1, oc2, oc3, oc4, oc5):
    """Vrne število točk, ki jih dobi skakalec za slog."""
    vse_skupaj = oc1 + oc2 + oc3 + oc4 + oc5
    najslabsa = min(oc1, oc2, oc3, oc4, oc5)
    najboljsa = max(oc1, oc2, oc3, oc4, oc5)
    return vse_skupaj - najslabsa - najboljsa

Funkcije višjega reda

Tale naloga je namenjena vsem, ki imate radi matematiko, pa tudi tistim, ki radi spreminjate svet in stvari.

Spodaj je primer funkcije višjega reda eksponentna(a), ki kot argument dobi število $a$ in vrne funkcijo $x \mapsto a^x$. Zgled uporabe:

>>> f = eksponentna(2)
>>> f(5)
32
>>> f(0.5)
1.4142135623730951

1. podnaloga

Sestavite funkcijo linearna(a, b), ki kot argumenta dobi števili $a$ in $b$ ter vrne funkcijo $x \mapsto a \cdot x + b$. Zgled:

>>> f = linearna(3, 2)
>>> f(0.5)
3.5

Uradna rešitev

def linearna(a, b):
    """Vrne funkcijo, ki sprejme število x ter vrne vrednost izraza a*x + b."""
    return lambda x: a*x + b

2. podnaloga

Sestavite funkcijo kompozitum(f, g), ki kot argumenta dobi funkciji f in g, ter vrne njun kompozitum. Zgled:

>>> import math
>>> f = kompozitum(abs, math.sin)
>>> f(3 * math.pi / 2)
1.0

Uradna rešitev

def kompozitum(f, g):
    """Vrne funkcijo, ki sprejme število x ter vrne kompozitum funkcij f in g na številu x."""
    return lambda x: f(g(x))

3. podnaloga

Sestavite funkcijo odvod(f, epsilon=10e-5), ki sprejme funkcijo f in vrne njen odvod (ki je spet funkcija). Odvod v točki x ocenimo z izrazom $f'(x) \approx (f(x + \epsilon/2) - f(x - \epsilon/2)) / \epsilon$. Zgled:

>>> f = odvod((lambda x: x * x + 1))
>>> f(1.0)
2.000000000002

Uradna rešitev

def odvod(f, epsilon=10e-5):
    """Vrne funkcijo, ki sprejme število x ter vrne odvod funkcije f v točki x z okolico epsilon."""
    return lambda x: (f(x + 0.5 * epsilon) - f(x - 0.5 * epsilon))/epsilon
Mesto objave ob koncu projekta 15.9.2018