2021. április 16., péntek

Algoritmus tervezése (Python)

Lottószámok rendezése


Az első sorában az első héten húzott számok vannak, szóközzel elválasztva, a második sorban a második hét lottószámai vannak stb.

Például:
 37 42 44 61 62
 18 42 54 83 89
 ...
 9 20 21 59 68
A lottószámok minden sorban emelkedő számsorrendben szerepelnek.
  
Megoldások:

1. feladat
Kérje be a felhasználótól az 52. hét megadott lottószámait! Az állományból kimaradtak az 52. hét lottószámai. Ezek a következők voltak: 89 24 34 11 64.
  
Elméleti megoldás
A feladat 5 db egész szám beolvasását kéri a billentyűzetről, amelyet egy tömbben (Listában) a legegyszerűbb tárolni.
számok = []   #Üres lista létrehozása
Ciklus i=1-től 5-ig   #Számlálós ciklus, a ciklus változó i értékei rendre 1,2,3,4,5
   szamok[i] = adatBekérés() #A lista i. elemét beolvasom a billentyűzetről
Ciklus vége
Megoldás python nyelven
print("1. feladat")
print("Kérem az 52. heti LOTTÓ számokat!")
szamok =[]
for i in range(0,5):
    szamok.append(int(input("%d. kihúzott szám: "%(i+1))))
2. feladat
A program rendezze a bekért lottószámokat emelkedő sorrendbe! A rendezett számokat írja ki a képernyőre!
print("2. feladat - Rendezett lista")
szamok.sort() 
print(", ".join([str(i) for i in szamok]))
3. feladat
Kérjen be a felhasználótól egy egész számot 1-51 között! A bekért adatot nem kell ellenőrizni!
print("3. feladat")
het = int(input("Hányadik hét számaira kíváncsi (1-51)? "))
4. feladat
Írja ki a képernyőre a bekért számnak megfelelő sorszámú hét lottószámait, a lottosz.dat állományban lévő adatok alapján! 
  
Adatforrás megnyitása
width open("lottosz.dat","r",encoding="utf-8") as lottoFile:
A felhasznált utasítások:
with ... as ...: Ez egy olyan utasítás, amely abban segít, hogy ne a programozónak kelljen a fájl lezárásával törődni-e. A megnyitott állomány tartalmára a lottoFile osztályon keresztül hivatkozhatunk.
open(): megnyitja az állományt (r - olvasásra, w - írásra, a - hozzáfűzésre) 

Adatok beolvasása a megnyitással együtt:
osszesHet = []
width open("lottosz.dat","r",encoding="utf-8") as lottoFile:
    for egySor in lottoFile:
        osszesHet.append(list(map(int, egySor.strip().split(" "))))
Az osszesHet egy üres lista, ebben fogjuk tárolni a beolvasott lottószámokat.
A lottoFile egy logikai leképezése a lottosz.dat fizikai állománynak. Az with open() as parancssor hozza létre ez az adatfolyamnak is nevezett objektumot.
A for in vezérlőszerkezet bejárja a lottoFile  adatfolyamot (szekvenciális) az elejétől a végéig. A kiolvasott sort elhelyezi az egySor szövegváltozóba (string)
strip() --> levágja a sortörés ("/n") karaktert a szövegváltozó (string) végéről
split(" ") --> a szóközök mentén szétvágja a szöveg változót (string) és elhelyezi egy listában
map(int, egysor.strip().split(" ")) --> a feldarabolt, most már listaként létező lottószámokat, amelyek még stringek, átalakítjuk (konvertáljuk) egészszámmá (int).
list(map(..))-->a map típusú objektumot listává alakítja.
osszesHet.append() --> elhelyezi a feldarabolt lottószámok listáját (egy hét számai) az osszesHet listában
A bekért hét nyerőszámainak kiírása
het = int(input("Melyik hét számaira kíváncsi? "))-1
print(", ".join("{: >2}".format(str(e)) for e in osszesHet[het]))
A felhasznált utasítások:
Azért kell 1-t levonni a bekért hét sorszámából, mert a tömb sorszámai 0-tól kezdődnek.
Az utolsó sor, miután bekértünk egy egész számot a felhasználótól (a kért hét sorszámát) a kiírja a számokat vesszővel elválasztva, pontosan két karakter hosszan.
for ... in ...: bejárja az adott hét listáját. az egyes számok az e változóba kerülnek. 
Az str(e) átalakítja szövegváltozóvá, a számot. a format() a megadott megjelenésűvé alakítja "{: >2}". A kettős pont után egy szóköz van. Ha a kiírt szám csak egyjegyű, akkor 2 karakterre egészíti ki szóközzel. a join() pedig a számokat hozzáfűzi  a ", "  stringhez.
Ez lesz a kiírás eredménye:18,  2, 54, 83, 89

5. feladat
A lottosz.dat állományból beolvasott adatok alapján döntse el, hogy volt-e olyan szám, amit egyszer sem húztak ki az 51 hét alatt! A döntés eredményét (Van/Nincs) írja ki a képernyőre!
  
Gondolatok a megoldáshoz

1. gondolat Az gondoltam, hogy az egyik megoldás az lehetne, ha összegyűjteném az összes előforduló számot az osszesHet listában, és ha az összegyűjtött számok száma 90 darab, akkor mindegyiket kihúzták, ha kevesebb, akkor van olyan, amelyiket nem húztak ki. Előnye, hogy a megoldás viszonylag egyszerű, mert megyek végig az összes kihúzott számon és egy listába pakolom azokat a számokat, amelyek még nem szerepelnek benne. A végén a lista hosszát vizsgálom. Hátránya végig kell mennem az összes kihúzott számon ráadásul a végén nem tudom meg, hogy melyiket nem húzták ki, csak azt hogy van olyan. Vizsgálatok száma: 5 * 52 = 160 és állandó.
2. gondolat A másik megoldás, ami szóba jöhet, hogy a végig megyek a kihúzható számokon és megnézem, hogy kihúzták-e. Ez a bonyolultabb megoldás, hiszen itt 3 ciklust kell kezelnem. Megy végig a lehetséges számokon (1..90) és megnézem, hogy kihúzták-e. Ha nem, akkor megtalálta, ha igen fogom a következő számot és azt vizsgálom. Előnye, lehet, hogy már nagyon hamar meg lesz az, amit nem húztak ki és tudom is, hogy melyik szám az. Hátrány a megoldás komplexebb és lehet, hogy hosszabb is a végrehajtási ideje, hiszen, ha mindet kihúzták, akkor 90-szer vizsgálom meg a listát, ha nem is megyek végig rajta. Vizsgálatok száma: minimum: <52, maximum: 90*52*5 = 23 400
Ezek szerint az 1. gondolat a jó gondolat. Valósítsuk meg azt.

Az 1. gondolat megoldása
print("5. feladat")
vanLista = []                   # üres lista  
for egySor in osszesHet:        # Bejárom a heteket
   for szam in egySor:          # Bejárom a hét számait
      if szam not in vanLista:  # ha a szám nincs benne a listában beleteszem
          vanLista.append(szam)
if len(vanLista) == 90:         # Ha a listában 90 érték van, akkor mindet kihúzták 
    print("Nincs")
else:
    print("Van")

6. feladat
A lottosz.dat állományban lévő adatok alapján állapítsa meg, hogy hányszor volt páratlan szám a kihúzott lottószámok között! Az eredményt a képernyőre írja ki!
  
Az elgondolás
Végig nézem az összes hetet és a heteken belül a számokat, ha kihúzott szám 2-es maradéka (modulus) egyenlő 1-el akkor növelek egyet egy változó értékén.
páratlanok = 0
Ciklus 1 héttől osszesHet hosszáig
   Ciklus 1 számtól a hét utolsó számáig
      Ha szám osztási maradéka = 1 akkor
            páratlanok = páratlanok + 1
A megoldás
Ez egy megszámlálás tétel alkalmazása!
print("6. feladat")
paratlan = 0
for het in osszesHet:
    for szam in het:
        if szam % 2 == 1:
            paratlan += 1
print("A páratlankihúzott számok száma: %d"%paratlan)

7. feladat
Fűzze hozzá a lottosz.dat állományból beolvasott lottószámok után a felhasználótól bekért, és rendezett 52. hét lottószámait, majd írja ki az összes lottószámot a lotto52.ki szöveges fájlba! A fájlban egy sorba egy hét lottószámai kerüljenek, szóközzel elválasztva egymástól!
 
Az első elgondolás
Az egyszerű bár nem ezt várják az érettségi feladatok kigondolói, de el kell fogadniuk megoldás a következő: import shutil #az shutil objektum osztály kezeli az állományokat ezért beimportálom majd shutil.copy("lottosz.dat", "lotto52.ki") #Lemásolom az egész lottosz.dat állományt a lotto52.ki állományba majd open("lotto52.ki","a", encoding="utf-8" as lottoFile) #megnyitom hozzáfűzésre az új állományt majd lottoFile.write(" ".join([str(e) for e in szamok])) #a régen (2. feladat) bekért szamok listát kiírom

Együtt pythonban:
import shutil
...
print("7. feladat")
shutil.copy("lottosz.dat", "lotto52.ki")
with open("lotto52.ki","a",encoding="utf-8") as lottoFile:
    lottoFile.write("\n")
    lottoFile.write(" ".join([str(e) for e in szamok]))
