Python (programski jezik)

Python je interpretni visokoravni večnamenski programski jezik, ki ga je ustvaril Guido van Rossum leta 1990. Jezik je dobil ime po priljubljeni angleški televizijski nanizanki Leteči cirkus Montyja Pythona (Monthy Python's Flying Circus). Python podpira dinamične podatkovne tipe, kar ga naredi drugačnega od npr. Jave ali družine C. Zaradi dinamičnih podatkovnih tipov je podoben jezikom Perl, Ruby, Scheme, Smalltalk in Tcl. Upravlja s pomnilnikom in podpira funkcionalen, imperativen oziroma proceduralen, strukturiran in objektno orientiran programski stil. Razvili so ga kot odprtokodni projekt, ki ga upravlja neprofitna organizacija Python Software Foundation.

Python
Začetna izdaja20. februar 1991[1]
OblikovalGuido van Rossum[d][1]
RazvijalecPython Software Foundation[d] in Guido van Rossum[d][1]
Stabilna izdaja3.12.3[2] in 3.13.0a6[2]
Tipizacijadinamično, močno, varno
Večje implementacijeCPython, IronPython, Jython, Python for S60, PyPy
VpliviALGOL 68[d][3], ABC[d][4], Modula-3[d][5], C[6], C++[5], Perl, Java, Lisp, Haskell[7], APL[d], CLU[d], Dylan[d], Icon[d] in Standard ML[d]
Vplival naBoo, Cobra, D, Falcon, Groovy, JavaScript, Ruby
OSvečplatformsko[d][8]
LicencaPython Software Foundation License[d][1]
Spletna stranhttps://www.python.org/[9]
Wikibooks logo Python Programming na Wikibooks

Pogosto uporabljene knjižnice

Python ima že ob namestitvi nekaj knjižnic oz. modulov. To so skupki programske kode, najpogosteje funkcij, ki jih nato pisci kode uporabijo v svojih programih. Nekaj izmed teh je napisanih v jeziku C[10] za doseganje optimalnih časov pri klicanju in izvedbi funkcij. Navkljub dejstvu, da je Python večplatformski, standardni nabor knjižnic ni enak na Linuxu[11] ali Windowsu[12]. Primarne knjinžnice standardnega nabora so math[13], podpora matematičnih funkcij, sys[14], za uporabo sistemskih funkcij in os[15], za nadziranje funkcij operacijskega sistema.

Knjižnice standardnega nabora
Ime knjižniceNamembnostFunkcije
mathPodpora matematičnih funkcij v Pythonupi, e, ceil, cos, sin, tan, log, degrees, radians
random[16]Generacija naključnih števil in znakovrandom, randint, randrange, choice
datetime[17]Implementacija časovnih pasovdatetime, date, timeifo
tkinter[18]Dodana funkcionalnost grafičnih vmesnikovTk, Label, Frame, Button, Entry
sys[14]Vsebuje interpretno odvisne funkcijeversion, platform, path, argv
os[19]Služi kot vezni člen med Pythonovim večplatformskim

delovanjem in operacijskim sistemom

getcwd, popen, close, rename,

Python je zaradi svoje preproste sintakse izredno preprost za uporabo. To omogoča programiranje tudi začetnikom. Je tudi odlika, ki veliko doprinese pri oblikovanju lastnih knjižnic. Knjižnice, ki niso v standardnemu naboru, so knjižnice t.i. 3. nabora. Naložene so na portalu PyPi in jih uporabnik sam namesti. Med njimi najdemo veliko knjižnic za velik asortiment področij. Trenutno je na portalu več kot 270.000 projektov z več kot 2.000.000 verzij.

Knjižnice 3. nabora
Ime knjižniceNamembnost
pygameTemelji na SDL-ju in služi kot funkcionalni nabor za razvijanje iger
pandasMočno optimizirana knjižnica za ekstrahacijo in obdelavo podatkov
matplotlibKnjižnica, namenjena prikazovanju grafov v obeh dimenzijah
numpyKnjižnica je namenjena numeričnim komputacijam in obdelavi tenzorjev
scipyEfektivna zbirka funkcij za komputacije v statistiki in algebri

Uporaba in namembnost Pythona v aplikacijah

Python uporablja različna orodja za različne tipe aplikacij, saj vsebuje tako orodja za pripravo grafike kot matematični modul za izračunavanje... Med grafično orientiranimi moduli so najbolj pogosti tkinter, ki je tudi del standardnega nabora. Poznamo tudi PyQt5 za naravni izgled oken na Windowsih ter Kivy, posebej prilagojen za grafiko na telefonih sistema IOs in Android.

Ima tudi orodja za razvijanje internetnih aplikacij, med najbolj pogosto uporabljena spadajo Django, ki ima svojo posebno knjižnico in deluje večinoma v relaciji s podatkovno bazo, Bottle, Flask, Tornado (orodje), web2py in Jade. Večina teh orodij mora uporabnik naložiti s spleta v intergrirano razvijalno okolje (Intergrated development enviroment, IDE). Zaradi preprostosti Pythona ga včasih uporabljajo za statistično-napovedovalne modele in programe, kot alternativo jeziku R. Med najpogosteje uporabljena analitična orodja spadajo SciPy, Pandas in Numpy. Večina analitičnih orodji je programiranih v jeziku C za optimalno delovanje in večplatformnega delovanja. Za razvijanje programske opreme pa se uporabljajo predvsem naslednja orodja: Buildbot, Trac in Roundup. Uporabljajo se tudi orodja za administracijo sistema, kot na primer: Ansible, Salt in OpenStack. Le-ti sistemi pa uporabljajo način MLA (multi language architecture, večjezična programska arhitektura), najdemo ga tudi v spletnih straneh[20]. Na področju umetne inteligence se Python uporablja zaradi preprostosti in velikega števila uporabnikov navkljub manjši hitrosti izvajanja. Uporabljajo ga NASA,[21] Pixar, Google, Facebook,[22] YouTube[23] in mnoge druge organizacije.

Zmogljivost in težave

Python je bil prvotno napisan za računalnike v 80. letih 20. stoletja, kjer so imeli večinsko samo enojedrne sisteme. Vse niti so tako delovale na enem jedru, ker računalnikov z več jedri preprosto ni bilo veliko. S časom pa so se pojavili računalniki z več jedri v CPE, katere še danes Python ne koristi zaradi ti. GIL (Global Interpreter Lock). V naslednjih letih je pričakovano, da se bo GIL verjetno odstranil s pomočjo ti. podtolmačev ki bi tolmačili vsak na svojem jedru ter komunicirali med seboj. Sicer pa se poraja vprašanje kakšen zmogljvostni vtis bo imela taka implementacija brez GIL na do sedaj napisane enojedrne Pythonove programe.

Ker je Python sam po sebi relativno počasen bodisi zaradi GIL (Global Interpreter Lock), ki dovoli uporabo samo enega jedra na enkrat, bodisi zaradi dinamičnih tipov ali overheada, ki ga povzročijo pri tekoči izvršitvi, se Python pogosto uporablja na visokonivojski plasti, ki kliče nižjenivojske funkcije, napisane v prevedenem jeziku kot npr. C. Tako povezavo med plastmi je možno doseči s standardno knjižnico ctypes in dinamično povezanimi knjižnicami, ki so zgrajene v C ali drugih prevedenih jeziki. Nestandardni način, ki je sicer industrijsko bolj uveljavljen (še posebej na embedded/AI čip področju) je uporaba nestandardne knjižnice Cython, ki umetno generira kompatibilnost med nizkonivojskimi hitrimi plastmi in visokonivojsko Pythonsko plastjo. To stori z tako imenovanimi .pyx (abstrakcije deklariranih konstruktov) in .pxd (deklaracije eksternih C simbolov) datotekami. V projektu se Cython se konfigurira na nivoju setup.py datoteke.

Poleg glavne implementacije pythonovega tolmača ti. CPython, imamo mnoge druge implementacije, kot npr. PyPy, ki doda JIT (Just-in-time compiler), kar lahko za določen tip aplikacij močno pospeši hitrost programa za nekatere pa močno upočasni hitrost programa.

Struktura python projekta

V splošnem se Python programi pišejo v .py datoteke čeprav so končnice neobvezne. Na prvi vrstici se lahko nahaja ti. shebang line npr. #!/usr/bin/env python3, tj. pot do tolmača (oz. ukaz, ki vrne pot do dolmača), ki bo izvajal sledečo kodo. Podoben princip obstaja v shell/bash skriptah. Shebang vrstica ponavadi ne deluje na Windows OS.

Poleg shebang vrstice imamo tudi coding vrstico, ki določa/namigne tolmaču kateri nabor znakov uporablja ta datoteka, npr: # -*- coding: utf-8 -*-.

Če za modul/datoteko vemo, da se lahko uporablja kot vhodna točka programa, potem po konvenciji vanjo zapišemo sledečo kodo:

# Deklaracije/definicije, tisto kar se lahko vnese v druge moduleif __name__ == "__main__":    # Koda ki se izvršuje    pass

Tako ima lahko Python program več vstopnih točk, zaganjamo pa lahko samo eno na enkrat.

Ponavadi se Python moduli nahajajo znotraj paketov ti pa znotraj ti. virtualnih okolji. Virtualno okolje je kot svoj lasten python za specifičen projekt katerega drugi projekti v splošnem ne vidijo (čeprav ga je možno deliti).

Najbolj primitivno virtualno okolje (tj. samo tolmač s pip upravljalcem paketov) je inicializirano s venv. Poleg tega se v projektu nahaja še requirements.txt v katerem so zapisana v obliki semantičnega versioninga imena in verzije odvisnosti (eksternih knjižnic), ki jih pip namesti v virtualno okolje.

Za večji nadzor in ker ni praktično imeti celotnega pythona v istem direktoriju kot dejanski projekt so na voljo ti. angl. package managerji drugega nivoja npr. pipenv in poetry. Pri obeh se ob inicializaciji v projektu zgenerirata dve datoteki oblike *[.toml] in *.lock v TOML datoteki so zapisane odvisnosti (eksterne knjižnice), v autogenerirani (glede na TOML) LOCK datoteki pa SHA128/SHA256 razpršilniki, semantične verzije trenutno nameščenih eksternih knjižnice, indeksi (registri) od kod se te knjižnice nameščajo, ter pogoji namestitve (tj. nekatere knjižnice se ne nemeščajo na npr. Windows OS, itn.). Dejanski tolmač okolja in namesčene knjižnice v tem primeru ponavadi sedijo v enem izmed poddirektorijev $HOME/.virtualenvs.

Poleg package managerjev drugega in prvega nivoja, virtualnih okolji in zgeneriranih datotek, se uporabljata še dve orodji: linter in formater.

Linter je program, ki prebere kodo in strukturo projekta ter programerju vrne morebitne težave oz. nesledenje določenim konvencijam, ki so se izkazale za dobre. Linte (težave) je možno supresirati za določen segment kode z raznimi lint direktivi. Najbolj popularen python linter je pylint.

Formater je program, ki preoblikuje kodo da sledi raznim konvencijam. Npr. autopep8 formater preoblikuje kode tako da sledi PEP8 konvenciji ali pa black, ki sledi bolj svoji konvenciji in je pri tem neizprosen (se ga ne da konfigurirati). Tako kot linterje se pravila formatiranja da supresirati za določen segment kode z raznimi format direktivi.

Program 'Pozdravljen svet'

Python je znan po preprostosti kode, zato je eden izmed najbolj priljubljenih jezikov v zadnjem času[24] ter pri otrocih. Program je skoraj enak svoji psevdokodi, tj. besedilu, ki ga programerji pogosto naredijo med razmišljanjem o problemu. V Pythonu se tip niz (string) označuje z " " ali ' ', ki je v spodaj podanem primeru prvi parameter funkcije[25] print, ki se uporablja za izpis podatkov. V Pythonu obstajata dva tipa komentarjev: #, ki se uporablja za enovrstične komentarje. Docstring """ """ se uporablja za dokumentiranje programa vendar to *ni* komentar pač pa samo string, ki sam po sebi nič ne naredi.

# To bo izpisalo 'Pozdravljen svet', ta vrstica pa bo prezrtaprint('Pozdravljen svet')

Spremenljivke

V svetu informatike spremenljivka predstavlja prostor, kamor se shrani neka vrednost. Spremeljivke lahko poimenujemo s poljubnim nizom alfanumeričnih znakov in podčrtajev, a ime se ne sme začeti s številko ali biti ena izmed rezerviranih besed.

Definirajo se tako, da jih poimenujemo in jim dodelimo vrednost. V nasprotju z drugimi programskimi jeziki se spremenljivke same prilagodijo pravemu podatkovnemu tipu. Prevladujejo numerične, nizne in logične spremenljivke. Za preverbo podatkovnega tipa uporabimo funkcijotype(), ki nam vrne tip podanega parametra.

pozdrav = "Živjo"   # niz (string)denar = 100         # celo število (integer)povprečje = 12.699  # decimalno število (float)jeVesel = True      # boolean (True ali False), lahko ju tudi izrazimo z 1(True) ali 0(False)kompleksno_število = 2+5j       # kompleksno številonič = None # ničelni podatkovni tip (NoneType) ta podatkovni tip je poseben, saj nima dejanske vrednosti.type(pozdrav) #ali katerokoli drugo že definirano spremenljivko

Tudi objekti, definirani s strani uporabnika, se štejejo kot tip spremenljivke, npr. Uporabnik. Vsaka spremenljivka ima svoje posebnosti zaradi različnih posebnosti v naravi Pythona samega. Tako lahko uporabimo dejstvo, da je vsak podatkovni tip lasten objekt. Tako lahko s spremenljivkami upravljamo tipe po atributih. Nizne spremenljivke lahko režemo zaradi skupnih lastnosti z kolektivnimi tipi spremenljivk (niz postane list spremenljivka).

x = "Danes je oblačno"print(x[3]) # izpiše črko "e", saj Python začne vedno šteti z 0.print(x[5:]) # izpiše " je oblačno", saj izreže vse pred 5 (šteje se tudi presledek)print(x[:4]) # izpiše "oblačno", saj izreže vse po 4.print(len(x)) # izpiše dolžino besede shranjene v spremenljivki x. Izpiše '16'.print(x[:-3]) # izpiše "a", saj kadar uporabimo znak minus (-), začne šteti od desne proti levi.

Dostopnost spremenljivke[26]

Poznamo 3 stopnje dostopnosti spremenljivke. To so global, nonlocal in local. Prvostopenjske oz. globalne spremenljivke so definirane izven vseh funkcij, ponavadi na vrhu strani. Dostopne so celotnemu programu, ki pa jih lahko spreminja, a se ji stopnja med spreminjanjem vrednosti ne spremeni. Drugostopenjske spremenljivke, tako local kot nonlocal, so pa definirane znotraj posameznih enot programa (funkcij, objektov, ...) in niso dostopne programu na globalni ravni. local se uporablja znotraj ne-gnezdenih funkcij, nonlocal pa uporabljamo v več-ravenskih funkcijah.

ime = 'Janez'# Spremenljivka ime je globalnadef pozdravi():    pozdrav = 'Dober dan' # Spremenljivka je lokalna    print(pozdrav)print(pozdrav) # Vrne napako# Primer upoerabe spremenljivke z statusom nonlocaldef pozdravi_z_imenom():    pozdrav = 'Dober dan'    def ime():        nonlocal ime         ime = 'Marija'        print(ime)    print('{}, {}'.format(pozdrav, ime))

Funkcije locals() in globals() vrnejo dict kjer so ključi imena lokalnih in globalnih spremenljivk v trenutnem dosegu.

Niz ali string

V računalniškem svetu je string ali niz zaporedje črk ali znakov v obliki spremenljivke ali izhodne sekvence. V Pythonu je niz spremenljiv bodisi v velikosti ali v vsebini. Definiran je kot matrica bytov, ki shranijo posamezen sekvenčni del oziroma črko glede na črkovno notacijo. V sebi lahko v obliki niza nosi tudi druge podatkovne tipe, npr. cela števila ali nize podatkov.

Konkatinacija niza[27]

Konkatinacija niza se uporablja, kadar moramo združiti več manjših nizov (string) objektov v končni izpis. Pri tem se uporablja operator +. Če hočemo konkatinirati druge podatkovne tipe jih moramo najprej prevesti v niz (string). V Pythonu je konkatinacija niza izvedena ob času izvedbe programa in njeni rezultati niso znani vnaprej. V primeru absolutnega niza z izhodnimi sekvencami pa je rezultat konkatinacije niza znan že ob izgradnji programa v Pythonovem predpomnilniku. Velja tudi izjema pri več-vrstičnih nizih. Ti so označeni z """ """ ali z ''' '''. Pri tem je upoštevana struktura niza z vsemi prelomi vrstic. Ta odlika je velikokrat uporabljena pri večvrstičnih komentarjih in dokumentaciji funkcij.

x = "Pozdravljen"y = "svet"print(x + " " + y)# izpis konzole:   #   Pozdravljen svet# primer prevoda podatkovnega tipajeŽalosten = FalsekolikoLet = 100000jeŽalosten = str(jeŽalosten)kolikoLet = str(kolikoLet)print("Ali si žalosten: " + jeŽalosten)print("Koliko let imaš: " + kolikoLet)# izpis konzole:#   Ali si žalosten: False#   Koliko let imaš: 100000#Primer večvrstičnega nizaprint("""Rad imamPython 3.8.""")#izpis konzole:#   Rad imam#   Python3.8

Za dva niza S1 in S2 je konkatinacija niza S1S2 sestavljena iz nizov v obliki ab, kjer je a del niza S1, w pa je del niza S2. To lahko izrazimo z . Velikokrat pa se znajdemo v primeru konkatinacije niza in samostojnega znaka. To pa lahko izrazimo z in .

Osnovno formatiranje niza[28]

Preprosto formatiranje niza je verjetno največkrat uporabljena oblika formatiranja in/ali konkatinacije niza. Uporabljamo ga v primeru enakega vrstnega reda parametrov v relativno majhnem obsegu združenih elementov. Zaradi dveh generacij Pythona (2 in 3), se je tudi način formatiranja spremenil. Tako poznamo stari in novi slog. Stari deluje tudi v 3. generaciji Pythona, novi pa ne deluje obratno. V novem slogu formatiranja Python kliče __format__() metodo, ki je implementacija že vgrajene funkcije format() v razredu object.

Formatiranje pa ne omogoča samo konkatinacije, ampak tudi poravnavo 2 nizov. Po privzetih parametrih formatiranje 2 nizov zavzame samo toliko prostora, kot ga potrebuje. V starem načinu je zamik desnosučni, v novem pa levosučni. Mogoča je uporaba vseh primitivnih podatkovnih tipov, pri številih z decimalno vejico pa jim moramo podati tudi število mest za vejico.

x = 5y = "Jure"k = "Nina"e = 2+3j# prvi primer (novejši način)print(y + " je vesel, saj je dobil oceno {}".format(x))# ali pa uporabimo znak % (starejši način)print(y + " je vesel, saj je dobil oceno %d"%x)# V tem primeru funkcija 'format' spremeni vrednost vseh y, k, e vrednosti v niz. Vpiše jih v glavni niz objekt po vrsti z začetkom od 0 do 2print("{0} in {1} sta skupaj rešila enačbo {2}".format(y, k, e))# Tukaj je posebna vrsta niza, ki omogoča formatiranje niza med dejanskim nizom. Gre za novejši način.print(f"{y} + {k} = {x} + {e}")#Zamikanje besede z uporabo format funkcije, novejši način.print('{:>10}'.format('test'))

Matematični operatorji

Matematični operatorji v Pythonu so posebni rezervirani simboli, ki izvedejo aritmetične ali logične operacije. Operatorji delujejo na operande. Operatorji se v Pythonu delijo na unarne in binarne. Poznamo aritmetične, logične, bitne in primerjalne operatorje. Python v izrazih sledi uporabi oklepajev in precedenci vseh operatorjev.

Izračun se izvaja v času izvajanja programa (čeprav to ni nujno, določene stvari se lahko izračunajo pred izvajanjem zaradi konstantne narave), medtem ko se spremenljivke zapišejo že med izgradnjo programa. Med tekom kode procesor najprej izvede (), nato sledijo klici funkcij (f(args)), sledi procesiranje kolektivnih spremenljivk (x[indeks:indeks] in x[index]). Program nato omogoči dostop atributom spremenljivke (x.attribute). Izvede se potenciranje, sledijo aritmetični operatorji z negacijo na čelu. Kot zadnji pridejo na vrstno bitni operatorji z primerjalnimi op. ter logični op. na koncu.

# Osnovne operacijex + y  # seštevanjex - y  # odštevanje x * y  # množenjex / y  # deljenje (zaokroženo na decimalno vrednost)x // y # deljenjex ** y # potenciranje (produkt x-ov y-krat)x % y  # modulo (ostanek pri deljenju)# Primerjalni operatorjix == y # primerjavax > y # je večje x < y # je manjšex >= y # je večje ali je enakox <= y # je manjše ali je enakox != y # ni enako# Logični operatorjix = Truey = Falsex and y # konjunkcijax or y # disjunkcijanot y # negacija# Bitni operatorjix & y # bitni ANDx | y # bitni OR ~ x # bitna negacijax ^ y # bitni XORx >> 2 # bitni desni premikx << 2 # bitni levi premik# Vse račune lahko shranjujemo v spremenljivkea = 2 + 5 # shrani rezultat računa v spremenljivko aprint(x) # izpiše vrednost aprint(3 + 7 * 2) # Izpiše 17, ker ima množenje prednostprint((5 - 7) * 4) # Izpiše -8, ker ima operacija v oklepaju prednost

.

Razlika med standardnimi in hitrimi operatorji[29]

Metoda __add__ (funkcija baznega razreda object) je zadolžena za izvedbo navadnega seštevanja. To pomeni da se a + b zapiše v spremenljivko c brez spremembe argumentov seštevancev. Hitra metoda __iadd__ je ravno tako zadolžena za izvedbo seštevanja, a se rezultat namesto v drugo spremenljivko zapiše v spremenljivko a (a = a + b). Hitri operatorji so naslednji:

#Hitre operacije namenjene dodelitvi vrednosti izraza v konjunkciji z drugo spremenljivkox += y # dodelitev seštevka (ekvivalent x = x + y)x -= y # dodelitev odštevka (ekvivalent x = x - y)x *= y # dodelitev zmnožka (ekvivalent x = x * y)x /= y # dodelitev količnika zaokroženega na najbližjo celoštevilsko vrednost (ekvivalent x = x / y)x //= y # dodelitev količnika (ekvivalent x = x // y)x **= y # dodelitev produkta x-ov y-krat (ekvivalent x = x ** y)x %= y # dodelitev ostanka pri deljenju (ekvivalent x = x % y)x <<= y # ekvivalent x = x << yx >>= y # ekvivalent x = x >> yx &= y # ekvivalent x = x & yx |= y # ekvivalent x = x | yx ^= y # ekvivalent x = x ^ y

Definiranje operatorjev znotraj objektov[30]

Definiranje operatorjev znotraj objektov pomeni dodajanje nove funkcionalnosti operatorju. Operator + lahko sešteje oz. konkatinira spremenljivke tipa string in int ali int in float itd. To je definirano v tako baznem razredu string kot v baznem razredu string . V Pythonu lahko znova definiramo vse operatorje, ne moremo pa ustvariti novih. Operatorji so definirani kot posebne funkcije baznega razreda Builtin, najdemo jih pod imenom __<ime operatorja>__.

class A:    def __init__(self, parameter):        self.parameter = parameter        #Definiramo "drugačno" ozadje funkcije __add__    def __add__(self, other):        return self.parameter + other.parameterobj1 = A('Janezek')obj2 = A('Micka')print(obj1 + obj2)#Konzola izpiše JanezekMicka

Kolektivni podatkovni tipi

Python pozna kar nekaj tipov spremenljivke, s katerimi lahko interpretiramo oz. integriramo množice. To so list, tuple, set in frozenset. Vsaka je malo drugačna, toda vse 4 lahko razdelimo v 2 skupini. Razdelimo jih glede na status uredbe spremenljivke. Spremenljivka je lahko spremenljiva, to sta list in set. Nasprotno je lahko kolektivni tip nespremenljiv, to sta tuple in frozenset. Nespremenljiv pomeni, da množici vrednosti programsko ne moremo dodati ene ali več vrednosti. Vrednosti znotraj množice ponavadi vsebujejo več tipov spremenljivk, z dodajanjem metaclass pa jih lahko naredimo homogene.

Vsi kolektivni tipi, razen dict, vsebujejo samo enojne vrednosti, medtem ko dict vsebuje pare ključ: vrednost kot urejeni par. Pri teh parih so lahko spremenljivke različnih tipov, ni pa nujno. Če je prva komponenta dict ključa a, druga pa b, lahko to izrazimo z . Število elementov v vseh kolektivnih tipih je omejeno in temelji na operacijskem sistemu. Če je sistem 32-bitni, je maksimum , v 64-bitnem pa .

Spremenljivke v kolektivnih tipih niso prave instance njihovih baznih objektov, ampak so to referenčne točke, ki vodijo do njihovega izvora[31]. Zato je velikost množice odvisna od števila elementov in ne od velikosti objektov. Čas iteracije skozi celoten seznam je ne glede na dolžino enak , čas dodajanja pa je konstanta.

znamke = ["Ferrari", "BMW", "Honda", "Alfa"] # to je list z 4 vrednostmi enakega tipa podatkovvse = (0, "Vito", 44, True, None, "Živjo", 2.44) # to je tuple, ki lahko vsebuje katerikoli tip podatkatabela_ocen = {"Miha":4, "Jure":2, "Jaz":5, "Nekdo":1, "Maja":4, "Nina":3} # to je dict vsebuje key and value. Key so v tem primeru imena, vsako ima svojo oceno torej value. Torej tuple ima key=string in value=intiger podatke."""# vse podatke lahko izpišemo s print funkcijoprint(znamke)print(vse)print(tabela_ocen)print(type(znamke))print(type(vse))print(type(tabela_ocen))# izpis konzole#['Ferrari', 'BMW', 'Honda', 'Alfa']#(0, 'Vito', 44, True, None, 'Živjo', 2.44)#{'Miha':4, 'Jure':2, 'Jaz':5, 'Nekdo':1, 'Maja':4, 'Nina':3}#<type 'list'>#<type 'tuple'>#<type 'dict'>

Urejanje kolektivnih podatkovnih tipov

Časovna kompleksnost dodajanja elementov[32] k listi je ublaženi . Če imamo list A z močjo in ji hočemo dodati 50 elementov, se zgodi naslednje:

Prvih 8 elementov je potisnjenih v , 9. sproži relokacijo in odpre ostalim 8 dostop v . V 17. iteraciji se sproži relokacija 16 prejšnjih členov in 15 novih členov pride v . 33. ponovitev zanke sproži novo relokacijo 32 prejšnjih členov in v pride 17 novih. Po vseh relokacijah imamo časovno kompleksnost , v kateri je 56 kopij in 3 realokacije v , za . Če upoštevamo, da je to geometrijska serija je to asimptotično enako za n = končna velikost seznama. To pomeni, da je celotna operacija potiskanja n predmetov na seznam . Če to amortiziramo na element, je . Če je seznam dolg, pa se lahko časovna kompleksnost poveča tudi na .

x = ["A", "B", "C", "D"]print(x[2])# konzola izpiše C saj se list začne šteti z 0# da dodamo vrednost listu uporabimo metodo appendx.append("E") # to doda x listu na konec vrednost "E"# da odstranimo vrednost listu uporabimo metodo popx.pop(1) # izbriše drugo vrednost na listu v tem primeru "B"print(x)# konzola izpiše ['A', 'C', 'D', 'E']# če nevemo katero število pripada določeni vrednosti na listu uporabimo metodo countšt_a = x.count("A")print(št_a) # izpiše 0 saj je a na prvem mestu.# Kolektivne podatkovne tipe je mogoče tudi gnezditi.j = [    [1, 2, 3],    [4, 5, 6],    [7, 8, 9]]# Spremenljivka je list listov torej če uporabimo enonivojsko klicanje podatkov preko [] operatorjaprint(j[0]) # Izpiše [1, 2, 3]# Do dostopamo do notranje vsebine recimo števila 5print(j[1][1]) # Izpiše 5

Za vsak kolektivni podatek obstaja vsaj 5 metod.

Vnos

Vnos se izraža z 2 built-in keyword-oma input in raw_input. Če uporabimo raw_input potem se vsak naš vnos šteje kot niz, če pa uporabljamo input moramo pred njega vstaviti tip podatka katerega hočemo pridobiti na primer: int(input("Vnesi število: ")), za vnos števila. raw_input ni več v uporabi od Python verzije 3.6.x

# primer raw_input keywordax = raw_input("Vnesi svoje ime: ")print("Pozdravljen " + x + "!")print("Dolžina tvojega imena je {}".format(len(x)))  # len() keyword se uporablja pri ugotavljanju dolžine določene besede# primer input keyworday = input("Vnesi svoje ime: ") # Ekvivalent starejši raw_inputk = int(input("Vnesi svojo starost: "))print("Tvoje ime je " + y)print("Star si {}".format(k)) # intiger tipe vedno formatiramo saj se jih ne more konkatinirati s string, razen v primeru prevoda podatkovnega tipa.

Pogojni stavki

Pogojni stavki se uporabljajo predvsem za zastavljanje pogojev skozi katere mora neka vrednost priti, da se nekaj izvaja. Izraža se jih s ključnimi besedami if, elif, else in match (dodan v verziji 3.10).

# primer if-elif-else stavkabarva = input("Vnesi svojo najljubšo barvo: ")if barva == "rdeča" or barva == "modra":   print("Zelo lepo")elif barva == "zelena" or barva == "rumena":   print("Lepo")elif barva == "črna" or barva == "bela" or barva == "roza":   print("Ne najbolje")elif barva == "rjava" or barva == "oranžna" or barva == "lila":   print("Slaba izbira")else:   print("Ne poznam te barve")# primer if-else stavkas = int(input("Prosim vnesi svojo starost: "))if s < 18:   print("Dostop ni dovoljen.")else:   print("Dobrodošli")# matematični primer if 9 + 1 == 10:   print("Pravilno")elif 9 + 1 != 10:   print("Narobe")
# primer nested stavkac = input("Vnesi črko: ")k = int(input("Vnesi številko: "))if c in ['A','B','C','D','E','F']:   if k > 50:      print("Uspešno")   elif k <= 40:      print("Skoraj uspešno")   else:      print("Ni uspešno")elif c in ['K','L','M','N','O']:   print("Bravo zmagal si")elif len(c) < 1 and len(c) > 1:   print("Moraš vpisati samo eno črko")else:   print("Napaka")
# primer walrus operatorja v if-uif c := input("Vnesi niz: "): # if se izvrsi samo v primeru če je bool(c) == True   if c.startswith("A"):      print(f"Vnesel/vnesla si niz, ki se začne z A: {c}")# to zgoraj je samo krajša oblika za naslednjec = input("Vnesi niz: ")if c and c.startswith("A"):    print(f"Vnesel/vnesla si niz, ki se začne z A: {c}")
# primer match stavkac = "Žaba"def zvok():    match c:       case "Žaba": return "Reganje"       case "Pes": return "Lajanje"       default: return "Neznano"zvok() # vrne "Reganje"

Zanke

Zanke so ukazi, s katerimi lahko večkrat izvedemo nek del kode. V Pythonu poznamo 2 tipa zank: for in while.Zanka for ponovi nek del kode za vsakega člana nekega iterativnega podatkovnega tipa, s stavkom while pa izvajamo kodo, dokler nek pogoj velja.

# primer for zankepozdravi = ['Živjo', 'Zdravo', 'Pozdravljeni']for x in pozdravi:    print(x)# ali pafor i, x in enumerate(pozdravi):    print(i, x) # Vrednost i in x sta razpakirana iz enumerate(pozdravi).# izpis konzole ŽivjoZdravoPozdravljeni0, Živjo1, Zdravo2, Pozdravljeni# primer while zankep = "12345"while True:   r = input("Vnesi geslo: ")   if r != p:      print("Napačno Geslo")   elif r == p:      print("Dobrodošli")# izpis konzoleVnesi geslo: 54321Napačno GesloVnesi geslo: 12345Dobrodošli

Moduli

Vsaka Python datoteka predstavlja natanko en modul. Modul lahko vpeljemo v drug modul s stavkom import oz. s stavkom from import. Vsi vnešeni konstrukti (paketi, moduli, funkcije, itd.) so lahko poimenovani drugače za modul v katerega vnašamo z besedo as.

pozdravi.py

def reči_živjo(ime):    print(f"Živjo {ime}")

glavni.py

import pozdravi as px = "Anastazija", "Špela", "Marija"for w in x:    p.reči_živjo(w)# izpis konzoleŽivjo AnastazijaŽivjo ŠpelaŽivjo Marija

Vsi stavki import vnašajo relativno na lokacijo trenutnega modula v datotečnem sistemu. Vnašamo lahko zato tudi npr. from ..A import b as c vnese modul A, ki se nahaja v starševskem direktoriju glede na trenutni modul v katerem smo to napisali.

Paketi

Paket (angl. package) je skupek modulov v nekem direktoriju. Minimalni Python paket ustvarimo če imamo v nekem direktoriju datoteko __init__.py. V ta direktorij nato lahko dodajamo razne module. Pakete se lahko tako kot module vnaša z import stavkom. Ko vnesemo paket se avtomatično izvrši __init__.py.

Funkcije

Funkcija je del kode, ki se izvede, ko jo kličemo. Z uporabo funkcij se izognemo večkratnemu ponavljanju iste kode, hkrati pa izboljšamo njeno berljivost.V funkcijo lahko podamo vhodne podatke, imenovane parametri ali argumenti, s katerimi funkcija lahko operira. Pogosto nam funkcija tudi vrne podatke. Funkcije lahko gnezdimo. Funkcije lahko podajamo kot parametere, saj so konec koncev samo kazalci na različne lokacije pomnilnika ter tako z njimi formiramo sintaktični sladkor, funkcijske dekoratorje (poznamo namreč tudi razredne dekoratorje). Anonimne funkcije se imenujejo lambde. Definiramo jih z besedo def (izjema so neimenovane funkcije lambda), ki ji sledi ime, nato pa seznam arguentov in dvopičje. V naslednjih vrsticah napišemo vsebino funkcije, zamaknjeno za 1 odmik.

# primer gnezdene funkcijedef a():    def b():       print(42)    b()    print(88)a() // izpise: 42 in v novi vrstici 88b() // napaka: ta funkcija je definirana v resoluciji a()-ja ne v globalni resoluciji# primer funkcije podane kot parameterdef a(fn):    print("kličem fn()")    fn()def b():    print("v b()")a(b) # izpise "kličem fn()" nato pa še "v b()" v novi vrstici# zgornje se lahko zapiše s funkcijskim dekoratorjem sledeče, vendar je bolj pogosto, da def a(fn):    def wrapper():        print("kličem fn()")        fn()    wrapper()@adef b():    print("v b()")b() # izpiše "kličem fn()" nato "v b()" v novi vrstici@adef c():    print("v c()")c() # izpiše "kličem fn()" nato "v c()" v novi vrstici
def seštej(x, y):    print("Rezultat = {}".format(x + y))seštej(2, 4) # klic funkctije # izpis6# Funkcija Seštej je ubistvu tako miniaturna, da jo lahko zapišemo kot lambdoseštej = lambda x, y: x + yprint(seštej(2, 4)) # Izpiše 6
# primer funkcije brez parametrovdef zahtevaj_vpis():    uporabniško_ime = input("Vnesi uporabniško ime: ")    geslo = input("Vnesi geslo: ")    if len(geslo) < 6:       print("Geslo more vsebovati več kot 6 znakov")    else:       print("Dobrodošel uporabnik {}".format(uporabniško_ime))# primer funkcije s poimenovanimi parametri# če drugi argument ni podan, se upošteva y=1def inkrement(x, y=1):    return x+y# primer funkcije s pozicijskimi parametridef odštej(a, b):    return a-bštevilo = 3rezultat = inkrement(3)print("3 + 1 = " + str(rezultat))print("5 - 7 = " + str(odštej(5, 7)))# izpis konzole 3 + 1 = 45 - 7 = -2

Funkcijo lahko pokličemo tudi v drugi funkciji saj so vse funkcije globalne. Z izjemo metod definiranih v UDR.

def pozdravi(ime):    print("Živjo "+ime)def vprašanje():    i = raw_input("Vnesi ime: ")    pozdravi(i)     vprašanje()# izpis konzole Vnesi ime: NekdoŽivjo Nekdo

Podatkovni tip parametrov je lahko namignjen z ti. angl. type hinting-om vendar to *ne* zagotovi deklariranega tipa (oz. statičnega tipkanja) in je samo v pomoč IDE okoljem pri indeksiranju knjižnice.

def odštej(a:int, b:int):    print("{}".format(a + b))def prepoznaj_tip(t:(list, dict))   if type(t) is type(list):      print("Tip je list")   elif type(t) is type(dict):      print("Tip je dict")   else:      print("Tip ni prepoznan")

Primeri Funkcij

import timedef štej(od, do, zamik=0.5):    while od < do:          od = od + 1 # ali pa z uporabo hitrega operatorja od += 1          print(od)          time.sleep(zamik) # ustavi izvajanje za zamik sekunddef vnos():    ime = input("Vnesi ime: ")    priimek = input("Vnesi priimek: ")    print(f"Pozdravljen {ime} {priimek}")# tukaj se uporablja ti. nested funkcije pri kateri je lahko funkcija v funkcijidef kalkulator():    def seštej(x, y):        return x + y    def odštej(x, y):        return x - y    def množi(x, y):        return x * y    def deli(x, y):        return x / y    def potenciraj(x, y):        return x ** y    def moduliraj(x, y):        return x % y        print("Izberi možnost")    print("Seštevanje = 1")    print("Odštevanje = 2")    print("Množenje = 3")    print("Deljenje = 4")    print("Potenciranje = 5")    print("Moduliranje = 6")    o = str(input("Izbira: "))    p = int(input("Prvi: ")    d = int(input("Drugi: ")    if o == "1":       seštej(p, d)    elif o == "2":       odštej(p, d)    elif o == "3":       množi(p, d)    elif o == "4":       deli(p, d)    elif o == "5":       potenciraj(p, d)    elif o == "6":       moduliraj(p, d)    else:       print("Neznana operacija.")kalkulator()# izpis konzoleIzberi možnostSeštevanje = 1Odštevanje = 2Množenje = 3Deljenje = 4Potenciranje = 5Moduliranje = 6Izbira: 2  # jaz napisal 2Prvi: 10Drugi: 4# izpis funkcije6

Konteksti

Konteksti so deli kode, v katerih se določene surovine inicializirajo in deinicializirajo avtomatično. Kontekste se definira z ti. contextlib standardno knjižnico. Najlažje je demonstrirati koncept na primeru branja iz datoteke.

# Primer brez branja datoteke kontekstafp = open("datoteka.txt", "rt")vsebina = fp.read()print(vsebina)fp.close()

Medtem ko se z kontekstom lahko s pomočjo with ključne besede zapiše:

with open("datoteka.txt", "rt") as fp:    vsebina = fp.read()    print(vsebina)# fp.close() ni potreben saj bo kontekstni upravljavec sam zaprl datoteko.

Kontekste je možno tudi gnezditi ali pa jih inicializirati več na istem nivoju.

Dekoratorji

Funkcije ter razrede lahko dekoriramo z dekoratorjem tik nad definicijo funkcije oz. razreda z @ime_dekoratorja.

Iteratorji

Vsak kolektivni podatkovni tip lahko spremenimo v iterator z vgrajeno funkcijo iter(). Ko dobimo iterator lahko nanj nato kličemo funkcijo next(), ki vrne nasledni element iz iteratorja. Primer:

ime = "Anastazija"ime_iterator = iter(ime)assert next(ime_iterator) == "A" # propade če prva črka ni A.

Generatorji

Generatorji so funkcije, ki lahko začasno prekinejo delovanje nato pa nadaljujejo. Delovanje se prekine z rezervirano besedo yield. Poleg začasne prekinitve imajo generatorji še popolno prekinitev normalno z besedo return. Primer:

def naravna_stevila():    num = 0    while True:        yield num        num += 1

Vsak klic zgornje generatorske funkcije vrne število za 1 večje od prejšnjega.Možno je konstruirati generator generatorjev itd. veliko uporabnih funkcij najdemo v standardni knjižnici itertools ter še bolj napredne funkcije v nestandardni knjižnici more_itertools.

Razredi

Razredi lahko vsebujejo funkcije. Funkcije v razredu se imenujejo metode. Razrede se inicializira tako da dobimo novo instanco z __init__ predefinirano build-in funkcijo. Pod to globalno predifinicijo spadajo tudi __delattr__, __format__, __getattribute__, __hash__, __long__, __native__, __new__, __call__, __repr__, __nonzero__, __sizeof__, __setattr__, __unicode__, __str__ in drugi. Vsaka definicija od naštetih zgoraj ima svoj pomen.

# glavni razredclass A:    def __init__(self): # klic konstruktorja        print("Inicializeran razred A")# podrazredclass Z(A):    def __init__(self):        super(Z, self).__init__(A)  # klic superkonstruktorjaclass U(Z, A):    def __init__(self, m1, m2):        super(Z, U, A, self).__init__(m1, m2)  # klic superkonstruktorja s parametri# primer nelogičnega oziroma nepravilnega razredaclass B:    def __init__(self):        pass# novo definirane globalne spremenljivke v razedu BB.ime = "Tone"B.priimek = "Altgr"r = B.ime # objekte in njihove člane lahko shranjujemo v spremenljivkeprint(r)        # primer razreda za osebeclass Oseba:    def __init__(self, ime:str, priimek:str, starost:int, email:str):        self.ime = ime # če damo pred objek parameter self lahko dostopamo do njegovih atributov        self.priimek = priimek        self.starost = starost        self.email = email        podatki = [[], []] # multidimenzionali list        podatki[0].append(ime)        podatki[0].append(priimek)        podatki[1].append(starost)        podatki[1].append(email)    def zahtevaj_podatke(self): # funkcija za klic izpisa podatkov na formatni način        print("Ime: {}".format(self.ime))        print("Priimek: {}".format(self.priimek))        print("Starost: {}".format(self.starost))        print("Email: {}".format(self.email)    def zahtevaj_dimenzije(self):        print(podatki)Jaz = Oseba("Null", "PError", 15, "abc.PError@unknown.abc") # Jaz postane Object Oseba z določenimi člani npr. ime. ter metodami za interpretacijo objekta ali postaktivnost tega objekta oziroma njegovih članov.Jaz.zahtevaj_podatke()# izpis konzole Ime: NullPriimek: PErrorStarost: 15Email: abc.PError@unknow.abc# ali print(Jaz.ime) # . pomeni član nekega kolektiva v razredu.print(Jaz.priimek)print(Jaz.starost)print(Jaz.email)

Referenčna izvedba

CPython je referenčna izvedba Pythona. Napisano je v jeziku C, ki ustreza standardu C89 z več izbranimi funkcijami C99 (s poznejšimi različicami C se šteje za zastarele;[33] CPython vključuje lastne razširitve C, vendar razširitve drugih proizvajalcev niso omejene na starejše različice C, lahko jih npr. Implementiramo s C11 ali C++). Program Python prevede v vmesno bajtno kodo, ki jo nato izvede navidezni stroj.[34]

CPython je razdeljen z veliko standardno knjižnico, napisano v mešanici C in domačega Pythona. Na voljo je za številne platforme, vključno z operacijskim sistemom Windows (začenši s Python 3.9, namestitveni program Python se namenoma ne namesti v operacijski sistem Windows 7 in 8; Windows XP je bil podprt do Python 3.5) in v večini sodobnih sistemov, podobnih Unixu, vključno z macOS (in Apple M1 Mac, od Pythona 3.9.1, z eksperimentalnim namestitvenim programom) in neuradno podporo za npr VMS.[35] Prenosljivost platforme je bila ena njegovih prvih prioritet, v časovnem okviru Python 1 in 2 sta bila podprta celo OS/2 in Solaris; podpora je od takrat opuščena za številne platforme.[36]

Generatorji dokumentacije API

Orodja, ki lahko ustvarijo dokumentacijo za Python API, so med drugim pydoc (na voljo kot del standardne knjižnice), Sphinx, Pdoc in njegove vilice, Doxygen in Graphviz.[37]

Zunanje povezave

Sklici

  • 2,0 2,1 Python 3.12.3 and 3.13.0a6 released — 2024.
  • https://impythonist.wordpress.com/2014/02/16/open-heart-with-guido-van-rosuuma-lost-interview-of-python-creator-part2/
  • Why was Python created in the first place?Python Software Foundation.
  • 5,0 5,1 Classes The Python TutorialPython Software Foundation.
  • An Introduction to Python for UNIX/C Programmers
  • Functional Programming HOWTO
  • Download Python
  • https://api.github.com/repos/python/cpython
  • »The Python Standard Library — Python 3.8.5 documentation«. docs.python.org. Pridobljeno 22. avgusta 2020.
  • »Unix Specific Services — Python 3.8.5 documentation«. docs.python.org. Pridobljeno 22. avgusta 2020.
  • »winsound — Sound-playing interface for Windows — Python 3.8.5 documentation«. docs.python.org. Pridobljeno 22. avgusta 2020.
  • »math — Mathematical functions — Python 3.9.0 documentation«. docs.python.org. Pridobljeno 1. novembra 2020.
  • 14,0 14,1 »sys — System-specific parameters and functions — Python 3.9.0 documentation«. docs.python.org. Pridobljeno 1. novembra 2020.
  • »os — Miscellaneous operating system interfaces — Python 3.9.0 documentation«. docs.python.org. Pridobljeno 1. novembra 2020.
  • »random — Generate pseudo-random numbers — Python 3.8.6 documentation«. docs.python.org. Pridobljeno 1. novembra 2020.
  • »datetime — Basic date and time types — Python 3.8.6 documentation«. docs.python.org. Pridobljeno 1. novembra 2020.
  • »tkinter — Python interface to Tcl/Tk — Python 3.8.6 documentation«. docs.python.org. Pridobljeno 1. novembra 2020.
  • »os — Miscellaneous operating system interfaces — Python 3.9.0 documentation«. docs.python.org. Pridobljeno 1. novembra 2020.
  • »php - Best practice multi language website«. Stack Overflow. Pridobljeno 22. avgusta 2020.
  • »How does NASA use Python? - Quora«. www.quora.com. Pridobljeno 21. avgusta 2020.
  • »How is Python being used at Facebook? - Quora«. www.quora.com. Pridobljeno 21. avgusta 2020.
  • »Developer's Guide: Python | YouTube«. Google Developers (v angleščini). Pridobljeno 21. avgusta 2020.
  • »The Incredible Growth of Python | Stack Overflow«. Stack Overflow Blog (v ameriški angleščini). 6. september 2017. Pridobljeno 22. avgusta 2020.
  • »Python print()«. www.programiz.com. Pridobljeno 30. avgusta 2020.
  • »7. Simple statements — Python 3.9.0 documentation«. docs.python.org. Pridobljeno 5. novembra 2020.
  • »Concatenation« (v angleščini). 7. oktober 2020. {{navedi revijo}}: Sklic magazine potrebuje|magazine= (pomoč)
  • »PyFormat: Using % and .format() for great good!«. pyformat.info. Pridobljeno 1. novembra 2020.
  • »Inplace vs Standard Operators in Python«. GeeksforGeeks (v ameriški angleščini). 10. januar 2017. Pridobljeno 6. novembra 2020.
  • »Operator Overloading in Python«. GeeksforGeeks (v ameriški angleščini). 10. december 2018. Pridobljeno 6. novembra 2020.
  • »An Introduction to Python Lists«. effbot.org. Arhivirano iz prvotnega spletišča dne 6. novembra 2020. Pridobljeno 6. novembra 2020.
  • »Why is the time complexity of python's list.append() method O(1)?«. Stack Overflow. Pridobljeno 6. novembra 2020.
  • »Mailman 3 Why aren't we allowing the use of C11? - Python-Dev - python.org«. mail.python.org (v angleščini). Arhivirano iz spletišča dne 14. aprila 2021. Pridobljeno 1. marca 2021.
  • Andreas C. Müller, Sarah Guido (2016). Introduction to Machine Learning with Python. O'Reilly Media. ISBN 9781449369415. Arhivirano iz prvotnega spletišča dne 6. septembra 2021. Pridobljeno 27. septembra 2021.
  • »history [vmspython]«. www.vmspython.org. Arhivirano iz spletišča dne 2. decembra 2020. Pridobljeno 4. decembra 2020.
  • »Download Python for Other Platforms«. Python.org (v angleščini). Arhivirano iz spletišča dne 27. novembra 2020. Pridobljeno 4. decembra 2020.
  • »Documentation Tools«. Python.org (v angleščini). Arhivirano iz spletišča dne 11. novembra 2020. Pridobljeno 22. marca 2021.
  • 🔥 Top keywords: Glavna stranPosebno:IskanjeFacebookSkrito v rajuPosebno:ZadnjeSpremembeNogometna Liga prvakovSlovenijaSeznam nemških igralcevZodiakMarija AntoanetaKategorija:Slovenski priimkiLjubljanaCarles PuigdemontFreelancerstvoNova24TVSeznam držav članic Evropske unijeYouTubeSeznam mednarodnih klicnih kodReal Madrid Club de FútbolDruga svetovna vojnaSeznam slovenskih slikarjevFrance PrešerenSeznam nemških filozofovDubajSabina KogovšekVolitve poslancev iz Slovenije v Evropski parlament 2024Meta PlatformsNogometRimsko cesarstvoSeznam škotskih fizikovSulejman I.MariborIranMatej ZemljičRadiotelevizija SlovenijaIranske pokrajineHrvaška demokratska skupnostWindows NT 4.0Izrael