6. hét: további vegyes feladatok, gyakorlás

Czirkos Zoltán, Frey Balázs · 2021.09.04.

1. A 2. kis ZH feladata

Ha nem 10 pontosra írtad meg a kis zárthelyit, vagy nem ezt a változatot írtad, oldd meg most a gyakorlatvezető segítségével!

Egy hűtőházban 7 szenzor méri a hűtött tér hőmérsékletét. Az szenzorok véletlenszerűen küldenek adatokat a következő formátumban: az első sor a szenzor sorszáma, 1..7 között, a második sor pedig egy valós szám, a mért hőmérséklet Celsius fokban, amelyet a programot dolgoz fel (a programod bementére kerül.. és input-tal kell olvasnod), a feldolgozás végét egy üres sor jelenti.

Írd ki a kimenetre csoportonként az egyes szenzorok hőmérsékletének maximumát, valamint azt, hogy hány olyan szenzor volt, ahol a hőmérséklet a -15C-ot meghaladta. Az egyszerűség kedvéért feltételezheted, hogy

  1. minden szenzor küld legalább egy adatot
  2. a küldött hőmérsékleti adat helyes

Legyen hatékony az adatszerkezeted, felesleges tárolás, felesleges listaépítés ne legyen!
Példa bemenet:

1
-23.5
3
-22.5
2
-18.9
1
-23.4
...

A kimenet ilyen legyen:

1. szenzor maximális mért hőmérséklet: -23.4C
2. szenzor maximális mért hőmérséklet: -18.9C
...
3 szenzor mért -15C-nál magasabb hőmérsékletet
Megoldás
legnagyobb= [-273] * 7 
ssens= input()
while ssens != "":
    sens= int(ssens)
    temp= float(input())
    if temp > legnagyobb[sens-1]: 
        legnagyobb[sens-1]= temp
    ssens= input()

db=0
for i in range(7):
    temp= legnagyobb[i]
    print(f"{i+1}. szenzor legmelegebb hőmérséklete {temp}C")
    if temp > -15.0:
        db+=1
print(f"Összesen {db} szenzor mért -15C-nál nagyobb hőmérsékletet")

2. Egy 'kis' átalakítás

Alakítsd át az előző programot a következőképpen:
  1. A szenzorok sorszám;adat formátumban VAGY (egy részét más gyártótól vettük :-) sorszám:adat formátumban küldik az adatokat.
  2. Elképzelhető, hogy lesz olyan szenzor, ami nem küld adatot
  3. Elképzelhető, hogy az adat hibás, ilyenkor hagyd figyelmen kívül!
Példa bemenet: (egy szenzor hibás adatot küld)
1;-23.5
3:-22.5
2;-1+!5.9
1;-23.4
...
Tipp

Használd az előadáson megismert split() függvényt (olvasd el a dokumentációt is!) és a kivételkezelést!

Megoldás

Mivel ez mostmár nem a kiszárthelyi feladat, több idő van helyesen elkészíteni. A szenzorok számát ill. a határokat rögzítsük a program elején. (így ha változtatni kell, könnyű lesz megtenni.) A "nem küld adatot" esetre úgy készülünk fel, hogy a számoló tömböt 0K-el töltjük fel. Nyilvántarthatnánk egy másik listában, hogy a szenzor küldött-e adatot, lehetne None az érték, amíg nincs érvényes adat stb., de ez most a legegyszerűbb mód.

A sort a split() függvénnyel bontjuk adatokra, előtte kicseréljük az elválasztó karaktert, hogy mindkét esetet fel tudjuk dolgozni egyszerre.

A try blokkban konvertáljuk az adatot és minden kivételt elkapunk. Ez lekezeli azt az esetet is, hogy nincs két adat a sorban, ekkor túlcímezzük a listát, és ez is kivételt vált ki. (próbáld ki debuggerrel!) Ezután még csinálunk egy extra ellenőrzést, hogy a lista címzése biztosan jó legyen és nyilvánvalóan rossz hibás adatot is eldobjuk. Látható, hogy a (viszonylag) korrekt hibakezelés szinte a feldolgozással összemérhető mennyiségű kódot eredményezett.

