Naloge
Vse naloge se da lepo rešiti z izpeljanimi seznami in izpeljanimi množicami. Običajni zanki for in while sta danes prepovedani. Osredotočite se na uporabo izpeljanih seznamov.
Vsota kvadratov
Napišite funkcijo vsota_kvadratov(n)
, ki izračuna vsoto kvadratov prvih n
naravnih števil.
$1^2 + 2^2 + 3^2 ... + 10^2 = ?$
>>> vsota_kvadratov(10)
385
Rešitev
def vsota_kvadratov(n):
return sum(i**2 for i in range(1, n+1))
Napišite funkcijo vsota_kvadratov_pal(n)
, ki bo izračunala vsoto kvadratov vseh palindromnih števil, manjših ali enakih n
? . Palindromna števila so tista, ki se preberejo iz obeh strani enako. Primer palindromnega števila je 12321.
$1^2 + 2^2 + ... + 323^2 + 333^2 + 343^2 + ... + 999^2 = ?$
>>> vsota_kvadratov_pal(1000)
33454620
Če vam dela naloga težave, najprej poskusite sestaviti seznam palindromnih števil in ga izpišite, da preverite, ali je pravilen. Nato mu dodate le še seštevanje.
Rešitev
def vsota_kvadratov_pal(n):
return sum(i**2 for i in range(1, n+1) if str(i) == str(i)[::-1])
Zamenjava črk
Napišite funkcijo subs(niz, polozaj)
, ki premeče črke v nizu glede na
podane nove položaje.
>>> subs("abc", "0002")
'aaac'
>>> subs("komar", "23401")
'marko'
Rešitev
def subs(niz, polozaj):
return ''.join(niz[int(i)] for i in polozaj)
Povprečje in standardni odklon
Napišite funkciji, ki izračunata povprečje (mean
) in standardni odklon (std
) populacije, ki je podana s seznamom števil xs
.
Standardni odklon je v testih izračunan po formuli $\sigma =\sqrt {\frac {\sum_{i=1}^N(x_i-{\overline x})^2}{N}}$.
>>> xs = [183, 168, 175, 176, 192, 180]
>>> mean(xs)
179.0
>>> std(xs)
7.43863786814
Rešitev
import math
def mean(xs):
return sum(xs) / len(xs)
def std(xs):
a = mean(xs)
return math.sqrt(sum((x - a)**2 for x in xs) / len(xs))
def std_slow(xs):
return math.sqrt(sum((x - mean(xs))**2 for x in xs) / len(xs))
Večina vas je napisala nekaj takega. Funkcija std_slow sicer vrača pravilen rezultat, je pa žal počasnejša kot bi morala biti. Kar poskusite primerjati čas izvajanja funkcij std in std_slow, pa boste razumeli kaj pomeni razlika med linearno in kvadratno časovno zahtevnostjo. V takih primerih se je pač treba odreči "oneliner-jem" ali pa ...
def std_oneline(xs):
return math.sqrt(sum(map(lambda x, a=mean(xs): (x - a)**2, xs)) / len(xs))
... ali pa napisati nekaj takega :) Tale rešitev si zasluži zvezdico, ker presega okvire tega predmeta. Naj jo razume tisti, ki ga te stvari zanimajo.
Morsejeva abeceda
Napišite funkcijo txt2morse(s)
, ki pretvori sporočilo s
v Morsejevo abecedo in
funkcijo morse2txt(s)
, ki naredi nasprotno.
>>> txt2morse('TE A')
'- . .-'
>>> txt2morse('HELLO WORLD')
'.... . .-.. .-.. --- .-- --- .-. .-.. -..'
>>> morse2txt('.... . .-.. .-.. --- .-- --- .-. .-.. -..')
'HELLO WORLD'
Če ste pozabili, ali pa morda nikoli niste znali, je Morsejeva abeceda prikazana spodaj. Morda se vam jo splača še kako dopolniti.
'A': '.-',
'B': '-...',
'C': '-.-.',
'D': '-..',
'E': '.',
'F': '..-.',
'G': '--.',
'H': '....',
'I': '..',
'J': '.---',
'K': '-.-',
'L': '.-..',
'M': '--',
'N': '-.',
'O': '---',
'P': '.--.',
'Q': '--.-',
'R': '.-.',
'S': '...',
'T': '-',
'U': '..-',
'V': '...-',
'W': '.--',
'X': '-..-',
'Y': '-.--',
'Z': '--..',
'1': '.----',
'2': '..---',
'3': '...--',
'4': '....-',
'5': '.....',
'6': '-....',
'7': '--...',
'8': '---..',
'9': '----.',
'0': '-----',
Rešitev
morse = {
'A': '.-',
'B': '-...',
'C': '-.-.',
'D': '-..',
'E': '.',
'F': '..-.',
'G': '--.',
'H': '....',
'I': '..',
'J': '.---',
'K': '-.-',
'L': '.-..',
'M': '--',
'N': '-.',
'O': '---',
'P': '.--.',
'Q': '--.-',
'R': '.-.',
'S': '...',
'T': '-',
'U': '..-',
'V': '...-',
'W': '.--',
'X': '-..-',
'Y': '-.--',
'Z': '--..',
'1': '.----',
'2': '..---',
'3': '...--',
'4': '....-',
'5': '.....',
'6': '-....',
'7': '--...',
'8': '---..',
'9': '----.',
'0': '-----',
' ': ''
}
def txt2morse(s):
return ' '.join(morse[c] for c in s)
morse_r = {v: k for k, v in morse.items()}
def morse2txt(s):
return ''.join(morse_r[c] for c in s.split(' '))
Obrni
Napiši funkcijo obrni(t)
, ki bo obrnila (transponirala) 2D tabelo t
, ki je podana
kot seznam seznamov enakih dolžin.\
>>> t = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> obrni(t)
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Rešitev
def obrni(t):
return [[t[i][j] for i in range(len(t))] for j in range(len(t[0]))]
ISBN
Napišite funkcijo valid(s)
, ki preveri ali je podan ISBN
veljaven.
>>> valid('0306406152'), valid('0553382578'), valid('0553293370'), valid('912115628X') # primer veljavnih ...
(True, True, True, True)
>>> valid('03064061522'), valid('1553382578'), valid('91211562811') # ... in neveljavnih ISBN.
(False, False, False)
Rešitev
def valid(isbn):
return len(isbn) == 10 and sum((10 if c == 'X' else int(c)) * (10 - i) for i, c in enumerate(isbn)) % 11 == 0
EAN
Zdaj pa napišite še funkcijo valid_ean(s)
, ki preveri pravilnost kode EAN, ki jo najdete na črtnih kodah v trgovini (in še kje).
Rešitev
def valid_ean(s):
return sum(int(x) * (1 + 2 * (i % 2)) for i, x in enumerate(str(s))) % 10 == 0