Tag Archives: Emelt szint

Informatika emelt érettségi 2008. május – Programozás (SMS)

SMS

Feladat: https://www.oktatas.hu/pub_bin/dload/kozoktatas/erettsegi/feladatok2008tavasz/e_info_08maj_fl.pdf

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á. 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.

print("1. feladat")
smsList = []
egySms = []
with open('sms.txt', 'r') as smsek:
    smsSzam=int(smsek.readline().strip())
    for i in range(0, smsSzam):
        egySms.append(smsek.readline().strip().split(" "))
        egySms.append(smsek.readline().strip())
        smsList.append(egySms)
        egySms = []
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!

print("2. feladat")
utolsoSMS = len(smsList)
print(smsList[utolsoSMS-1][1])

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,len(smsList)):
    if len(smsList[index][1]) < len(smsList[i][1]):
        index = i
print("A leghosszabb üzenet adatai:")
ora = smsList[index][0][0]
perc = smsList[index][0][1]
tel = smsList[index][0][2]
uzenet = smsList[index][1]
print("%s:%s tel: %s üzenet: %s"%(ora,perc,tel,uzenet))

Szerintem menni fog a legrövidebb egyedül is! 🙂

Folytatása következik….

Informatika emelt érettségi 2016. május (magyar) – Programozás (Zár)

Zár

http://dload.oktatas.educatio.hu/erettsegi/feladatok_2016tavasz_emelt/e_infma_16maj_fl.pdf

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! (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.

Megoldások: 1. 2. 3. 4. 5. 6. 7.

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())
1. feladat megoldása

A megnyitott ajto.txt-t soronként végigjárva (for in), a végéről a sortörést (\n) eltávolítva a strip() metódusssal, 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'
2. feladat megoldása

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ő:
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. Mint a példából látható, 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)
két szám távolsága

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('{: >1}'.format(str(e)) for e in nyitok))
print(" ".join(str(e) for e in nyitok))
3. feladat megoldása

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.

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")
4. feladat (döntés elhalasztás elvének alkalmazása)

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
nincsIsmetles() függvény

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))
5. feladat

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
6. feladat mgoldása

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 hibá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)
7. feladat megoldása

Azt hiszem ez nem kíván magyarázatot.

 

Informatika érettségi emelt szintű – Adatbázis-kezelés – 2015. május

Nincs adat importálás csak tábla ellenőrzés. A feladatokat javarészt nem én oldottam meg, ez egy ellenőrzés magyarázattal. Az 5.,  8. és 9. feladat megoldással, mert az hiányzott belőle.

Feladat leírása:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2015tavasz_emelt/e_inf_15maj_fl.pdf
Feladat forrása:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2015tavasz_emelt/e_inffor_15maj_fl.zip

Informatika érettségi emelt szintű 2013. október – Adatbázis-kezelés

Konferencia

2008 tavaszán Patakfalván nagyszabású konferenciát rendeztek. Minden előadás témája a nyílt forráskódú szoftverek iskolai felhasználásához kapcsolódott. Az előadók a résztvevők közül kerültek ki. Minden előadás félórás volt, az ebédszünet 12 órakor kezdődött. Az előadók kiválasztása, majd a végleges program kialakulása után a regisztrálóknak minden előadásra, amelyet meg kívántak hallgatni, jelentkezniük kellett. Elképzelhető, hogy a konferencián több azonos nevű személy is részt vett.

Feladat leírása:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2013osz_emelt/e_inf_13okt_fl.pdf
Forrás:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2013osz_emelt/e_inffor_13okt_fl.zip

Informatika érettségi emelt szintű 2013. május – Táblázatkezelés

Sikerfilm

A mozifilmek népszerűségének többféle mérőszáma ismert. Ezek közül az egyik leggyakoribb index a film árbevételének nagysága. Ebből a szempontból az elmúlt évek egyik népszerű mozifilmjének az USA-ban elért napi adatait rögzítettük a bevetelek.txt tabulátorokkal tagolt, UTF-8 kódolású állományában. Ezen adatok feldolgozása lesz a feladata a leírás és a minta alapján.
Az adathalmaz időrendben tartalmazza, hogy mely napokon vetítették a filmet, az egyes napokon hány moziban játszották, és mennyi volt dollárban az aznapi összes bevétel az eladott jegyekből.

