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.

Naloge s predavanja :)

  1. Napiši funkcijo vsebuje_sodo, ki z enim zamahom (pogojem) ugotovi, ali seznam števil s vsebuje kako sodo število. Napiši še funkcijo samo_soda, ki preveri ali seznam vsebuje sama soda števila.
Rešitev
def vsebuje_sodo(s):
    return any(x % 2 == 0 for x in s)
  1. Napiši funkcijo izlusci_soda, ki sestavi seznam vseh sodih števil iz s.
Rešitev
def izlusci_soda(s):
    return [x for x in s if x % 2 == 0]
  1. Napiši funkcijo naj_razlika, ki poišče največjo razliko med dvema zaporednima številoma iz s.
Rešitev
def naj_razlika(s):
    return max(a - b for a, b in zip(s, s[1:]))
  1. Napiši funkcijo se_izmenjuje, ki preveri ali se v s izmenjujejo soda in liha števila?
Rešitev
def se_izmenjuje(s):
    return all(a % 2 != b % 2 for a, b in zip(s, s[1:]))
  1. Napiši funkcijo se_izmenjuje2, ki preveri ali se v s izmenjujejo soda in liha števila, pri čemer mora biti prvo število sodo?
Rešitev
def se_izmenjuje2(s):
    return all(st % 2 == i % 2 for i, st in enumerate(s))

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. (Ali je število palindromno, boste najlažje preverili tako, da ga za začetek spremenite v niz.)

$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. (Če imate seznam črk s, ga združite v niz z "".join(s).)

>>> 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(' '))

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
Zadnja sprememba: četrtek, 7. december 2023, 11.12