HATAR= -15.0
SZENZOROK= 7
ZEROKELVIN= -273.0

legnagyobb= [ZEROKELVIN] * SZENZOROK
hibas= 0

while True: 
    sor = input()
    if sor == "":
        break
    adat= sor.replace(":",";").split(";")
    try:
        sens=int(adat[0])
        temp=float(adat[1])
    except:
        hibas+= 1
        continue
    if sens < 1 or sens > SZENZOROK or temp <= ZEROKELVIN:
        hibas+=1
        continue    
    if temp > legnagyobb[sens-1]: 
        legnagyobb[sens-1]= temp

db=0
for i in range(SZENZOROK):
    temp= legnagyobb[i]
    if temp == ZEROKELVIN: # ez a szenzor nem kuldott adatot
        continue
    print(f"{i+1}. szenzor legmelegebb hőmérséklete {temp}C")
    if temp > HATAR:
        db+=1
print(f"Összesen {db} szenzor mért {HATAR} C-nál nagyobb hőmérsékletet")
print(f"Összesen {hibas} hibás adat érkezett")

3. Kasszák

Egy áruházban 32 kassza van, 1-től számozva. A tulajdonos nyomon szeretné követni a napi forgalom adatait az egyes kasszáknál. Így minden vásárláskor egy központi gépen megjelenik a kassza sorszáma és a fizetett összeg, vesszővel elválasztva:

11,33800

Ez a 11-es kassza, 33800 Ft. Írj olyan programot, ami beolvassa ezeket az adatokat a szabványos bemenetéről, és összegzi kasszánként a bevételeket! (Záráskor üres sorral zárul az aznapi forgalom figyelése.) Írja ki az összegzés után, melyik kasszánál mekkora volt a bevétel, és hogy az az összbevétel hány százaléka! Ha egy kassza az adott napon nem üzemelt, akkor az ne jelenjen meg. A nem megfelelő formátumú sorokat külön számold meg, és a program futása végén írd ezek számát!

Tipp

Használd az előadáson megismert split() függvényt és a kivételkezelést!

4. Nyelvi statisztika

Bölcsész haverod, aki az angol nyelvvel foglalkozik, szeretné megvizsgálni a szavakban előforduló betűk gyakoriságát. Ezért megkér téged, hogy írj egy programot, amely a szabványos bemenetén egy angol nyelvű szöveget fogad. Egészen addig olvasd a szöveget soronként, amíg egy üres sort nem kapsz. A programod feladata egy statisztikát készíteni, amelyben az szerepel, hogy melyik (az egyszerűség kedvéért az angol abc betűit számoljuk csak, és kisbetű-nagybetű nem számít) betű hányszor fordult elő a szövegben, és az összes betű hány százalékát adja. A kimenete ilyen legyen:

        A: 19 db, 5.0%
        B:  7 db, 1.8%
        ...
    

Ha valamelyik betű nem szerepelt a szövegben, az ne jelenjen meg a statisztikában se! A nem betű karaktereket figyelmen kívül kell hagyni. A teljes szöveget nem szabad eltárolni!

Tipp
  • Használd az ord függvényt a karakterkód meghatározására. Ha pl. c változó az angol abc nagybetŰje, akkor igaz rá, hogy 'A' <= c <= 'Z'
  • Ha ezzel szeretnél egy 26 elemű tömböt címezni, egyszerűen vond ki az 'A' kódját, azaz pl. stat[ord(c)- ord('A')]+=1 megnöveli a stat tömb 0. elemét, amiben az 'A' betüket számoljuk. Vigyázz! Ha nem vizsgálod meg, hogy valóban nagybetű-e, túlcímezheted a tömböt!
Megoldás
betustat=[0]*26     # a 26 betunek
sor= input()
while sor != "":
    for c in sor.upper():
        if 'A'<= c <= 'Z':
            betustat[ord(c)-ord('A')] += 1
    sor=input()

ossz= sum(betustat)
if ossz != 0: # ha van legalabb 1 betu
    for i in range(len(betustat)):
        if betustat[i] != 0:
            print(f"{chr(ord('A')+i)}: {betustat[i]} db, {betustat[i]/ossz*100.0 :.1f}%")

5. További feladatok