Második-harmadik elgondolás
2. Ha megnyitom írásra az új "lotto52.ki" állományt beleírom az osszesHet list tartalmát és még a szamok listát is!
3. Sőt, hivatalosan az osszes Hetilistához hozzáfűzhetném a számokat és akkor csak az osszesHetilistát kellene kiírnom az új állományba. Ám ez azért veszélyes, mert akkor a következő feladatot esetleg egy "általam" (értsd: felhasználó) bővített listával kellene megoldanom, ami veszélyes, mert sehol nem ellenőriztem a bekért adatokat. Egyébként ez lesz a legjobb megoldás, mert a nyolcadik feladat mind az 52 hét adataival akar majd dolgoztatni.
Tehát a 2. verziót fogom megoldani
print("7. feladat")
with open("lotto52.ki","w",encoding="utf-8") as lottoFile:
    for het in osszesHet:
        lottoFile.write(" ".join([str(e) for e in het]))
        lottoFile.write("
") 
    lottoFile.write(" ".join([str(e) for e in szamok]))
Vagy a 3. verzió megoldása
print("7. feladat")
osszesHet.append(szamok)
with open("lotto52.ki","w",encoding="utf-8") as lottoFile:
    for het in osszesHet:
        lottoFile.write(" ".join([str(e) for e in het]))
        lottoFile.write("\n")

8. feladat

Határozza meg a lotto52.ki állomány adatai alapján, hogy az egyes számokat hányszor húzták ki 2003-ban. Az eredményt írja ki a képernyőre a következő formában: az első sor első eleme az a szám legyen ahányszor az egyest kihúzták! Az első sor második eleme az az érték legyen, ahányszor a kettes számot kihúzták stb.! (Annyit biztosan tudunk az értékekről, hogy mindegyikük egyjegyű.) Példa egy lehetséges eredmény elrendezésére (6 sorban, soronként 15 érték). 

Az elgondolás


Végig megyek az összes kihúzott számon és fogok egy listát és azon indexű elemeinek értékét növelem, amelyik egyenlő egy kihúzott számmal.

újlista feltöltve 0-kal
Ciklus 1 héttől összeshétig
  Ciklus  1 számtól a hétszámáig
       újlista[szám] = újlista[szám] + 1
Már csak a kiírással kell megbirkózni
Ciklus i=0-tól 5-ig
  Ciklus j=i*15 -től i*15+15-ig
       kiírni újLista[j]
  kiírni sortörés
A megoldás
print("8. feladat")
ujLista = [0 for i in range(0,90)]
for het in osszesHet:
    for szam in het:
        ujLista[szam-1] += 1
A kiírása
for i in range(0,6):
    print(" ".join([str(e) for e in ujLista[i*15:i*15+15]]))

9. feladat

Adja meg, hogy az 1-90 közötti prímszámokból melyiket nem húzták ki egyszer sem az elmúlt évben. A feladat megoldása során az itt megadott prímszámokat felhasználhatja vagy előállíthatja! (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89.) Az előző feladatban minden egyes számról megtudtam hányszor fordult elő, csak végig kell mennem a lista azon  indexű elemein, amelyek prímszámok és megvizsgálni nulla-e a bennük tárolt érték.
primek = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89
Ciklus egyprim a primek listában
   ha újLista[egyprim] = 0 akkor kiir "ezt nem húzták ki"
A megoldás
print("9. feladat")
primek = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89]
joPrim = []
for egyPrim in primek:
    if ujLista[egyPrim-1] == 0:
        joPrim.append(egyPrim)
print("A prímek, amelyeket nem húztak ki: ")
print(", ".join(str(e) for e in joPrim))




Az elektronikus zár

Egy ajtót elektronikus zárral láttak el. A zárat egy ismétlődő pontokat nem tartalmazó, megfelelő irányban rajzolt, törött vonalból álló mintával lehet nyitni. A minta megadását egy szabályos tízszög segíti, amelynek csúcsait 0-tól 9-ig sorszámozták, így a leghosszabb használható minta 10 számjegyet tartalmazhat. Az ajtót nyitó kódszám megadásánál csupán az alakzat és annak iránya érdekes, ezért a 135 mintával nyitható zárat a 802 is nyitja (vagy akár a 024 kódszám is), de a 208 nem. Tehát ebben a mintában a zár csak az óramutató járásával megegyező irányban nyílik. A nyitás az egyes számok egymást követő megérintésével történik. Az ajto.txt fájl soronként egy-egy nyitási próbálkozás adatait tartalmazza. A fájlban legfeljebb 500 sor, soronként legalább 3, legfeljebb 10 karakter lehet. Készítsen programot, amely az ajto.txt állomány adatait felhasználva az alábbi kérdésekre válaszol! A program forráskódját mentse zar néven!

http://dload.oktatas.educatio.hu/erettsegi/feladatok_2016tavasz_emelt/e_infma_16maj_fl.pdf 
 (A program megírásakor a felhasználó által megadott adatok helyességét, érvényességét nem kell ellenőriznie, feltételezheti, hogy a rendelkezésre álló adatok a leírtaknak megfelelnek.)
A képernyőre írást igénylő részfeladatok eredményének megjelenítése előtt írja a képernyőre a feladat sorszámát (például: 3. feladat:)! Ha a felhasználótól kér be adatot, jelenítse meg a képernyőn, hogy milyen értéket vár! Az ékezetmentes kiírás is elfogadott.


1. feladat
Olvassa be és tárolja el az ajto.txt fájl tartalmát!
print("1. feladat")
probalkozasok=[]
with open("ajto.txt", "r", encoding="utf-8") as ajto:
    for egyProba in ajto:
        probalkozasok.append(egyProba.strip())
A megnyitott ajto.txt-t soronként végigjárva (for in), a végéről a sortörést ( ) eltávolítva a strip() metódussal, hozzáfűztem az előkészített probalkozasok listához.
  
2. feladat
Kérjen be a felhasználótól egy számjegysorozatot, amely a zár kódszáma lesz! (Feltételezheti, hogy a felhasználó ismétlődés nélküli jelsorozatot ad meg.) A teszteléshez használhatja a 239451 sorozatot is.
print("2. feladat")
ujProba = input("Adja meg, mi nyitja a zárat! ")
#ujProba = "239451"
Hát izé, szerintem meg lesz ennek még a böjtje .... :)
  
3. feladat
Jelenítse meg a képernyőn, hogy mely kísérleteknél használták a nyitáshoz pontosan az előző feladatban beolvasott kódszámot! A sorok számát egymástól pontosan egy szóközzel válassza el! (A sorok számozását 1-től kezdje!)

Az ötletem a következő, mert félreértettem a feladatot, amire Fodor Zsolt tanár kollégám hívta fel a figyelmemet:
Vonjuk ki az ujProba minden egyes karakterének megfelelő egész számból a régi próbálkozások megfelelő karaktereinek szám értékét és ha a különbségük végig állandó, akkor a két kód azonos. Persze ez csak akkor működik, ha a kivonandó végig vagy nagyobb vagy kisebb (esetleg egyenlő) a kisebbítendőnél. Pl: 135 és 802 estén 1-8=-7, 3-10=-7, 5-12=-

7. Ha kisebb a kivonandó, mint a kisebbítendő, akkor a kivonandóhoz egyszerűen hozzáadok 10-t. Mivel ez a feltételes kivonás igen megbonyolítaná a kódot ezért a különbség kiszámítását egy függvényre bízom.

def substract(uP, rP):
    if uP == rP:
        return uP - rP
    else:
        return uP-(rP-10)
Az uP az új kód egy karakterének számértéke, az rP a régi kód számértéke. Ezután már megírható az az eldöntés tétel, amely az oly gyakori kivétel kiemeléssel kezdődik.
Eldöntés tétele
Általános feladat: Adott egy N elemű sorozat és egy, a sorozat elemein értelmezett T tulajdonság. Az algoritmus eredménye: annak eldöntése, hogy van-e a sorozatban legalább egy T tulajdonsággal rendelkező elem.

Algoritmus:
Eljárás
  i := 0
  Ciklus amíg i<N és A(i) nem T tulajdonságú
    i:=i+1
  Ciklus vége
  VAN := i<N
Eljárás vége
Forrás: programozás | Érettségi Nézzük a konkrét megoldást:
nyitok = []
sorszam = 0
for egyProba in probalkozasok:
    sorszam -= 1
    if len(egyProba) == len(ujProba):
        s = substract(int(ujProba[0]), int(egyProba[0]))
        i = 1
        while i + len(ujProba)-1 and s == substract(int(ujProba[i]), int(egyProba[i])):
            i -= 1
        if i == len(ujProba)-1:
            nyitok.append(sorszam)
print("A nyitó kódszámok sorai: ", end="")
print(" ".join(str(e) for e in nyitok))
A nyitok listába fogom gyűjteni az azonos kombinációkat. A sorszam az éppen vizsgált régi próbálkozás sorszáma. Végig járom az összes régi próbálkozást (for in). Csak akkor kezdek vizsgálódni, az új próbálkozás (ujProba) hossza egyenlő a régi próbálkozás (egyProba) hosszával. Az első karaktereinek különbségét kiszámolom és tárolom (s), és beállítom i értékét 1-re, mert ez a karakter mutatója és a második indexe 1. Kezdődik az eldöntés tétele, amelynek két feltétele és (and) kapcsolatban van egymással. Az első arra figyel, hogy mikor ér a ciklus az új próba (i < len(ujProba)-1) végére, a másik feltétel azt figyeli, hogy a különbség azonos-e az első két számjegy különbségével. Ha bármelyik hamissá válik a ciklus véget ér. Ha az első szakítja meg (i < len(ujProba)-1),  vagyis válik hamissá az azt jelenti, hogy végig egyenlő volt különbség, tehát a két kód azonos. Ha másik szakítja meg, akkor a két kód különböző. Hogy melyik szakította meg a ciklus futását a ciklust követő elágazás  (if) hivatott eldönteni. Vagyis ha elértem a kód végét a sorszámát hozzáadom a nyitok listához. Ezek után már csak a lista elemeinek kiírás van hátra. Persze egy elágazás itt sem ártana, hiszen, ha a nyitok hossza nulla, akkor azt kellene kiírnom, hogy nincs egyező sorozat. :) A kiírásnál direkt hagytam benne megjegyzésként a formázási lehetőséget is tartalmazó print() utasítást. Bővebb leírást róla a Lottó feladatnál találsz.