Feladat leírás:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2013tavasz_emelt/e_inf_13maj_fl.pdf
Forrás:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2013tavasz_emelt/e_inffor_13maj_fl.zip

Informatika érettségi feladat javítása 2015 október emelt szövegszerkesztés

Egy érettségire készülő hallgató munkájának javítását nézheted meg a videóban. Remélem, sőt biztos vagyok benne, hogy ez is segít abban, hogy tudatosabban oldjátok meg a feladatokat.

Feladat leírás:
http://dload.oktatas.educatio.hu/erettsegi/feladatok_2015osz_emelt/e_inf_15okt_fl.pdf
Forrás:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2015osz_emelt/e_inffor_15okt_fl.zip
Útmutató:
https://www.oktatas.hu/bin/content/dload/erettsegi/feladatok_2015osz_emelt/e_infmeg_15okt_ut.zip

Ötszáz programozás feladat – 2016. május

Feladat leírása


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.

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 árúcikkeket
      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 \n a sortörés. A végén csak megnövelem az i-t vagyis a vásárlás sorszámát.

Törtek feladat – 2012. május

Feladat leírás


A matematikában sokszor van szükségünk műveletvégzésre a közönséges törtekkel. A legtöbb számológép és számítógépes program csak a tizedes törteket ismeri. Készítsen programot, amely az alábbi – közönséges törtekkel kapcsolatos – feladatokat megoldja! A program forráskódját tort néven mentse! A feladatban csak pozitív számokkal kell dolgoznia, és ennek a tulajdonságnak a feldolgozandó fájlban található számadatok is megfelelnek. A felhasználótól bekérendő és a feldolgozandó fájlban található számokról feltételezheti, hogy legfeljebb kétjegyűek.

Feladatok megoldásai:
1. feladat
2. feladat
3. feladat
4. feladat
5. feladat
6. feladat
7. feladat

1. feladat

Kérjen be a felhasználótól két számot, amely egy közönséges tört számlálója és nevezője!
Döntse el, hogy az így bevitt tört felírható-e egész számként! Ha igen, írja ki értékét egész számként, ha nem, írja ki „Nem egész”!

print("1. feladat")
a = int(input("Kérem a tört számlálóját: "))
b = int(input("Kérem a tört nevezőjét: "))
if a % b == 0:
    print(int(a/b))
else:
    print("Nem egész")

A % operandus két szám maradékát adja eredményül – például: 4 % 2 = 0 vagy 11 % 3 = 2, mert 11 / 3 = 3 és a maradék 2.

Az a/b eredménye valós szám típusú szám. Az int(a/b) egész szám típusúvá alakítja a hányadost.

2. feladat

A közönséges törteket úgy tudjuk a legegyszerűbb alakra hozni, ha a számlálóját és nevezőjét elosztjuk a két szám legnagyobb közös osztójával, és az így kapott érték lesz az új számláló, illetve nevező. Az egyszerűsítéshez készítsen egy rekurzív függvényt az alább leírt euklideszi algoritmusnak megfelelően!

Természetesen a Python tudja önállóan az LNKO előállítását is, de ezt most nem használhatjuk.

A legszebb megoldás, de sajnos a feladat nem ezt kéri a következő:

def lnko(m, n):
    if n:
        return lnko(n, m%n)
    return m

Ez az Euklideszi algoritmus python leírása. Röviden ez történik:

Az euklideszi algoritmus két egész szám legnagyobb közös osztójának (lnko) meghatározására szolgál, maradékos osztások egymásutánjával. Először maradékosan elosztjuk az egyik számot a másikkal, majd az osztót a maradékkal, majd a második osztás osztóját a második osztás maradékával, és így tovább egészen addig, amíg a maradék 0 nem lesz.
A maradékos osztás maradékát visszaadó kifejezés jele a Python-ban a % jel, úgyhogy a példában szereplő számokkal az osztások láncolata: 21 % 33 = 21, 33 % 21 = 12, 21 % 12 = 9, 12 % 9 = 3, 9 % 3 = 0. (A hányadosokra jelen esetben nincs szükségünk.)
Az utolsó nem nulla maradék lesz az lnko. Ő ugyanis osztója a láncolatban szereplő összes számnak, tehát a kiinduló két számnak is. És fordítva, a kiinduló két szám minden közös osztója osztója lesz a láncolatban szereplő összes számnak, tehát az utolsó nem nulla maradéknak is. És az algoritmus valamikor biztosan véget ér, mivel a maradékok sorozata szigorúan monoton csökkenő.

