Fail¶
Failihaldus¶
Fail on nimega viide salvestatud andmetele. Failid võimaldavad andmete taaskasutust.
Failide haldus programmeerimiskeeles hõlmab järgmisi tegevusi:
- Faili avamine;
- Andmete (sõne) kirjutamine faili;
- Andmete (sõne) lugemine failist;
- Faili sulgemine.
Tekstifail ja binaarne fail¶
Kõik arvutis salvestatud failid sisaldavad andmeid binaarsel kujul $-$ on binaarsed failid. Fundametaalsel tasemel eristatakse kõigest kahte tüüpi failile. Pythonis ja mujal eristame binaarseid- ja tekstifaile. Kusjuures tekstifail on binaarne fail mille sisu tõlgendatake kui teksti. Kõiki faile on võimalik jagade kas binaarseks või tekstifailiks. Lisainfo: https://fileinfo.com/help/binary_vs_text_files
Andmete esitus failis:
Binaarsed failid
- Andmed kirjutatakse faili nii nagu need on esitatud arvuti mälus.
- Andmed loetakse failist mällu otsese kopeerimisega, programmid võivad andmeid interpreteerida.
Tekstifailid
- Eeldatakse, et binaarsed andmed on tekstimärkide koodid.
- Andmete lugemisel tekstiredaktorid interpreteerivad andmeid tekstina (dekodeerimine ja kodeerimine).
Sõne esitus arvuti mälus¶
Sõne on muutmatu (immutable) objekt, mis esindab tähemärkide jada. Igal märgil on täisarvuline kood ja graafiline esitus (šrift, inglise k. font). Arvuti mälus on sõned esitatud koodide jadana. Kuvaril näidatakse sõnet kasutades selle tähemärkide graafilist esitust. Klaviatuuri nupule vajutus genereerib vastava märgi koodi. Pythoni sõned kasutavad vaikimisi nn. Unicode tähemärke (kodeeringuga UTF-8). Loe lisaks: https://docs.python.org/3/howto/unicode.html
Näiteks märgile a
vastav kood on 97
. Koodile 107
vastav märk on k
jne.
ord('a') # Funktsioon ord ehk ordinaal.
97
chr(97)
'a'
bin(97)
'0b1100001'
'0' + bin(97)[2:] # Tavaliselt 8 bitine.
'01100001'
chr(231) # UTF-8 toetab kõiki suuremaid tähemärkide rühmi.
'ç'
Sõne Juulius
esitus arvuti mälus:
fraas = 'Juulius'
binary = ''
for mark in fraas:
o = ord(mark) # 'a' --> 97
b = bin(o) # 97 --> '0b1100001'
b = b[2:] # '0b1100001' --> '1100001'
b = b.zfill(8) # '1100001' --> '01100001'
binary += b # Konkatenatsioon.
print(binary) # --> 01001010 01110101 01110101 01101100...
01001010011101010111010101101100011010010111010101110011
Joonis 1. (Vasak) Binaarne pildifail avatuna pildikuvamise tarkvaraga. (Parem) Binaarne pildifail vasakpoolselt jooniselt avatuna lihtsas tekstiredaktoris. |
Binaarseid faile ehk mitte-tekstifaile saab avada tekstiredaktoris, vt. Joonis 1. Joonisel 1 (Parem) näidatud tekstiredaktor tõlgendab pildifailis olevaid nulle ja ühtesid kui tähemärkide koode.
Failihaldus Pythonis¶
Failide avamiseks kasutame sisseehitatud funktsiooni open
. Faile saab avada erinevates režiimides (nimega argument mode
). Kui pole teisiti otsustatud siis Python eeldab, et andmed on tõlgenadatavad sõne andmetüübina nii andmete lugemisel kui ka kirjutamisel. Loeme sisseehitatud funktsiooni open
dokumentatsiooni:
#help(open) # Loe iseseisvalt.
Faili avamine kasutades sisseehitatud funktsiooni open
:
<muutuja> = open('<faili nimi>.<laiend>', 'r') # Režiim 'r' ehk read mode (vaikeväärtus).
Uue faili loomine:
<muutuja> = open('<faili nimi>.<laiend>', 'w') # Režiim 'w' ehk write mode.
Peale faili avamist ja sellega töötamist tuleb see alati sulgeda. Kasutame failiobjekti meetodit close
:
<muutuja>.close()
Faili sõne kirjutamiseks kasutame meetodit write
(NB! Kui fail eksisteerib ja selles on andmeid siis need kirjutatakse üle):
<muutuja>.write(<andmed>)
Failist lugemiseks (kogu sisu korraga, kõik baidid korraga) kasutame meetodit read
. Meetod read
itereerib üle failiobjekti mis on iteraator. Faili sisse lugemine ammendab iteraatori:
<muutuja>.read()
Loome faili ja kirjutame sellese sõne 'Juulius Tipikas on maskott.'
:
f = open('Juulius.txt', 'w') # Loob faili töökausta.
f.write('Juulius Tipikas on maskott.')
f.close() # Ära unusta.
f = open('Juulius.txt') # Vaikimisi režiim 'r'.
print(dir(f)) # Objekti meetodid ja atribuudid.
print()
print(type(f)) # Failiobjekt on iteraator.
print(iter(f)) # Failiobjekt on iseenda iteraator.
print(f.name) # Atribuut.
print('mode =', f.mode) # Atribuut.
print()
print(f.read()) # Loeme sisu ja prindime konsooli.
f.close() # Ära unusta.
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines'] <class '_io.TextIOWrapper'> <_io.TextIOWrapper name='Juulius.txt' mode='r' encoding='UTF-8'> Juulius.txt mode = r Juulius Tipikas on maskott.
Kontekstihaldur, konstruktsioon with/open/as
¶
Selleks, et mitte muretseda ega unustada failide sulgemist on loodud kontekstihaldur. Konstruktsiooni with/open/as
kasutamise süntaks:
with open('<faili nimi>.<laiend>', 'w') as <nimi>:
<nimi>.write('Faili sisu')
with open('<faili nimi>.<laiend>', 'r') as <nimi>:
sisu = <nimi>.read()
with
-blokist väljaspool on fail automaatselt suletud.
Loome faili ja lisame sellesse sõne 'Juulius Tipikas on maskott.\nTema õde on Juulia.'
. Mis tähendab et faili sisu saab olema kujul:
Juulius Tipikas on maskott.
Tema õde on Juulia.
with open('Juulius.txt', 'w') as f: # Proovi ka muid faili laiend näiteks .dat jne.
f.write('Juulius Tipikas on maskott.\nTema õde on Juulia.')
print(f.closed) # Suletud või mitte?
f.closed # Suletud või mitte?
False
True
Avame faili ja loeme selle sisu:
with open('Juulius.txt', 'r') as f:
sisu = f.read() # Kogu sisu korraga itereerides üle faili (kõik baidid korraga).
print(sisu)
Juulius Tipikas on maskott. Tema õde on Juulia.
Failiobjekti meetodid: writelines
, readlines
, readline
, seek
, tell
¶
Lisaks eelmainitud meetoditele write
ja read
on ka teisi. Allpool näitame valitud meetodite kasutamise näiteid.
Meetod writelines
kirjutab faili mitu sõnet korraga. Paiguta sõned iteratortoega objekti:
with open('Juulius.txt', 'w') as f: # Proovi ka muid faili laiend näiteks .dat jne.
f.writelines(['Juulius\n', 'Juulia'])
with open('Juulius.txt', 'r') as f:
sisu = f.read() # Kogu sisu korraga (kõik baidid korraga).
print(sisu)
Juulius Juulia
rows = ('Juulius Tipikas on maskott.\n', 'Tema õde on Juulia.') # NB! reavahetus.
with open('Juulius.txt', 'w') as f: # Proovi ka muid faili laiend näiteks .dat jne.
f.writelines(rows)
with open('Juulius.txt', 'r') as f:
sisu = f.read() # Kogu sisu korraga (kõik baidid korraga).
print(sisu)
Juulius Tipikas on maskott. Tema õde on Juulia.
Meetod readlines
loob loetud ridu sisaldava loendi itereerides üle failiobjekti (ammendab iteraatori):
with open('Juulius.txt', 'r') as f:
sisu = f.readlines() # Kõik teksti read listis sisu.
print(sisu)
print()
for rida in sisu: # Itereerin üle listis olevate ridade.
print(rida, end='') # Argument end, et ei tekiks tühja lisarida.
['Juulius Tipikas on maskott.\n', 'Tema õde on Juulia.'] Juulius Tipikas on maskott. Tema õde on Juulia.
Kuna loetud read on paigutatud listi saame kasutada listiga kaasasolevaid võimalusi:
with open('Juulius.txt', 'r') as f:
sisu = f.readlines()[1:] # Indekseerimine: Alates indeks = 1.
print(sisu)
print()
for rida in sisu: # Itereerin üle listi sisu.
print(rida)
['Tema õde on Juulia.'] Tema õde on Juulia.
Meetod readline
teostab ühe realugemise ehk iteratsiooni üle failiobjekti mis on iteraator:
with open('Juulius.txt', 'r') as f:
sisu = f.readline() # Fail f on iteraator, readline on analoogne iteraatori __next__ meetodiga.
print(sisu, end='')
sisu = f.readline() # Mäletab viimati loetud rida. Järgmine iteraat.
print(sisu)
Juulius Tipikas on maskott. Tema õde on Juulia.
Nagu eelpool mainitud on failiobjekt iteraator. Seda kinnitas ka eelmine näide. Kas me saame üle faili itereerida? Üle failiobjekti saab lugemise režiimis 'r'
itereerida:
with open('Juulius.txt', 'r') as f:
for rida in f: # Itereerime üle failiobjekti.
print(rida, end='') # Eemaldame esimese rea lõpus oleva reavahetuse.
Juulius Tipikas on maskott. Tema õde on Juulia.
Lisaks eelmainitule võtab meetod read
vastu argumendi mis tähistab baitide arvu milleni failisisu itereerida ehk lugeda (mitu baiti lugeda):
with open('Juulius.txt', 'r') as f:
sisu = f.read(7) # Mitu baiti loeme: 1 bait = 1 tähemärk.
print(sisu)
sisu = f.read(8) # Järgmised 8 baiti, mäletab viimati loetud baiti.
print(sisu)
Juulius Tipikas
Meetod tell
tagastab sinu asukoha avatud ja hetkel loetavas failis esitatuna baitides:
with open('Juulius.txt', 'r') as f:
sisu = f.read(7) # Mitmenda baidini loeb.
print(sisu)
print('Kus asun:', f.tell()) # Mitmes bait hetkel.
sisu = f.read(20) # Leme järgmised 20 baiti.
print(sisu)
print('Kus asun:', f.tell())
Juulius Kus asun: 7 Tipikas on maskott. Kus asun: 27
Meetod seek
lubab baitides esitatud asukohta muuta või määrata:
with open('Juulius.txt', 'r') as f:
sisu = f.read(7) # Loeb 7 baiti.
print(sisu)
f.seek(0) # Liigume faili algusesse.
sisu = f.read(15) # Loen algusest 15 baiti.
print(sisu)
print('Kus asun:', f.tell())
Juulius Juulius Tipikas Kus asun: 15
Näide: Kirjutan with
-blokis eelnevalt faili kirjutataud teksti üle:
with open('Juulius.txt', 'w') as f:
f.write('Juulius Tipikas on maskott.') # Algne tekst, loodud sisu.
f.seek(19) # Liigub baitidevoos siia.
f.write('eeskujulik kodanik\n') # Kirjutan üle alates bait 19.
for i in range(2):
f.write('Eeskujulik kodanik!\n') # Lisan veel teksti.
with open('Juulius.txt', 'r') as f:
sisu = f.read()
print(sisu)
Juulius Tipikas on eeskujulik kodanik Eeskujulik kodanik! Eeskujulik kodanik!
with open('Juulius.txt', 'r') as rf:
with open('Juulius_copy.txt', 'w') as wf:
for line in rf:
wf.write(line)
Binaarse pildifaili kopeerimine:
with open('Juulius.png', 'rb') as rf:
sisu = rf.read()
with open('Juulius_copy.png', 'wb') as wf:
wf.write(sisu)
with open('Juulius.png', 'rb') as rf:
with open('Juulius_copy.png', 'wb') as wf:
for line in rf:
wf.write(line)
Kui kopeeritav fail on arvuti operatiivmälu jaoks liiga suur. Kopeerime seda osade kaupa:
with open('Juulius.png', 'rb') as rf:
with open('Juulius_copy.png', 'wb') as wf:
jupp = rf.read(30) # 30ne baidi kaupa.
while len(jupp) > 0:
wf.write(jupp)
jupp = rf.read(30)
Lausend with
ja mitme faili avamine korraga¶
Lausend with
toetab mitme faili samaaegset avamist. Faili kopeerimiese näide:
with open('Juulius.png', 'rb') as rf, open('Juulius_copy.png', 'wb') as wf:
for line in rf:
wf.write(line)
Failile andmete lisamine meetoditega write
ja writelines
¶
Kas faili saab lisada andmeid meetodiga write
nii, et see ei kirjutaks üle olemasolevaid andmeid (ei looks uut failisisu). Kasutame faililugemise režiimi 'a'
(append):
with open('Juulius.txt', 'a') as f:
for _rida in range(2):
f.write(' Lisame uue rea.\n') # NB! Ära unusta reavahetust rea lõpus.
with open('Juulius.txt', 'a') as f:
for _rida in range(2):
f.write(' LISAME UUE REA.\n') # NB! Ära unusta reavahetust rea lõpus.
with open('Juulius.txt', 'r') as f:
sisu = f.read()
print(sisu)
Juulius Tipikas on eeskujulik kodanik Eeskujulik kodanik! Eeskujulik kodanik! Lisame uue rea. Lisame uue rea. LISAME UUE REA. LISAME UUE REA.
Sarnaselt töötab ka faili meetod writelines
:
lines = ['Python ', 'on ', 'madu.']
with open('Juulius.txt', 'a') as f:
f.writelines(lines)
with open('Juulius.txt', 'r') as f:
sisu = f.read()
print(sisu)
Juulius Tipikas on eeskujulik kodanik Eeskujulik kodanik! Eeskujulik kodanik! Lisame uue rea. Lisame uue rea. LISAME UUE REA. LISAME UUE REA. Python on madu.
Andmete serialiseerimine¶
Moodul pickle
¶
Moodul pickle
serialiseerib Pythoni objektid baitide jadaks (nullideks ja ühtedeks) ja tagasi.
- Igat Pythoni objekti saab serialiseerida ja salvestada kettale.
- Loodud baitide jada sisaldab kogu informatsiooni mis on vajalik teisel Pythoni moodulil objekti taastamiseks.
Kasutamise näide, objekti sealiseerimiseks kasutame meetodit dump
ja desearialireerimiseks meetodit load
:
import pickle
data = dict(a = 1, b = [1, 2])
f = open('Juulius.pkl', 'wb') # Kasuta .pkl faililaiendit.
pickle.dump(data, f)
f.close()
f = open('Juulius.pkl', 'rb')
print(pickle.load(f)) # --> {'a':1, 'b':[1, 2]}
f.close()
{'a': 1, 'b': [1, 2]}
Kasutus koos kontekstihalduriga ehk with
-blokis:
import pickle
data = dict(a = 1, b = [1, 2, 3])
with open('Juulius.pkl', 'wb') as f:
pickle.dump(data, f)
with open('Juulius.pkl', 'rb') as f:
print(pickle.load(f))
{'a': 1, 'b': [1, 2, 3]}
Joonis 2. Meem moodulile pickle . |
Moodule shelve
¶
Moodul shelve
on salvestuv sõnaraamat.
- Moodulit kasutatakse siis kui keerulisemate andmebaaside kasutus pole õigustatud.
- Andmete lugemiseks kasutame võtmenimesid nii nagu sõnastikes.
- Salvestamisel andmed serialiseeritakse.
Kasutamise näide:
import shelve
f = shelve.open('Juulius') # Faililaiendit .db pole vaja lisada.
f['a'] = 1 # Lisan võtmesõna ja väärtuse paari.
f['b'] = [1, 2, 3, 'd'] # Lisan võtmesõna ja väärtusi paari.
f.close()
f = shelve.open('Juulius')
print(f['a']) # --> 1
print(f['b']) # --> [1, 2, 3, 'd']
f.close()
1 [1, 2, 3, 'd']
Kasutus koos kontekstihalduriga ehk with
-blokis:
import shelve
with shelve.open('Juulius') as f: # laiendit .db pole vaja kasutada
f['a'] = 1
f['b'] = [1, 2, 3, 'd']
f['c'] = 'Juulius kallistamine ei ole kuritegu.'
with shelve.open('Juulius') as f:
print(f['a'])
print(f['b'])
print(f['c'])
1 [1, 2, 3, 'd'] Juulius kallistamine ei ole kuritegu.
Joonised 2 ja 3 kujutavad meeme mis piltlikustavad moodulite pickle
ja shelve
poolt loodud serialireeritud struktuuride erinevuse.
Joonis 3. Meem moodulile shelve . |
Moodul csv
, CSV failide kasutamine¶
CSV failide importimiseks ja loomiseks on loodud moodul mis on Pythoni standarteegi osa. Lisainfo: https://docs.python.org/3/library/csv.html
CSV (Comma Separated Values) on üks vanimaid ja universaalsemaid failivorminguid, kus andmed on üksteisest eraldatud semikoolonitega, komadega, taandetega või muude sümbolitega. Andmete lugemisega saavad hakkama nii tavalised kontoritööprogrammid (MS Word, OpenOffice, LibreOffice), kui ka lihtsad tekstiredektorid nagu Notepad jne.
Loome .csv
faili:
import csv
with open('Juulius.csv', 'w') as f:
k = csv.writer(f, delimiter=',')
k.writerow(['No', ' Name', ' Contribution'])
k.writerow(['1', ' Linus Torvalds', ' Linux Kernel'])
k.writerow(['2', ' Tim Berners-Lee', ' World Wide Web'])
k.writerow(['3', ' Guido van Rossum', ' Python Programming'])
k.writerow(['4', ' Juulius Tipikas', ' None'])
with open('Juulius.csv', 'r') as f: # Avame ja loeme:
sisu = f.read()
print(sisu)
No, Name, Contribution 1, Linus Torvalds, Linux Kernel 2, Tim Berners-Lee, World Wide Web 3, Guido van Rossum, Python Programming 4, Juulius Tipikas, None
Mooduli csv
meetod reader
:
import csv
with open('Juulius.csv', 'r') as f: # Loeb ka muid faililaiendeid.
reader = csv.reader(f)
for row in reader: # reader, iteraatortoega objekt.
print(row)
['No', ' Name', ' Contribution'] ['1', ' Linus Torvalds', ' Linux Kernel'] ['2', ' Tim Berners-Lee', ' World Wide Web'] ['3', ' Guido van Rossum', ' Python Programming'] ['4', ' Juulius Tipikas', ' None']
Meetodi reader
argumendid:
import csv
with open('Juulius.csv', 'r') as f:
reader = csv.reader(f, skipinitialspace=True) # Eemaldab tühikud.
for row in reader:
print(row)
['No', 'Name', 'Contribution'] ['1', 'Linus Torvalds', 'Linux Kernel'] ['2', 'Tim Berners-Lee', 'World Wide Web'] ['3', 'Guido van Rossum', 'Python Programming'] ['4', 'Juulius Tipikas', 'None']
Eelnevalt kasutatud CSV faili põhjal saab luua sõnaraamatu. Meetod: DictReader
.
import csv
with open("Juulius.csv", 'r') as f:
csv_file = csv.DictReader(f, skipinitialspace=True)
for sonastik in csv_file:
print(sonastik) # Võid muuta tavaliseks sõnastikuks, dict(sonastik).
print()
with open("Juulius.csv", 'r') as f:
csv_file = csv.DictReader(f, skipinitialspace=True)
for sonastik2 in csv_file:
print(dict(sonastik2))
sonastik2['Name']
{'No': '1', 'Name': 'Linus Torvalds', 'Contribution': 'Linux Kernel'} {'No': '2', 'Name': 'Tim Berners-Lee', 'Contribution': 'World Wide Web'} {'No': '3', 'Name': 'Guido van Rossum', 'Contribution': 'Python Programming'} {'No': '4', 'Name': 'Juulius Tipikas', 'Contribution': 'None'} {'No': '1', 'Name': 'Linus Torvalds', 'Contribution': 'Linux Kernel'} {'No': '2', 'Name': 'Tim Berners-Lee', 'Contribution': 'World Wide Web'} {'No': '3', 'Name': 'Guido van Rossum', 'Contribution': 'Python Programming'} {'No': '4', 'Name': 'Juulius Tipikas', 'Contribution': 'None'}
'Juulius Tipikas'
Sõnaraamatute abil saab luua .csv
faili. Meetod: DictWriter
.
import csv
with open('Juulius.csv', 'w') as f:
päis = ['Nimi', 'Kool']
writer = csv.DictWriter(f, fieldnames=päis)
writer.writeheader() # Päise loomine.
writer.writerow({'Nimi': 'Juulius Tipikas', 'Kool': 'TPI'})
writer.writerow({'Nimi': 'Juhan Liiv', 'Kool': 'TTÜ'})
with open('Juulius.csv', 'r') as f:
sisu = f.read()
print(sisu)
Nimi,Kool Juulius Tipikas,TPI Juhan Liiv,TTÜ
NumPy ja vormindatud tekstifaili sisselugemine ja funktsioon numpy.loadtxt
¶
Oletame, et meil on mitme tulbaga fail mis sisaldab numbreid. Moodul NumPy sisaldab funktsiooni mis lubab need andmed suhteliselt lihtsalt importida. Lisainfo: https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html
from numpy import loadtxt
from io import StringIO
fail = StringIO("0 1 2\n2 3 4") # Käitub nagu failiobjekt, failise on 3 tulpa ja 2 rida.
v1, v2 = loadtxt(fail,
delimiter = ' ',
skiprows = 0,
usecols = (1, 2), # Kasutan ainult neid tulpasid.
unpack = True)
print(v1, v2)
[1. 3.] [2. 4.]
Kasutus koos kontekstihalduriga ehk with
-blokis:
with StringIO("0 1 2\n2 3 4") as f: # Väljakutse StringIO() asemel kasuta faili nime ja laiendit.
v1, v2 = loadtxt(f,
delimiter = ' ',
skiprows = 0,
usecols = (1, 2), # Kasutan ainult neid tulpasid.
unpack = True)
print(v1, v2)
[1. 3.] [2. 4.]
Numpy võimaldab enda spetsiaalseid andmetüüpide (arutame tuleviku loengutes) väärtusi ja andmeid salvestada spetsiaalsesse binaarsesse serialiseeritud faili mille laiendiks on .npy (või .npz):
import numpy as np
with open('Juulius.npy', 'wb') as f: # Loome binaarse faili.
np.save(f, np.array([1, 2])) # Salvestame andmemasiivi.
np.save(f, np.array([3, 4]))
with open('Juulius.npy', 'rb') as f: # Loeme faili. Fail sisaldab kõike vajalikku objekti taastamiseks.
a = np.load(f) # Loodud .npy ja .npz failide lugemiseks.
b = np.load(f)
print(a, b)
[1 2] [3 4]
Lisaks võid vaadata ka: numpy.savetxt
, numpy.savez
ja numpy.savez_compressed
.
Muutujatele väärtuste omistamine käsurealt konsoolist (argument parsing)¶
Loome proge.py
programmifaili mis sisaldab järgmist lähtekoodi:
import sys
x = int(sys.argv[1])
y = int(sys.argv[2])
print('Argumente kokku: {}'.format(len(sys.argv)))
print('Edastatud argumendid: {}'.format(sys.argv))
print('x + y =', x + y)
Käivita programm konsoolist kasutades käsku python proge.py 5 6
, kus 5
ja 6
on muutujatele edastatud (parsitud) väärtused.
Allolev tabel seletab argumentide sys.argv
indekreesimise järjekorda.
python | proge.py | <argument 1> | <argument 2> |
---|---|---|---|
indeks | 0 | 1 | 2 |