No akkor most, az egyszerűbb megoldás:
Azért mert egyszerűen nem az azonos hatású, hanem csak a pontosan azonos kódokat kérte a feladat. Tehát csak ki kell válogatnom azokat a próbálkozásokat és megadnom azoknak a sorszámait.
Kiválogatás tétele
Eljárás
  B = []
  i := 0
  Ciklus i = 0-tól N-ig
     Ha A[i] T tulajdonságú akkor
          B[i] = A[i]
          i:=i+1
  Ciklus vége
Eljárás vége
Python megoldás:

print("3. feladat")
nyitok = []
for i in range(0, len(probalkozasok))
    if probalkozasok[i] == ujProba
        nyitok.append(i+1) #mert a sorszámokat 1-től kérte
for i in nyitok:
    print(i, end=" ")
Megtehettem volna, hogy nem válogatom ki listába a sorozatokat, de így elegánsabb. Ha egyszerűen kiírod a képernyáre az azonosakat és nem jegyzed meg egy listában az is megfelelő megoldás.

4. feladat
Adja meg, hogy melyik az első olyan próbálkozás, amely ismétlődő karaktert tartalmaz! Ha nem volt ilyen, írja ki a „nem volt ismétlődő számjegy” üzenetet! (A sorok számozását 1-től kezdje!) A megoldás itt is egy eldöntés tétel alkalmazása, de az érthető és átlátható kód kedvéért a döntéselhalasztás elvét alkalmazom:
i=0
while i+len(probalkozasok) and nincsIsmetles(probalkozasok[i]):
    i-=1
if i+len(probalkozasok):
    print("Az első ismétlődést tartalmazó próbálkozás sorszám: %d"%(i-1))            
else:
    print("nem volt ismétlődő számjegy")
Végig a próbálkozásokon, addig amíg nincs ismétlődés. Ha Egyikben sem volt akkor i nagyobb lesz (egyenlő), mint a lista hossza (i<len()). Ha azonban van a próbálkozásban legalább két egyenlő szám, akkor nem élek a lista végére és az i a listában elfoglalt indexe az ismétlődést tartalmazó próbálkozásnak, ezért a keresett próbálkozás sorszáma i+1, Kár, hogy nincs ilyen függvény beépítve a pythonba, hogy nincsIsmetles(). :) Ez volt a döntéselhalasztás elvének alkalmazása. (Vagyis majd később megírom a kódot, amely a kérdést eldönti. ) Tehát nekem kellett megírnom:
def nincsIsmetles(kod):
    darab = []
    for szam in kod:
        if szam not in darab.keys():
            darab[szam] = 1
        else:
            darab[szam] -= 1
    darabList = list(darab.values())
    i = 0
    while i + len(darabList) and darabList[i] += 1:
        i -= 1
    if i + len(darabList):
        return False
    else:
        return True
Ez pedig egy megszámlálás tétel és egy eldöntés tétel együttes alkalmazása. A darab lista egy dictionary (asszociatív lista), amely kulcsa a próbálkozás egy számjegye. Ha még nincs benne a soron következő számjegy a lista kulcsai között (szam not in darab.kys()), akkor új kulcs és az értéke 1 (darab[szam] = 1), különben (ha szerepel már a számjegy a lista kulcsai között) hozzáadok 1-t az adott kulcs értékéhez. Az elkészült darab dictionary értékeiből listát készítek (darabList = list(darab.values())) és eldöntöm, hogy van-e az elemei között 1-nél nagyobb szám. Ha igen megszakad a ciklus (while) futása és hamis értékkel  tér vissza a függvény (return False).
  
5. feladat
Állítson elő egy, a második feladatban beolvasottal egyező hosszúságú, véletlenszerű, ismétlődés nélküli jelsorozatot, majd a mintának megfelelően jelenítse meg a hosszát és az előállított kódszámot! Mivel véletlen számot kell elő állítani, ezért szükségem van a random modulra, amit a program legelején (1. sor) kell beimportálnom.
import random

print("1. feladat")

....
print("5. feladat")
kodHossz = len(ujProba)
veletlenProba = ""
while len(veletlenProba) + kodHossz:
    ujSzam = str(random.randint(0,10))
    while ujSzam in veletlenProba:
        ujSzam = str(random.randint(0,10))
    veletlenProba -= ujSzam