Itt találtam: Python haiku

Megoldás a feladat szerint

A feladat azt kéri, hogy ezt az algoritmus használjuk:

tortAlgRekurzio

Ez egy rekurzív függvény, mert önmagát hívja meg egészen addig, amíg az a egyenlő nem lesz b-vel. Ez a kilépési pont!

Nézzük, hogyan működik:

Ez egy rekurzív függvény, mert önmagát hívja meg egészen addig, amíg az a egyenlő nem lesz b-vel. Ez a kilépési pont!

Nézzük, hogyan működik:

Algoritmus teszt
a b a = b a < b a > b
21 33 hamis igaz hamis
21 33-21 = 12 hamis hamis igaz
21-12 = 9 12 hamis igaz hamis
9 12 – 9 = 3 hamis hamis igaz
9 – 3 = 6 3 hamis igaz hamis
3 3 igaz hamis hamis

És tényleg a 21 és 33 legnagyobb közös osztója a 3.

Megoldás python nyelven

print("2. feladat")
def lnko(a, b)
    if a == b:
        return a
    if a < b:
        return lnko(a, b - a)
    if a > b:
        return lnko(b, a - b)

Az lnko egy saját gyátású függvény, használata a következő:

print(lnko(21, 33))
vagy
x = lnko(21,33)

3. feladat

Az első feladatban bekért törtet hozza a legegyszerűbb alakra a létrehozott függvény segítségével! Amennyiben nem sikerül az előírt függvényt elkészítenie, alkalmazhat más megoldást, hogy a további feladatokat meg tudja oldani. Az eredményt írja ki a következő formában:
24/32 = 3/4

vagy

24/6 = 4

A megoldás

print("3. feladat")
oszto = lnko(a,b)
if int(b / oszto) != 1:
    print("%d/%d = %d/%d"%(a,b,int(a/oszto), int(b/oszto)))
else:
    print("%d/%d = %d"%(a,b,int(a/oszto)))

4. feladat

Két törtet úgy tudunk összeszorozni, hogy a két tört számlálóját összeszorozva kapjuk az eredmény számlálóját, és a két tört nevezőjét összeszorozva kapjuk az eredmény nevezőjét. Kérjen be a felhasználótól egy újabb közönséges törtet a számlálójával és a nevezőjével! Szorozza meg ezzel a törttel az első feladatban bekért törtet! Az eredményt hozza a legegyszerűbb alakra, és ezt írja ki a következő formában:
24/32 * 12/15 = 288/480 =3/5

vagy

24/32 * 8/3 = 192/96 = 2

A megoldás

print("4. feladat")
c = int(input("Kérem a szorzó tört számlálóját: "))
d = int(input("Kérem a szorzó tört nevezőjét: "))
oszto = lnko(a*c,b*d)
if int(b*d / oszto) != 1:
    print("%d/%d * %d/%d = %d/%d = %d/%d"%(a,b,c,d,a*c,b*d,int(a*c/oszto), int(b*d/oszto)))
else:
    print("%d/%d * %d/%d = %d/%d = %d"%(a,b,c,d,a*c,b*d,int(a*c/oszto)))

5. feladat

Két közönséges tört összeadásához a következő lépésekre van szükség:

  • Mindkét számot bővíteni kell, azaz mind a számlálóját, mind a nevezőjét ugyanazzal a számmal kell megszorozni. Ezt a bővítést úgy célszerű elvégezni, hogy a közös nevező a két eredeti nevező legkisebb közös többszöröse legyen. Ez lesz az összeg nevezője.
  • A két bővített alakú tört számlálóját összeadjuk, ez lesz az eredmény számlálója. Ehhez készítsen függvényt az alábbiakban leírtak szerint – a korábban elkészített lnko függvény felhasználásával – a legkisebb közös többszörös meghatározására!
Függvény lkkt(a, b: egész számok) : egész szám
   lkkt := a * b / lnko(a, b)