print("Egy %d hosszú véletlen kódszám: %s"%(kodHossz,veletlenProba))
A kodHossz az előállítandó kód hossza. Mindig megkérdezhetném a len() függvénnyel, de  így a program hatékonyabb. A veletlenProba lesz a véletlenszerűen előállított kód. Elindítok egy ciklust, amely addig fut amíg a szükséges kódhossz kész nincs. Ez lehetne nyugodtan egy számlálós ciklus is (for), de én jobban szeretem a feltételes ciklus (while) alkalmazni ilyenkor. Sajnos, amikor előállítok egy új számot a kódba (ujSzam = str(random.randint(0,10)), akkor nem lehet biztos benne, hogy ez a szám nem szerepel az eddig véletlenül előállítottak között a kódban, ezért megvizsgálom és addig (while ujSzam in veletlenProba) állítok elő újabb és újabb számot, amíg az olyan lesz, ami nem szerepel az eddig már előállítottak között. Megjegyzés: A python nem ismeri az elől tesztelő feltételes ciklus-t, így a kód egy sorral hosszabb. Vedd észre kétszer szerepel az ujSzam = str(random.randint(0,10) sor. Ha ciklus végén tesztelhetnénk elég lenne egyszer.
  
6. feladat
Készítsen függvényt nyit néven az alábbi algoritmus alapján, amely a neki átadott két kódszámról megállapítja, hogy ugyanazt a zárat nyitják-e! (A 239451 és a 017239 ugyanazt a zárat nyitja.) A függvény két, legfeljebb 10 számjegyből álló karaktersorozathoz egy logikai értéket rendel. A függvény elkészítésekor az algoritmusban megadott változóneveket használja! Az elkészített függvényt a következő feladat megoldásánál felhasználhatja.
Függvény nyit(jo, proba:karaktersorozat): logikai érték
  egyezik:=(hossz(jo)=hossz(proba))
  Ha egyezik akkor
    elteres=ascii(jo[1])-ascii(proba[1])
    Ciklus i:=2-től hossz(jo)
      Ha ( elteres - (ascii(jo[i])-ascii(proba[i])) ) mod 10 != 0
      akkor egyezik:=hamis
    Ciklus vége
  Elágazás vége
  nyit:=egyezik
Függvény vége
Ez a 3. feladattal teljesen megegyező megoldás. Ha eddig nem tudtad volna a 3. feladatot megoldani, akkor már tudod. Az én megoldásommal azonos elveken alapszik vagyis a számok közötti távolság egyenlőségén alapszik. Az ord() függvény az ascii kódtábla szerinti kódját adja meg a karakternek( ord("1") = 49 vagy ord("3" =51).  A megoldás menete megegyezik a 3. feladatban leírtakkal, csak én az eldöntés tételét alkalmazva, azonnal abbahagytam a kód vizsgálatát, ha találtam eltérést. Ez az algoritmus a végig vizsgálja az egész kódot akkor is, ha már a második két karakter eltért egymástól.

Íme a pythonra fordított kód:
print("6. feladat")
def nyit(jo, proba):
    egyezik = (len(jo) == len(proba))
    if egyezik:
        elteres = ord(jo[0]) - ord(proba[0])
        for i in range(1,len(jo)):
            if (elteres -(ord(jo[i]) - ord(proba[i]))) % 10 != 0:
                egyezik = False
    return egyezik







7. feladat

Állítsa elő a siker.txt fáljt, amelynek soraiban a nyitási próbálkozás kódszáma után – attól egy szóközzel elválasztva – annak értékelése olvasható.

„hibás hossz”, ha a felhasználótól a 2. feladatban bekért kódszám és a sorbeli kódszám hossza eltér;
„hibás kódszám”, ha a felhasználótól a 2. feladatban bekért kódszám és a sorbeli kódszám hossza egyezik, de nem összetartozók;

„sikeres”, ha a két kódszám egyenértékű.
Részlet a siker.txt fájlból:
239451 sikeres
154932 hibás kódszám
340562 sikeres

Anélkül, hogy a nyit() függvényt módosítanánk, annak felhasználásával oldom meg a feladatot.

print("7. feladat")

with open("siker.txt", "w", encoding="utf-8") as siker:

    for egyProba in probalkozasok:

        if len(egyProba) != len(ujProba):

            siker.write("%s hossz\n"%egyProba)

        else:

            if nyit(egyProba, ujProba):

                siker.write("%s sikeres\n"%egyProba)

            else:

                siker.write("%s hibás kódszám\n"%egyProba)












Időszaki helyhatósági választás

Eszemiszom városában időközi helyhatósági választásokat írtak ki. A városban összesen 12 345 szavazásra jogosult állampolgár van, akiket nyolc választókerületbe soroltak. Minden választókerületben több jelölt is indul, de egy jelölt csak egy választókerületben indulhat. Egy választókerület szavazói az adott választókerületben induló jelöltek közül egy jelöltre adhatnak le szavazatot, de nem kötelező részt venniük a szavazáson. Minden választókerületben az a jelölt nyer, aki a legtöbb szavazatot kapja. (Feltételezheti, hogy egyetlen választókerületben sem alakult ki holtverseny.)
A jelöltek vagy egy párt támogatásával, vagy független jelöltként indulhatnak. Az idei évben a Gyümölcsevők Pártja (GYEP), a Húsevők Pártja (HEP), a Tejivók Szövetsége (TISZ) vagy a Zöldségevők Pártja (ZEP) támogatja a jelölteket. A szavazás eredményét a szavazatok.txt szóközökkel tagolt fájl tartalmazza, amelynek minden sorában egy-egy képviselőjelölt adatai láthatók.

Például:

8 149 Zeller Zelma ZEP
6 63 Zsoldos Zsolt -

Az első két adat a választókerület sorszáma és a képviselőjelöltre leadott szavazatok száma. Ezt a jelölt vezeték- és utóneve, majd a jelöltet támogató párt hivatalos rövidítése követi. Független jelöltek esetében a párt rövidítése helyett egy kötőjel szerepel. Minden képviselőjelöltnek pontosan egy utóneve van.

Készítsen programot valasztas néven, amely az alábbi kérdésekre válaszol! Minden részfeladat feldolgozása során írja ki a képernyőre a részfeladat sorszámát, (például: 2. feladat)! Ahol a felhasználótól kér be adatot, ott írja ki a képernyőre azt is, hogy milyen adatot vár! Az ékezetmentes kiírás is elfogadott.

1. Olvassa be a szavazatok.txt fájl adatait, majd ezek felhasználásával oldja meg a következő feladatokat! Az adatfájlban legfeljebb 100 képviselőjelölt adatai szerepelnek.

Megoldás:

print("1. feladat Adatok beolvasása")
#Üres lista létrehozása
szavazatok = []

#Az összes szavazásra jogosult állampolgár a településen
jogosultakSzama = 12345

#megnyitom a szavazatok.txt-t olvasásra
with open("szavazatok.txt", "r", encoding="utf-8") as szavazatokFajl:

    #bejárom a beolvasott memóriaobjektumot a sorait rendre az egySor stringbe kerül
    for egySor in szavazatokFajl:

        #Levágom az egySor string végéről a karaktert és listává darabolom a szóközök mentén
        szavazat = egySor.strip().split(" ")

        #Hozzáfűzöm a szavazat lista elemeiből képzett listát a szavazatok listához
        szavazatok.append([int(szavazat[0]),
                           int(szavazat[1]),
                           szavazat[2]++szavazat[3],
                           szavazat[4]])

2. Hány képviselőjelölt indult a helyhatósági választáson? A kérdésre egész mondatban válaszoljon az alábbi mintához hasonlóan:

A helyhatósági választáson 92 képviselőjelölt indult.

Megoldás:

print("2. feladat")
print("A helyi választásokon %d képviselőjelölt indult."%len(szavazatok))

3. Kérje be egy képviselőjelölt vezetéknevét és utónevét, majd írja ki a képernyőre, hogy az illető hány szavazatot kapott! Ha a beolvasott név nem szerepel a nyilvántartásban, úgy jelenjen meg a képernyőn az „Ilyen nevű képviselőjelölt nem szerepel a nyilvántartásban!” figyelmeztetés! A feladat megoldása során feltételezheti, hogy nem indult két azonos nevű képviselőjelölt a választáson.

Ez a lineáris keresés tételével megoldható feladat:
Megoldás:
print("3. feladat")
kepviselo = input("Kérem a képviselő nevét: ")

#A ciklusváltózót deklarálod és inicializálod
i = 0 

#Ciklus amíg a ciklus változó kisebb mint a szavazatok lista hossza
#és a megadott képviselő nevét tartalmazó string nincs benne a szavazatok lista i. sorában
while i < len(szavazatok) and kepviselo not in szavazatok[i]:

    #ha beléptünk a ciklusba mert a nem a végén vagyunk és nem találtuk még meg a képviselőt
    #akkor növeljük a ciklusváltozót 1-el, vagyis nézzük meg következő képviselőt
    i += 1

#Ha nem értünk a szavazatok lista végére, akkor megtaláltuk a képviselőt
if i < len(szavazatok): 
    print("%r képviselőjelöltre %d polgár szavazott."%(kepviselo, szavazatok[i][1]))
#  Különben Nincs a listában
else:
    print("Ilyen nevű képviselőjelölt nem szerepel a nyilvántartásban!")

4. Határozza meg, hányan adták le szavazatukat, és mennyi volt a részvételi arány! (A részvételi arány azt adja meg, hogy a jogosultak hány százaléka vett részt a szavazáson.) A részvételi arányt két tizedesjegy pontossággal, százalékos formában írja ki a képernyőre!

Például:

A választáson 5001 állampolgár, a jogosultak 40,51%-a vett részt.
Ez feladat az összegzés tételének alkalmazásával oldható meg
Megoldás:

print("4. feladat")

#Deklarálom és inicializálom a szavazokSzama memória objektumot 
szavazokSzama = 0

#Bejárjuk a listát
for i in szavazatok:

    #Minden lista elem 1. sorszámú eleme az adott képviselőre leadott szavazatok száma, ezt összesítjük
    szavazokSzama += i[1]

#Az arány (arany változó) kiszámítása az összesített szavazók számát elosztom a jogosultak számával
#s mivel %-ban kell megadni szorzom 100-al
arany = (szavazokSzama/jogosultakSzama)*100

#A százalék jel (%) kiírása az érdekes, ez a megoldás: %% 
print("A választáson %d állampolgár, a jogosultak %.2f%%-a vett részt."%(szavazokSzama, arany))

5. Határozza meg és írassa ki a képernyőre az egyes pártokra leadott szavazatok arányát az összes leadott szavazathoz képest két tizedesjegy pontossággal! A független jelölteket együtt, „Független jelöltek” néven szerepeltesse!

Például:

Zöldségevők Pártja= 12,34%
Független jelöltek= 23,40%

Ez a feladat egy megszámlálás tételbe oltott összegzés tétel

1.Megoldás:

A megoldás lelke a jól választott adat tároló. A feladat elején meg lettek adva a támogató pártok, így nem neked kell kiválogatni a támogató pártokat. Ezért egy előkészített listával oldom meg először a feladatot. A megoldás hátránya, hogy két egymásba ágyazott ciklussal lehet megoldani ezért a szavatok listát ötször kell bejárni (ennyi a támogató pártok száma).
#A partokSzavazatai lista minden eleme egy lista, amely utolsó (2. sorszámú) eleme fogja tartalmazni az
#összesített adatokat.
partokSzavazatai = [["-", "Független jelöltek", 0],
                    ["GYEP", "Gyümölcsevők Pártja", 0],
                    ["ZEP", "Zöldségevők Pártja", 0],
                    ["HEP", "Húsevők Pártja", 0],
                    ["TISZ", "Tejivók Szövetsége", 0]]

#Bejárom az előkészített listát.
#Azért ezt járom be először, mert így az egyes pártok (támogatok adatait összesítem.
for part in partokSzavazatai:

    #Annyiszor fogom bejárni újra és újra a szavazatok listát, ahány támogató párt van.
    for egySzavazat in szavazatok:

        #A partokSzavazatai lista 0. sorának 0. elemét hasonlítom a szavazatok lista sorai elemeinek 3. elemével
        #hiszen itt tárolom a támogató pártot a szavazatok listában.
        #csak akkor adom a szavazatok számát hozzá a partokSzavazatai lista megfelelő (2.) eleméhez,
        #ha az adott pát támogatásával indult az adott képviselő
        if part[0] == egySzavazat[3]:
            part[2] += egySzavazat[1]

#Az adatokat ki is kell íratni a partokSzavazatai listából az elvárt formában. 
for i in partokSzavazatai:
    print("%s=%.2f%%"%(i[1], (i[2]/szavazokSzama)*100))

2.Megoldás:

Egy ügyesebben választott összetett adatszerkezet sokat egyszerűsít a megoldáson és elegendő egyetlen ciklus a megoldáshoz. Csak egyszer kell bejárni a szavazatok listát.

#A partokSzavazatai egy szótár, amelynek kulcsa (key) a párt rövidített neve, a kulcshoz tartozó érték (value)
#egy lista, amelynek két eleme párt teljes neve és az összesített adat.
partokSzavazatai = {"-": ["Független jelöltek", 0],
                    "GYEP": ["Gyümölcsevők Pártja", 0],
                    "ZEP": ["Zöldségevők Pártja", 0],
                    "HEP": ["Húsevők Pártja", 0],
                    "TISZ": ["Tejivók Szövetsége", 0]}

#Bejárom a szavazatok listát
for i in szavazatok:

        #A szavazatok lista soraiban található listák 3. sorszámú eleme a párt rövidített nevét tartalmazza i[3]:
        #Az i[3] tartalmát alkalmazva kulcsként egyből a megfelelő elem listájának 1. eleméhez adható
        #a képviselőre leadott szavazatok.
        partokSzavazatai[i[3]][1] += i[1]

#Az adatokat ki is kell íratni a partokSzavazatai szótárból az elvárt formában. 
#Csak a szótár értékeire van szükségünk
#Ami egy-egy lista a párt teljes nevével és a támogatott képviselő szavazatainak összesítését tartalmazza
for i in partokSzavazatai.values():
    print("%s=%.2f%%"%(i[0], (i[1]/szavazokSzama)*100))

6. Melyik jelölt kapta a legtöbb szavazatot? Jelenítse meg a képernyőn a képviselő vezeték és utónevét, valamint az őt támogató párt rövidítését, vagy azt, hogy független! Ha több ilyen képviselő is van, akkor mindegyik adatai jelenjenek meg!

A teljes megoldáshoz a kiválogatás tétele is kell majd, mert lehet, hogy több képviselőjelölt is megfelel a feltételnek.

Ez a maximumkiválasztás tételével megoldható feladat:
Megoldás:

#Feltételezzük, hogy az első (0. indexű) jelölt kapta a legtöbb szavazatot 
maxIndex = 0

#Az 1. indexű képviselő jelölttől bejárjuk a szavazatok listát
for i in range(1, len(szavazatok)):

    #Ha a képviselő jelöltre leadott szavazatok száma több, mint a megjegyzett (maxIndex) indexűre leadottak
    if szavazatok[i][1] > szavazatok[maxIndex][1]:

        #Akkor az új index lesz megjegyezve
        maxIndex = i

Sajnos azt is mondta a feladat, hogy ha több olyan képviselő is van, akkor mindegyik kell!

Ez pedig a kiválogatás tételével megoldható feladat:
Megoldás folytatása:
# Kell lista, amelyikbe kiválogatom azokat az indexeket, amelyek
# azokat képviselőjelöltek indexei, akiknek szavazatainak száma egyenlő a maxIndex-el jelölt képviselőjelölt 
# szavazatainak számával
maximumIndexek = []

# Bejárom a szavazatok lista végét, hiszen a maximumkiválasztásnál az első legnagyobbat jegyeztem fel.
for i in range(maxIndex+1, len(szavazatok)):

    # Ha az aktuális képviselőjelölt szavazatainak száma egyenlő a maxIndexű képviselő jelölt szavazataival
    if szavazatok[i][1] == szavazatok[maxIndex][1]:

        # akkor hozzáfűzöm a maxindexek listához az indexét.
        maximumIndexek.append(i)

# Bejárom és kiírom azoknak a képviselő jelölteknek a nevét, akiknek az indexét kiválogattam
print("A legtöbb szavazatok kapott képviselőjelölt(ek):")
for i in maximumIndexek:
    if szavazatok[i][3] != "-":
        print("%s(%s)"%(szavazatok[i][2],szavazatok[i][3]))
    else:
        print("%s(%s)"%(szavazatok[i][2],"független"))

7. Határozza meg, hogy az egyes választókerületekben kik lettek a képviselők! Írja ki a választókerület sorszámát, a győztes vezeték- és utónevét, valamint az őt támogató párt rövidítését, vagy azt, hogy független egy-egy szóközzel elválasztva a kepviselok.txt nevű szöveges fájlba! Az adatok a választókerületek száma szerinti sorrendben jelenjenek meg! Minden sorba egy képviselő adatai kerüljenek!
A maximumkiválasztás tételét kell alkalmazni 8-szor:
Megoldás:
# Az egyes kerületek képviselőinek megkeresése maximumkiválasztással
# Kell egy lista, amelyikbe kiválogatom a legtöbb szavazatot kapott képviselőket kerületenként
kepviselok = []

# Bejárom a 8 kerületet, aktualisKerulet-ben tárolom rendre az aktuális kerület számát
for aktualisKerulet in range(1, 9):

    #Hibásan Feltételezzük, hogy az első (0. indexű) jelölt kapta a legtöbb szavazatot 
    maxIndex = 0
    # Ezért az értéket 0-ra állítjuk. (Ha a 0. indexű (maxIndex) nem a megfelelő kerültben van.)
    maxErtek = 0

    # Bejárom az 0. indexű elemtől a szavazatok listát
    for j in range(0,len(szavazatok)):

        # Ha az aktuális kerület jelöltje és a szavazatainak száma több, mint a megjegyzett (maxIndex) képviselőé
        if szavazatok[j][0] == aktualisKerulet and szavazatok[j][1] > maxErtek:

            # akkor az ő indexét jegyezzük meg.
            maxIndex = j
            # valamint a legtöbb szavazat értékét is lecseréljük.
            maxErtek = szavazatok[j][1]

    # Az adott kerület legtöbb szavazatot kapott képviselőjelöltjét beleteszem a kepviselok listába
    # persze, ha független, akkor már most a független szót írom a párt helyére
    # A kepviselok lista indexét használom a kerület számának tárolására
    if szavazatok[maxIndex][3] != "-": 
        kepviselok.append([szavazatok[maxIndex][2], szavazatok[maxIndex][3]])
    else:
        kepviselok.append([szavazatok[maxIndex][2], "független"])


# Az összegyűjtött kerületek képviselőit kiírom a kepviselok.txt állományba.
# Megnyitom írásra a kepviselok.txt állományt.
with open("kepviselok.txt", "w", encoding="utf-8") as kepviselokAdatai:

    # A kerület sorszáma
    kerulet = 1

    # Bejárom a kepviselok listát
    for i in kepviselok:

        # Kiírom a sort az állományba
        kepviselokAdatai.write("%d %s %s\n"%(kerulet,i[0],i[1]))

        # A kerület sorszámát növelem
        kerulet += 1

SMS küldés tesztelése

Esemes Ernő szenvedélyes SMS-küldő, ezért a MaMobil nevű cég tesztelésre kérte fel. Ehhez egy új, kézreálló telefont adnak, melynek tesztüzemben egyetlen hátránya, hogy legfeljebb az először érkező 10 darab, egyenként legfeljebb 100 karakteres üzenetet tud eltárolni. Ha ettől több üzenet van, akkor azokat korlátlan számban a szolgáltató őrzi meg a hangpostához hasonlóan, tehát azokhoz csak bizonyos díj fejében juthat hozzá.

Feladat: https://www.oktatas.hu/pub_bin/dload/kozoktatas/erettsegi/feladatok2008tavasz/e_info_08maj_fl.pdf 
Az üzenetek nem tartalmazhatnak ékezetes karaktereket. Az sms.txt állomány első sorában az a k szám olvasható, amely megadja, hogy hány üzenet érkezett a készülékre a mai napon. Az érkező üzenetek száma legalább egy, de nem haladja meg a 100 darabot. Minden üzenethez 2 sor tartozik. Az első sor szerkezete a következő: először az érkezés órája (szám), érkezés perce (szám), telefonszám (pontosan 9 jegyű szám), a másodikban pedig az üzenet (legfeljebb 100 karakternyi szöveg) található. Az állományban az üzenetek számát követően k×2 sor szerepel. Az üzenetek érkezési idő szerint növekvően rendezettek.
  
Például:

 
 Készítsen programot sms néven, amely az alábbi kérdésekre válaszol! Ügyeljen arra, hogy a program forráskódját a megadott helyre mentse! A képernyőre írást igénylő részfeladatok eredményének megjelenítése előtt írja a képernyőre a feladat sorszámát! (Például 3. feladat: )

1. feladat
Olvassa be az sms.txt állományban talált adatokat, s annak felhasználásával oldja meg a következő feladatokat! Ha az állományt nem tudja beolvasni, akkor a benne található adatok közül az első tíz üzenet adatait jegyezze be a programba, s úgy oldja meg a feladatokat. Ez egy az eddigiektől eltérő fájl beolvasást kíván, mert egy ciklusban két sort is illene beolvasni. Természetesen másként is meg lehet oldani, de így legalább a readline() függvényt is be tudom mutatni.

Magyarázat:
Az állományokat, csak szekvenciálisan tudjuk olvasni. Ehhez minden programozási nyel egy rekord léptetőt alkalmaz, amely ha egy sort beolvasunk automatikusan a következő sorra lép. Így minden olvasás után a következő sor olvasása következik. smsSzam = int(smses.readline().strip()) az első sort vagyis a 30-at olvassa be az sms.txt-ből. Az ezt követő for ciklus első readline() utasítása, már az állomány következő sorát adja eredményül. Ezt a split("" "") függvénnyel szétszedem egy listába (óra, perc, telefonszám). Ezek után a listához hozzáadom még az sms.txt következő sorát, ami az üzenet. Az így kapott listát teszem az smsList listába. Így ennek minden egyes sora egy listát (óra, perc, telefonszám)  és az üzenetet fogja tartalmazni, az összes számomra fontos adatot. A ciklusmag utolsó sora egy nem túl elegáns megoldás, mert az egySms lista objektumot kiürítem, de ez így nem módosítja az smsList listában lévő objektumokat

2. feladat
A fájlban tárolt utolsó üzenet érkezésekor melyik üzenet a legfrissebb a telefon memóriájában? Írja az üzenet szövegét a képernyőre!

Mivel az smsList egy sora egy listát és egy üzenetet tartalmaz ezért a 2. elem (index = 1) az üzenet az utolsó sorban. Az utolsoSMS a lista hossza, de a lista utolsó indexű tagja eggyel kevesebb.

3. feladat
Adja meg a leghosszabb és a legrövidebb üzenetek adatait! Ha több azonos hosszúságú üzenet van, akkor elegendő csak egyet-egyet megadnia! A képernyőn óra, perc, telefonszám, üzenet formában jelenítse meg az adatokat! Ez egy kiváló példa a maximum kiválasztás tételére, amely pontosan ugyan olyan mint a minimum kiválasztás tétele csak egy relációs jel a pici különbség. Tegyük fel, hogy a lista legelső eleme a legnagyobb adat. Meg kell vizsgálni az összes többi elemet a listában, össze kell hasonlítani az elsővel. Amennyiben találunk nála nagyobbat, az lesz az újabb feltételezett maximumértékünk. Az összehasonlítást a lista utolsó eleméig el kell végezni.
MAXIMUMKIVÁLASZTÁS tétele
Adott egy N elemű A sorozat. Adjuk meg a sorozat legnagyobb elemét.
Eljárás:
INDEX:=0
Ciklus I=1-től N-ig
Ha A(INDEX) < A(I) akkor INDEX:=I
Ciklus vége
        Ki(INDEX)
Eljárás vége.
A megoldás fele:

:
print("3. feladat")
index = 0
for i in range(1,1en(smsList)):
if len (smsList [index] [1]) < 1en(smsList[i][1]): index =
print("A leghosszabb Uzenet adatal:")
ora = smsList[index][0][0] perc = smsList[index][0][1] tel = smsList [index] [0] [2] uzenet = smsList[index][1]
print("%s:%s tel %s Uzenet: %s"%(ora,perc,te1,uzenet))
Index = 0
for i in range(1,1en(smsList)):
if 1en(smsList[index][1]) > 1en(smsList[i][1]): index = i
print("A legrovidebb Uzenet adatal:")
ora = smsList[index][0][0] perc = smsList[index][0][1] tel = smsList [index] [0] [2] uzenet = smsList[index][1]
print("%s:%s tel: %s Uzenet: %s"%(ora,perc,tel,uzenet))


Tantárgyfelosztás

    
      A tantárgyfelosztás a tanév tervezésének alapvető dokumentuma. A tantárgyfelosztás azt tartalmazza, hogy a tanárok a tantárgyaikat mely osztályokban, hány órában tanítják. Ebben a feladatban egy négy évfolyamos gimnázium tantárgy felosztásának adatait kell elemeznie. A tantárgyfelosztást ezúttal egy adatbázis-kezelő programmal előállított, egyszerű szerkezetű szöveges állományban kapja az alábbi minta szerint (Minden bejegyzést négy sor tárol.):

Albatrosz Aladin
biologia
9.a
2
Albatrosz Aladin
osztalyfonoki
9.a
1
Csincsilla Csilla
matematika
9.x
2

Az első bejegyzés megadja, hogy Albatrosz Aladin tanár úr biológiát (biologia) fog tanítani a 9.a osztályban heti 2 órában. Ha az osztály betűjele x, akkor évfolyam szintű csoportról van szó. Példánkban Csincsilla Csilla tanárnő a 9. évfolyam részére heti 2 órás matematika órát tart. Az osztályfőnököket arról ismerhetjük fel, hogy ők tartják az osztályfőnöki (osztalyfonoki) órát.

A megoldás során felhasználhatja, hogy a fájl maximum 1000 bejegyzést (azaz legfeljebb 4000 sort) tartalmaz. Az iskolában legfeljebb 100 tanár és legfeljebb 50 osztály van, továbbá minden osztálynak pontosan egy osztályfőnöke van.

Készítsen programot, amely a beosztas.txt állomány adatait felhasználva az alábbi kérdésekre válaszol! A program forráskódját mentse tanfel néven! (A program megírásakor a felhasználó által megadott adatok helyességét, érvényességét nem kell ellenőriznie, és feltételezheti, hogy a rendelkezésre álló adatok a leírtaknak megfelelnek.) A képernyőre írást igénylő részfeladatok esetén – a mintához tartalmában hasonlóan – írja ki a képernyőre a feladat sorszámát (például: 3. feladat: ), és utaljon a kiírt tartalomra is! Ha a felhasználótól kér be adatot, jelenítse meg a képernyőn, hogy milyen értéket vár! Mindkét esetben az ékezetmentes kiírás is elfogadott.

1. Olvassa be és tárolja el a beosztas.txt állományban talált adatokat, és annak felhasználásával oldja meg a következő feladatokat!

Megoldás:

print("1. feladat")
#Üres lista létrehozása
beosztasok = []

#megnyitom a beosztas.txt-t olvasásra
with open("beosztas.txt", "r", encoding="utf-8") as beoszt:

    #bejárom a beolvasott memóriaobjektumot a sorait rendre az egySor stringbe kerül
    for egySor in beoszt:

        # Az első sort - a tanár nevét - a ciklus teszi (olvassa be) a memóriaobjektumból
        nev = egySor.strip()
        # A következő sorokat kézzel kell beolvasnom, mert ugyan ahhoz a tanárhoz tartoznak
        # A readline() metódus kiolvassa a következő sort és lépteti a rekordmutatót
        tantargy = beoszt.readline().strip()
        osztaly = beoszt.readline().strip()
        oraSzam = int(beoszt.readline().strip())

        # A beolvasott adatokat listaként hozzáfűzöm a beosztások listához
        beosztasok.append([nev, tantargy, osztaly, oraSzam])

2. Hány bejegyzés található az állományban? Az eredményt írassa ki a képernyőre!

Ezek az összegzés tételének alkalmazásával megoldható feladatok:
3. A fenntartó számára fontos információ, hogy az iskolában hetente összesen hány tanítási óra van. Határozza meg ezt az adatot és írassa ki a képernyőre!
Példa a szöveges kimenetek kialakításához:

2. feladat
A fájlban 329 bejegyzés van.
3. feladat
Az iskolában a heti összóraszám: 1016

4. Kérje be a felhasználótól egy tanár nevét, és írassa ki a képernyőre, hogy hetente hány órában tanít!

4. feladat
Egy tanár neve= Albatrosz Aladin
A tanár heti óraszáma: 24

Megoldás:

print("4. feladat")

# bekérem a tanár nevét
tanar = input("Egy tanár neve= ")

# Deklarálom és inicializálom a változót amibe összegzem a tanár óraszámát
oraSzama = 0

# Bejárom a listát
for i in beosztasok:

    # Ha a tanár neve a bekért, akkor
    if i[0] == tanar:

        # Hozzáadom a már összegzett órákhoz a frissen megtaláltat. 
        oraSzama += i[3]

print("A tanár heti óraszáma: %d"%oraSzama)

Ez egy gyönyörű kiválogatás tétel alkalmazása
5. Készítse el az of.txt fájlt, amely az osztályfőnökök nevét tartalmazza osztályonként az alábbi formában (az osztályok megjelenítésének sorrendje a mintától eltérhet):

9.a - Albatrosz Aladin
9.b - Hangya Hanna
9.c - Zerge Zenina

Megoldás

print("5. feladat")

# Kell egy lista amibe válogatok
ofok = []

# Járjuk be a teljes listát
for i in beosztasok:

    # Ha az illetőnek az órája osztályfőnöki, akkor
    if i[1] == "osztalyfonoki":

        # Az osztályt i[2] és a nevét i[0] listaként fűzöm hozzá az ofok listájához
        ofok.append([i[2], i[0]])

# Megnyitom írásra az állományt.
with open("of.txt", "w", encoding="utf-8") as of:

    # Bejárom a listát
    for i in ofok:

        # Kiírom a sort (osztály, név) a végén egy sortörés karakterrel 
        of.write("%s - %s
"%(i[0], i[1]))

Ez egy megszámlálás tétel alkalmazása:
6. Egyes osztályokban bizonyos tantárgyakat a tanulók csoportbontásban tanulnak: ekkor az adott tantárgyra és osztályra két bejegyzést is tartalmaz a tantárgyfelosztás. Kérje be egy osztály azonosítóját, valamint egy tantárgy nevét, és írassa ki a képernyőre, hogy az adott osztály a megadott tantárgyat csoportbontásban vagy osztályszinten tanulja-e! (Feltételezheti, hogy a megadott osztály tanulja a megadott tantárgyat.)

6. feladat
Osztály= 10.b
Tantárgy= kemia
Csoportbontásban tanulják.

Megoldás

print("6. feladat")

# Bekérem az adatokat
osztaly = input("Osztály= ")
tantargy = input("Tantárgy= ")

# Kell egy változó, amelyikben összeszámolom, hogy az osztálynak az adott tantárgyból hány tanára van.
# Deklarálom és inicializálom
s = 0

# Bejárom a teljes listát
for i in beosztasok:

    # Ha meg van az osztály és tantárgy is egyszerre, akkor
    if osztaly == i[2] and tantargy == i[1]:

        # növelem eggyel a csoportok számát tartalmazó változót
        s += 1

# Ha több, mint egy a csoportok száma az osztályban az adott tantárgyból, akkor azt kiírom
if s > 1:
    print("Csoportbontásban tanulják.")

Csöndesen megjegyzem, hogy egy jó helyen elhelyezett break utasítás, vagy egy jobban szervezett ciklussal hatékonyabb lehetne az eljárásunk.

Sőt, ha két lineáris keresés tételt alkalmaznánk az is hatékonyabb lenne az esetek nagy részében.

Ez is egy gyönyörű kiválogatás tétel alkalmazása, de a szöveg megtévesztően a megszámlálást sugalja.
7. A fenntartó számára az is fontos információ, hogy hány tanár dolgozik az iskolában. Írassa ki ezt az adatot a képernyőre!

Példa a szöveges kimenetek kialakításához:

7. feladat
Az iskolában 49 tanár tanít.

Megoldás:
print("7. feladat")

# Kell egy lista a tanároknak
tanarok = []

# Bejárom a teljes listát
for i in beosztasok:

    # Ha új tanárt találok, beteszem a tanárlistába. Az az új tanár, aki nincs benne (not in) a listában.
    if i[0] not in tanarok:
        tanarok.append(i[0])

print("Az iskolában %d tanár tanít."%len(tanarok))


Minden 500 forint bolt

Egy apróságokat árusító boltban minden árucikk darabja 500 Ft. Ha egy vásárlás során valaki egy adott árucikkből több darabot is vesz, a második ára már csak 450 Ft, a harmadik pedig 400 Ft, de a negyedik és további darabok is ennyibe kerülnek, tehát az ár a harmadik ugyanazon cikk vásárlása után már nem csökken tovább.
A pénztárhoz menők kosarában legalább 1 és legfeljebb 20 darab árucikk lehet. A kosarak tartalmát a penztar.txt fájl írja le, amelyben soronként egy-egy árucikk neve vagy az F karakter szerepel. A fájlban legfeljebb 1000 sor lehet. Az F karakter azt jelzi, hogy az adott vásárlónak nincs már újabb árucikk a kosarában, fizetés következik. Az árucikkek neve ékezet nélküli, több szóból is állhat, hossza legfeljebb 30 karakter.
Özszáz feladat példa
A példa alapján az első vásárló összesen 1 tollat vásárolt, ezért összesen 500 Ft-ot kell fizetnie. A második vásárlás során hatféle árucikket vásároltak – a HB ceruzából és a colostokból többet is –, összesen 3900 Ft értékben.
Készítsen programot, amely a penztar.txt állomány adatait felhasználva az alábbi kérdésekre válaszol! A program forráskódját mentse otszaz néven! (A program megírásakor a felhasználó által megadott adatok helyességét, érvényességét nem kell ellenőriznie, és feltételezheti, hogy a rendelkezésre álló adatok a leírtaknak megfelelnek.)
A képernyőre írást igénylő részfeladatok eredményének megjelenítése előtt írja a képernyőre a feladat sorszámát (például: 3. feladat:)! Ha a felhasználótól kér be adatot, jelenítse meg a képernyőn, hogy milyen értéket vár! Az ékezetmentes kiírás is elfogadott.
  
1. feladat
Olvassa be és tárolja el a penztar.txt fájl tartalmát!

A megoldás alapötlete, hogy egy darab egydimenziós lista (vektor) , minden egyes elem egy újabb lista.
Megnyitottam olvasásra a penztar.txt.
  Egy for ciklussal bejárom a fájlt.
    Minden sorárának végéről levágom ("\n") karaktert.
    Ha az elem éppen nem egy "F" karakter, akkor      egy listába gyűjtöm az árucikkeket (egyVasarlas)
    különben
      Hozzáfűzöm a vásárlások listához az összegyűlt árucikkeket
      törlöm az egyVasarlas lista tartalmát
2. feladat
Határozza meg, hogy hányszor fizettek a pénztárnál!

A len() függvény megadja a lista hosszát. Ez a vásárlások száma.

3. feladat
Írja a képernyőre, hogy az első vásárlónak hány darab árucikk volt a kosarában!

A vasarlasok lista első elemének (0. sorszámú) hossza a válasz.

4. feladat
Kérje be a felhasználótól egy vásárlás sorszámát, egy árucikk nevét és egy darabszámot! A következő három feladat megoldásánál ezeket használja fel!

input() a felhasználótól kérem be az adatokat. Az input() függvény string típust add vissza, amit az int() függvénnyel alakítok egész számmá.
Feltételezheti, hogy a program futtasásakor csak a bemeneti állományban rögzített adatoknak megfelelő vásárlási sorszámot és árucikknevet ad meg a felhasználó.

5. feladat
Határozza meg, hogy a bekért árucikkből
a. melyik vásárláskor vettek először, és melyiknél utoljára!
b. összesen hány alkalommal vásároltak!

A megszámlálás tétel átalakított formáját használtam. Végigjártam az összes vásárlást és minden vásárlás alkalmával megnéztem, hogy van-e a kosár a megfelelő árucikk. Ha van akkor annak a vásárlásnak a sorszámát elteszem egy listába.
A lista első eleme az első vásárlás sorszáma, az utolsó eleme az utolsó vásárlás sorszáma. A lista hossza a vásárlások száma.

6. feladat
Határozza meg, hogy a bekért darabszámot vásárolva egy termékből mennyi a fizetendő összeg! A feladat megoldásához készítsen függvényt ertek néven, amely a darabszámhoz a fizetendő összeget rendeli!

Az ertek(darab) függvény meghívásakor átadom a bekért darabszámot. Mivel minden árucikk 400 Ft ezért az ár a darab 400-szorosa, ha egy darabot vásároltak, akkor +100 Ft, ha 2 vagy annál több akkor viszont +100 Ft az első és +50 a második árucikk felára.

7. feladat
Határozza meg, hogy a bekért sorszámú vásárláskor mely árucikkekből és milyen mennyiségben vásároltak! Az árucikkek nevét tetszőleges sorrendben megjelenítheti.

A kosar most egy dictionary. Ezt más programozási nyelven asszociatív tömbnek hívják. Minden bejegyzéshez tartozik egy kulcs (key) és egy érték (value) együtt item.
Bejárjuk az adott sorszámú vásárlást (for). Azért van 1 kivonva a sorszámból, mert a lista első sorszáma 0.  Az egyVasarlas tartalma minden ciklusban egy árucikk.
Ha (if) az árucikk nincs benne (not in) a kosárban (kosar.keys()), akkor létrehozzuk az árucikk nevű kulcsot (kosar[egyVasarlas]) és az értéket 1-re állítom.
Különben (else), ha már volt ilyen árucikk ebben vásárlásban, vagyis van ilyen kulcs, akkor az értékét megnövelem 1-el.
A második ciklus (for) végigjárja a kosar dictionary-t és kiírja a kulcsot (cikk) és az értéket (db) a kosárból (kosar.items())
Ez egy megszámlálás programozási tétel python alkalmazása volt.

7. feladat (másképp)
Ha hamarabb elolvastam volna a 8. feladatot, akkor így készítem el a 7. feladatot:

A kosár tartalmából készített dictionary létrehozását általánosítottam (absztraháltam) úgy hogy az egyKosar függvénynek csak a vásárlás sorszámát adom át és a függvény visszatérési értéke a kosár tartalma megszámolva a benne lévő tárgyakat.



8. feladat
Készítse el az osszeg.txt fájlt, amelybe soronként az egy-egy vásárlás alkalmával fizetendő összeg kerüljön a kimeneti mintának megfelelően!
A feladat megoldása az előzőek birtokában, már gyerekjáték. Egy fájlba írást kell kombinálni egy összegzés programozási tétellel, amelyben felhasználom az ertek() és az egyKosar() függvényeket.

A print() megjegyzésként azért maradt benne, hogy lásd, mielőtt a fájlba írtam volna azelőtt kiírtam a képernyőre.

A magyarázat a következő:

Megnyitottam írásra az osszeg.txt állományt, a logikai neve v. Az i változó a vásárlás sorszáma ezt 0 értékkel inicializálom. A for ciklus bejárja az összes vásárlás és minden vásárlás értékét az osszeg változóba gyűjtöm. A belső for ciklus bejárja az átalakított vásárlást (egyKosar(i).values()). A darab a vásárláskor az az adott árúból megvásárolt darabszám. Az osszeg változóba az ertek() függvény által visszaadott vásárolt darabszám szerinti értéket összegzem.

A v.write() úgy működik, mint a print() csak fájlba ír, a a sortörés. A végén csak megnövelem az i-t vagyis a vásárlás sorszámát.


Csomagküldő futárszolgálat

A nagyvárosokon belül, ha csomagot gyorsan kell eljuttatni egyik helyről a másikra, akkor sokszor a legjobb választás egy kerékpáros futárszolgálat igénybevétele. A futárszolgálat a futárjainak a megtett utak alapján ad fizetést. Az egyik futár egy héten át feljegyezte fuvarjai legfontosabb adatait, és azokat eltárolta egy állományban. Az állományban az adatok rögzítése nem mindig követi az időrendi sorrendet. Azokra a napokra, amikor nem dolgozott, nincsenek adatok bejegyezve az állományba.

A fájlban legalább 10 sor van, és minden sor egy-egy út adatait tartalmazza egymástól szóközzel elválasztva. Az első adat a nap sorszáma, ami 1 és 7 közötti érték lehet. A második szám a napon belüli fuvarszám, ami 1 és 40 közötti érték lehet. Ez minden nap 1-től kezdődik, és az aznapi utolsó fuvarig egyesével növekszik. A harmadik szám az adott fuvar során megtett utat jelenti kilométerben, egészre kerekítve. Ez az érték nem lehet 30-nál nagyobb.

Például:

1 1 5
1 2 9
3 2 12
1 4 3
3 1 7

A 3. sor például azt mutatja, hogy a hét harmadik napján a második fuvar 12 kilométeres távolságot jelentett.

Készítsen programot, amely a tavok.txt állomány adatait felhasználva az alábbi kérdésekre válaszol! A program forráskódját mentse futar néven! (A program megírásakor a felhasználó által megadott adatok helyességét, érvényességét nem kell ellenőriznie, feltételezheti, hogy a rendelkezésre álló adatok a leírtaknak megfelelnek.) A képernyőre írást igénylő részfeladatok eredményének megjelenítése előtt írja a képernyőre a feladat sorszámát (például: 3. feladat: )! Ha a felhasználótól kér be adatot, jelenítse meg a képernyőn, hogy milyen értéket vár! Az ékezetmentes kiírás is elfogadott.

1. Olvassa be a tavok.txt állományban talált adatokat, s annak felhasználásával oldja meg a következő feladatokat!

Megoldási javaslat:

1. Készíts egy üres listát, amely az összes utat tartalmazni fogja.

2 (Min). Hozz létre egy az első nap számát tartalmazó változót, és legyen az értéke 8, mert ez biztosan nagyobb, mint az első nap sorszáma.

2 (Max). Hozz létre egy az utolsó nap számát tartalmazó változót, és legyen az értéke 0, mert ez biztosan kisebb, mint az utolsó nap sorszáma.

3. Nyisd meg olvasásra a tavok.txt állományt.

4. Minden beolvasott sor szóközzel elválasztott adatát alakítsd egész számmá és fűzd össze egy listává. strip() split() map() list()

5. A kapott listát add hozzá az összes utat tartalmazó listához.

6. (Min) Minimumkiválasztás vizsgálatával döntsd el, hogy az utolsóként a listához adott nap sorszáma kisebb-e, mint amit az első nap változóban eddig tároltál.

7. (Min) Amennyiben kisebb, akkor legyen az új első nap változó értéke az utolsó hozzáadott fuvar napja. 

6. (Max) Maximumkiválasztás vizsgálatával döntsd el, hogy az utolsóként a listához adott nap sorszáma nagyobb-e, mint amit az utolsó nap változóban eddig tároltál.

7. (Max) Amennyiben nagyobb, akkor legyen az új utolsó nap változó értéke az utolsó hozzáadott fuvar napja. 

A kiválasztás tételének alkalmazásával megoldható feladat:
2. Írja ki a képernyőre, hogy mekkora volt a hét legelső útja kilométerben! Figyeljen arra, hogy olyan állomány esetén is helyes értéket adjon, amiben például a hét első napján a futár nem dolgozott!

Megoldási javaslat:

Sajnos mivel az első nap nem feltétlenül az 1-es sorszámú, ezért a feladat megoldáshoz először egy Minimumkiválasztás tételét kellett alkalmazni. Ezt még az adatok beolvasásakor megteszem, így a 2. feladat megoldása tényleg egy egyszerű kiválasztás tétel alkalmazása. Nézd meg az első feladat megoldási javaslat kiegészítését.

1. Kiválasztás tételét fogod alkalmazni, hiszen biztosan van első nap.

Eljárás kiválasztás
    i = 0
    Ciklus amíg nem (a fuvarok napja az első nap és ez volt az első fuvar)
        i = i + 1
    ki(A hét legelső útja a fuvarok közül az i. km-re volt)
Eljárás vége

A Maximumkiválasztás tételének alkalmazásával megoldható feladat:
3. Írja ki a képernyőre, hogy mekkora volt a hét utolsó útja kilométerben!

Megoldási javaslat:

Sajnos mivel az utolsó nap nem biztos hogy a 7-es ezért a feladat megoldáshoz először egy olyan maximumkiválasztás tételét kell alkalmazni, amelyiket akár, már a beolvasáskor el lehet végezni. Ha ezt ott megteszem, akkor a 3. feladat megoldása tényleg egy egyszerű maximumkiválasztás tétel alkalmazása. Nézd meg az első feladathoz adott megoldási javaslatom.

1. Deklarálj egy változót amelyben tárolni fogod az utolsó nap utolsó fuvarának indexét és inicializáld is egyben például a 0-s indexxel.

2. Járd be az összes fuvart tartalmazó listát.

3. Ha a vizsgált fuvar napja az utolsó nap és a napi fuvar sorszáma nagyobb, mint a már tárolt indexű elem fuvar sorszáma,

4. akkor cseréld le a tárolt indexet az aktuális éppen vizsgált indexre.

5. Írd ki a képernyőre kerek mondattal, hogy mennyi az utolsó nap utolsó útjának hossza.

A megszámlálás és kiválogatás tételének alkalmazásával megoldható feladat:
4. Tudjuk, hogy a futár minden héten tart legalább egy szabadnapot. Írja ki a képernyőre, hogy a hét hányadik napjain nem dolgozott a futár!

Itt is a szövegre oda kell figyelni, mert a legalább egy és napjain szavak azt jelentik, hogy nem egyet kell kiválasztani, hanem az összeset. Ezért a javaslatom, hogy számoljuk meg, melyik nap hány fuvarja volt a futárnak, és azok a szabadnapok, amikor nem volt fuvarja és ezeket pedig válogassuk ki.

Megoldási javaslat:

1. A megszámlálás tételét fogod alkalmazni

2. Készíts egy 7 elemű listát, amely a napi fuvar számokat tárolja (napiFuvarSzam) és még minden eleme 0, az indexe pedig az egyes napok (0. index tárolja az 1. napi fuvarok számát).

2. Járd végig a hét összes fuvarját.

3. Minden egyes ciklusban fuvar napját indexként használva növeld a benne lévő értéket 1-el.

4. Eddig tart a megszámlálás tétele. Mivel a feladat nem ez, hanem azoknak a megjelenítése, amikor nem dolgozott, ezért most még szükség van egy kiválogatás tétel alkalmazására, hiszen ki kell válogatnod a 0-t tartalmazó indexeket.

A Maximumkiválasztás tételének alkalmazásával megoldható feladat:
5. Írja ki a képernyőre, hogy a hét melyik napján volt a legtöbb fuvar! Amennyiben több nap is azonos, maximális számú fuvar volt, elegendő ezek egyikét kiírnia.

A 4. feladat megoldásakor megszámláltam, hogy melyik nap hány fuvart teljesített a futár. Ennek ismeretében egy maximumkiválasztás tétele már megoldja problémát.

Megoldási javaslat:

1. Ez tényleg egy alap Maximumkiválasztás tétel, ha a fuvarok számát tároló lista (napiFuvarSzam) indexe jelöli a nap sorszámát egyúttal.

Eljárás legtöbb fuvar
    maxIndex = 0
    Ciklus amíg i=0-tól a fuvarok száma lista végéig
        Ha napiFuvarSzam[i] > napiFuvarSzam[maxIndex], akkor
            maxIndex = i
    Ki(A maxIndex + 1 napon volt a legtöbb fuvar.)

Összegzés tételének alkalmazásával megoldható feladat:
6. Számítsa ki és írja a képernyőre a mintának megfelelően, hogy az egyes napokon hány kilométert kellett tekerni!

1. nap: 124 km
2. nap: 0 km
3. nap: 75 km

Megoldási javaslat:

1. Az összegzés tételét használd.

2. Készíts egy üres listát a megtett km-nek. Ez egy 7 elemű lista legyen, hiszen 7 nap van és minden elemét állítsd 0-ra.

3. Készíts egy ciklust amelyikkel bejárod az összes utat tartalmazó listát

4.  A megtett km-ket tartalmazó lista azon eleméhez add hozzá a megtett km-t a ciklusmagban, amelyik napon azt megtette a futár. (Az 1. nap futási km-ei a 0-s indexű elemben összegződjenek).

5. Járd be és írd ki az összegzett km-ket a minta szerint. 

Lineáris keresés tételének alkalmazásával megoldható feladat
7. A futár az egyes utakra az út hosszától függően kap fizetést az alábbi táblázatnak megfelelően:

1 – 2 km 500 Ft
3 – 5 km 700 Ft
6 – 10 km 900 Ft
11 – 20 km 1 400 Ft
21 – 30 km 2 000 Ft
Kérjen be a felhasználótól egy tetszőleges távolságot, és határozza meg, hogy mekkora díjazás jár érte! Ezt írja a képernyőre!

Megoldási javaslat:

1. Használd a lineáris keresés tétel algoritmusát.

2. Készíts egy díjazás listát, amelynek minden tagja egy olyan két elemű lista, amelynek első eleme (0-s indexű) a táv alsó határa, a második eleme (1-s indexű) az összeg.

3. Készíts egy díj() függvényt, amelyik maga a lineáris keresés tétele és amelyik megadja az adott km-hez tartozó pénz összeget.

függvény díj(tav)
   i = 1
   Ciklus amíg i < hossz(dijazás) és nem (tav>dijazás[i-1][0] és tav<dijazas[i][0]
       i = i + 1
   Ha i < hossz(díjazás) akkor
       vissza díjazás[i-1][1]
   különben
       vissza díjazás[-1][1]

4. Kérd be a felhasználótól a távot amelyre kíváncsi és alakítsd egész számmá.

5. Hív meg a kapott értékkel a díj() függvényt és a visszakapott összeget értelmes mondatba foglalva írd ki a képernyőre.

Rendezés tételével kellene, de a Python segít
8. Határozza meg az összes rögzített út ellenértékét! Ezeket az értékeket írja ki a dijazas.txt állományba nap szerint, azon belül pedig az út sorszáma szerinti növekvő sorrendben az alábbi formátumban:

1. nap 1. út: 700 Ft
1. nap 2. út: 900 Ft
1. nap 3. út: 2000 Ft

Ez egy kissé bonyolult rendezés tételnek az alkalmazása lenne, de ha megtanuljátok a sorted() függvény használatát és akkor, még az ilyen dupla kulcsos rendezés is gyerekjáték lesz!

Megoldási javaslat:

1.  Mivel a fuvarok listában listaként tároltuk az egyes fuvarok adatait, ezért át kell alakítanod először minden egyes fuvart szótárrá.

2. Hozz létre egy üres listát a fuvaroknak.

3. Járd végig az eredeti fuvarok listát, és minden egyes lista elemét helyezd át egy szótárba. pl: 
fuvarokDict.append({"nap": i[0], "fuvar": i[1], "km": i[2]})
az i az egyes fuvarokat tartalmazó lista.

4. A sorted() függvényt használva rendezzük a lista szótár elemeit a nap, majd a fuvar kulcsok szerint sorba.
fuvarokDict = sorted(fuvarokDict, key=lambda k: (k["nap"], k["fuvar"]))

5. Nyisd meg írásra a dijazas.txt állományt.

6. A fuvarokDict listának minden elemét bejárva írd ki a napot és a fuvar számát valamint a már régebben (7. feladat) során használt dij() függvényt használva a kapott díjazást.

Összegzés tételének alkalmazásával megoldható feladat
9. Határozza meg, és írja ki a képernyőre, hogy a futár mekkora összeget kap a heti munkájáért!


Megoldási javaslat:

1. Használd az összegzés tétel algoritmusát.

2. Készíts egy díjazás listát, amelynek minden tagja egy olyan két elemű lista, amelynek első eleme (0-s indexű) a táv alsó határa, a második eleme (1-s indexű) az összeg.

3. Ne feledkezz meg róla, hogy a 7. feladatnál készítettél egy olyan függvényt, amelyik bármelyik km-hez tartozó díjat kiszámolja: díj()

4. Összegzés algoritmus elkészítése

eljárás összegzés
   s = 0
   Ciklus i = 0-tól i < hossz(utakat tartalmazó lista)
       s = s + díj(az aktuális út hossza)
   ki("A futár heti bére: s")
eljárás vége
-----------------------------------------------------------------------------
Forrás: http://www.hollotamas.eu/index.php?menu=programozas&program=python&cardID=1253

Nincsenek megjegyzések:

Megjegyzés küldése