Függvény vége

Egyszerű matematika:

12 = 2 * 2 * 3 és 18 = 2 * 3 * 3, tehát a legnagyobb közös osztó  2 * 3 = 6. A függvény szerint a legkisebb közös többszörös 12 * 18 / 6 = 36. A matek órán tanultak szerint az összes prímtényező a legmagasabb hatványon a legkisebb közös többszörös. Vagyis 2 * 2 * 3 * 3 = 36. És tényleg.

 

A megoldás

print("5. feladat")
def lkkt(a, b):
    return int(a * b / lnko(a,b))

6. feladat

A függvény segítségével határozza meg a két bekért tört összegét, és ezt adja meg a következő formában! (Amennyiben nem sikerül az előírt függvényt elkészítenie, alkalmazhat más megoldást, hogy a további feladatokat meg tudja oldani.)

24/32 + 8/3 = 72/96 + 256/96 = 328/96 = 41/12

Amennyiben az eredmény felírható egész számként, akkor ebben az alakban jelenjen meg:

22/4 + 27/6 = 66/12 + 54/12 = 120/12 = 10

A megoldás

print("6. feladat")
_lkkt = lkkt(b,d) #a legkisebb közös többszörös kiszámítása
_a = a * _lkkt / b #az első tag bővített számlálója
_c = c * _lkkt / d #az második tag bővített számlálója
_sz = _a + _c #eredmény számlálója
if int(_lkkt / lnko(_sz, _lkkt)) != 1:
    print("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d/%d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt)),int(_lkkt/lnko(_sz,_lkkt))))
else:
    print("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt))))

7. feladat

Az adat.txt (becsomagolva(zip)) állományban található műveleteket végezze el, és az eredményeket a korábbi, képernyőre kiírt formátumnak megfelelően írja az eredmeny.txt állományba! Az adat.txt fájlnak legfeljebb 100 sora lehet; soronként 4 számot és egy műveleti jelet tartalmaz, melyeket mindenhol egy szóköz választ el egymástól. Műveleti jelként csak összeadás és szorzás szerepel.

Például:

tortAdatTxt

A megoldás

Ez  a beolvasás:

print("7. feladat")
feladatok = []
with open('adat.txt','r') as adat:
    for egySor in adat:      
        feladatok.append(list(egySor.strip().split(' ')))

Ez pedig a kiírás:

with open('eredmeny.txt','w') as eredmeny: 
    for egyFeladat in feladatok:
        a = int(egyFeladat[0])
        b = int(egyFeladat[1])
        c = int(egyFeladat[2])
        d = int(egyFeladat[3])
        muvelet = egyFeladat[4]
        if muvelet == '+':
            _lkkt = lkkt(b,d)
            _a = a * _lkkt / b
            _c = c * _lkkt / d
            _sz = _a + _c
            if int(_lkkt / lnko(_sz, _lkkt)) != 1:
                eredmeny.write("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d/%d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt)),int(_lkkt/lnko(_sz,_lkkt))))
            else:
                eredmeny.write("%d/%d + %d/%d = %d/%d + %d/%d = %d/%d = %d"%(a,b,c,d,_a, _lkkt, _c, _lkkt, _sz, _lkkt, int(_sz/lnko(_sz,_lkkt))))
        if muvelet == "*":
            oszto = lnko(a*c,b*d)
            if int((b*d) / oszto) != 1:
                eredmeny.write("%d/%d * %d/%d = %d/%d = %d/%d"%(a,b,c,d,a*c,b*d,int(a*c/oszto),int(b*d/oszto)))
            else:
                eredmeny.write("%d/%d * %d/%d = %d/%d = %d"%(a,b,c,d,a*c,b*d,int(a*c/oszto)))
        eredmeny.write("\n")            
Ez a megoldás olyan, mint amikor a diák, nem olvassa el előre a feladatot, nem tervez előre, csak csinálja, csinálja és csinálja. Gyakorlatilag lemásoltam újra az előző feladatok megoldását, a print() utasítást pedig átírtam eredmeny.write() utasításra. Ez gyors, de nem szép programozói megoldás.

A tört feladat megoldás hivatkozás alatt a teljes programot találod a szebbik megoldással.