Kalandozás a python programozás földjén.

Python, ahogy én ...

Emelt informatika érettségi 2022 május

2022. május 27. - d3c0d3r
savok = {}
with open ('utca.txt', 'rt', encoding='utf-8') as f:
    a, b, c = f.readline().strip().split(' ')
    savok['A'] = int(a)
    savok['B'] = int(b)
    savok['C'] = int(c)

 

import pandas as pd
import numpy as np
cols = ['adoszam', 'utca', 'hazszam', 'sav', 'terulet']
df = pd.read_csv('utca.txt', delimiter = ' ', skiprows = 1, names = cols, index_col = False)
df.dtypes
adoszam int64 
utca object
hazszam object
sav object
terulet int64
dtype: object

print(f"A mintában {df.shape[0]} telek szerepel.")
A mintában 543 telek szerepel.

def ado(sav, terulet, savok):
    osszeg = savok[sav] * terulet
    return 0 if osszeg < 10000 else osszeg

 

a_szam = int(input("3. feladat. Egy tulajdonos adószáma:"))
filt = (df.adoszam == a_szam)
if df[filt].shape[0] > 0:
    print(df[filt])
else:
    print(f'Nincs {a_szam} adószám az adatbázisban')
      adoszam      utca hazszam sav  terulet     ado
542    12345  Zsomboly      20   A      134  107200
df['ado'] = df.apply(lambda x: ado(x.sav, x.terulet, savok), axis=1)
df2 = df.groupby('sav')['ado'].agg(['count', 'sum'])
df2.rename(columns={'count':'Telkek száma','sum':'Fizetendő adó'}, inplace = True)
df2
   Telkek száma	Fizetendő adó
sav		
A	165	20805600
B	144	13107000
C	234	3479600
a = set(df[df.sav=='A']['utca'])
b = set(df[df.sav=='B']['utca'])
c = set(df[df.sav=='C']['utca'])

ab = a.intersection(b)
ac = a.intersection(c)
bc = b.intersection(c)

ab |= ac
ab |= bc

for utca in ab:
    print(utca)
Besztercei
Rezeda
Gyurgyalag
Szepesi
Icce
Kurta
df2 = df.groupby('adoszam').sum()['ado']
df2.to_csv('fizetendo.css', sep=' ', header=False)
df2
adoszam
10388     22000
10495     72000
10507    126000
10843     11600
10934     14400
          ...  
98489     84000
98769     72000
98791    113400
99795         0
99986    151800
Name: ado, Length: 519, dtype: int64

Érettségi 2005 (Vigenère tábla)

Feladat:

Már a XVI. században komoly titkosítási módszereket találtak ki az üzenetek elrejtésére. A század egyik legjobb kriptográfusának Blaise de Vigenère-nek a módszerét olvashatja a következőkben. A kódoláshoz egy táblázatot és egy ún. kulcsszót használt. A táblázatot a jobb oldali ábra tartalmazza. A tábla adatait a vtabla.dat fájlban találja a következő formában.

Feladat leírás: itt, forrás állományok: itt.

Megoldás:

in_tab = 'öüóőúéáűíÖÜÓŐÚÉÁŰÍ'
outtab = 'ouooueauiOUOOUEAUI'
deltab = ' ,.!?;:#()[]{}-=+*'
tab = str.maketrans(in_tab, outtab, deltab)

nyilt = input('Nyílt szöveg: ').translate(tab).upper()
print('Szöveg átalakítása: ', nyilt)

kulcs = (input('Kulcsszó: ').upper() * len(nyilt))[0:len(nyilt)]
print('Nyílt szöveg és kulcs együtt:', nyilt, kulcs, sep='\n')

with open('vtabla.dat', 'r') as f:
    vtabla = [line.strip() for line in f]

kodolt = ''
for i in range(len(nyilt)):
    sor = vtabla[0].find(kulcs[i])
    for j in range(len(vtabla)):
        if vtabla[j][0] == nyilt[i]:
            oszl = j
            break
    kodolt += vtabla[oszl][sor]

print('Kódolt szöveg:', kodolt, sep='\n')

with open('kodolt.dat', 'w') as f:
    f.write(kodolt)
print('Kódolt szöveg fájlba írása: kodolt.dat')

Érettségi 2008 (SMS)

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, amelynek 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.

Feladat leírás: itt, forrás állományok: itt.

Megoldás:

from datetime import time, timedelta
from collections import Counter

kategoria = ['1-20', '21-40', '41-60', '61-80', '81-100']

class Sms:
    def __init__(self, ora, perc, tel, szoveg):
        self.ido = time(int(ora), int(perc))
        self.tel = tel
        self.szoveg = szoveg
        self.hossz = len(szoveg)
        self.d_ido = timedelta(hours=int(ora), minutes=int(perc))

    def ir(self, txt=''):
        print(txt, self.ido, self.tel, self.szoveg)

    def __str__(self):
        return '\n '+str(self.ido)[:5]+ ' ' + self.szoveg + ' '


smsek = []
mem = 10
with open('sms.txt') as f:
    x = f.read().split('\n')
    for i in range(1, len(x) - 1, 2):
        s = x[i].split()
        smsek.append(Sms(s[0], s[1], s[2], x[i + 1]))

print('2. feladat\nA legfrissebb üzenet: ', smsek[mem - 1].szoveg)

min(smsek, key=lambda v: v.hossz).ir('3. feladat\nA legrövidebb üzenet:')
max(smsek, key=lambda v: v.hossz).ir('A leghosszabb üzenet:')

print('4. feladat')
c = Counter((sms.hossz - 1) // 20 for sms in smsek)
[print(f'{kategoria[i]:>6}: {c[i]:<}') for i in range(len(c))]

print('5. feladat')
x = Counter([sms.ido.hour for sms in smsek])
print(f'A szolgáltatót {sum([i-mem for i in x.values() if i > mem])} SMS miatt kell felhívni.')

print('6. feladat')
x = [sms.d_ido for sms in smsek if sms.tel == '123456789']
print('Nincs elég adat.') if len(x) == 0 else print('Leghosszabb időtartam:', max(x[i+1] - x[i] for i in range(len(x) - 1)))

print('7. feladat')
smsek.append(Sms(input('Óra: '), input('Perc: '), input('Telefon: '), input('Szöveg: ')))

print('8. feledat', end=' -> ')
with open('smski.txt', 'w') as f:
    x = sorted(smsek, key=lambda v: v.tel)
    prev = x[0]
    f.write(prev.tel + str(prev))
    for c in range(1, len(x)):
        if x[c].tel != prev.tel:
            f.write('\n' + x[c].tel)
            prev = x[c]
        f.write(str(x[c]))

print('kész!')

Képből Excel tábla

Feladat:

Egy adott kép pixeljeinek megjelenítése egy Excel táblában. Az ötlet az index.hu-n megjelent cikkből származik, annyi módosítással, hogy az adott mappa összes képéből ('.jpg', '.jpeg', '.bmp', '.tif', '.tga') excel tábla készül, és ha a kép túl nagy, akkor 400x400-as lesz a munkafüzet.

2_1.jpg

1.jpg

 

Megoldás:

from PIL import Image
import xlsxwriter
import os

temp_image = '__temp_image'
temp_size = (400, 400)
image_files = ('.jpg', '.jpeg', '.bmp', '.tif', '.tga')

for f in os.listdir('.'):
    if f.endswith(image_files):
        fn, fext = os.path.splitext(f)
        img = Image.open(f)
        wb = xlsxwriter.Workbook(fn + '.xlsx')
        ws = wb.add_worksheet()
        ws.set_column('A:OJ', 1)
        ws.set_default_row(10)
        ws.center_horizontally()
        ws.center_vertically()
        ws.hide_gridlines()
        ws.set_zoom(15)
        ws.fit_to_pages(1,1)

        if max(img.size) > 400:
            img.thumbnail(temp_size, Image.ANTIALIAS)
            img.save(temp_image+fext)
            img = Image.open(temp_image+fext)

        width, height = img.size
        pixels = list(img.getdata())
        pixels = [pixels[i * width:(i + 1) * width] for i in range(height)]
        row, col = 0, 0
        print(f'Generating file {fn:>15}.xlsx -> ', end=' ')
        for sor in pixels:
            for t in sor:
                color = '#%02x%02x%02x' % t if img.mode != 'L' else '#%02x%02x%02x' % (t, t, t)
                cf = wb.add_format()
                cf.set_bg_color(color)
                ws.write_string(row, col, '', cf)
                col += 1
            row += 1
            col = 0
        if os.path.exists(temp_image+fext):
            os.remove(temp_image+fext)
        wb.close()
        print('done!')

Érettségi 2005 (Lottó)

Feladat:

Magyarországon 1957 óta lehet ötös lottót játszani. A játék lényege a következő: a lottószelvényeken 90 szám közül 5 számot kell a fogadónak megjelölnie. Ha ezek közül 2 vagy annál több megegyezik a kisorsolt számokkal, akkor nyer. Az évek során egyre többen hódoltak ennek a szerencsejátéknak és a nyeremények is egyre nőttek.

Feladat leírás: itt, forrás állományok: itt.

Megoldás:

def prim(a):
    return all(a % i for i in range(2, int(a ** 0.5) + 1))

huzasok = {}
with open('lottosz.dat') as f:
    for i, l in enumerate(f):
        huzasok[i + 1] = list(map(int, l.split()))

szamok = [v[i] for v in huzasok.values() for i in range(5)]

het_52 = sorted(list(map(int, input('52. hét számai (szóközzel elválasztva): ').split())))
print(het_52)

print(huzasok[int(input('Melyik hét számaira kiváncsi: '))])

print('Van ki nem húzott szám!') if len(set(szamok)) < 90 else print('Nincs ki nem húzott szám!')

print(f'Páratlan számot {len([szam for szam in szamok if szam % 2 != 0])}-szor húztak ki.')

huzasok[52] = het_52
szamok += het_52

with open('lotto52.ki', 'w') as f:
    for het in huzasok.values():
        f.write(' '.join(map(str, het)) + '\n')

szam_stat = [szamok.count(i) for i in range(1, 91)]
print('\nSzámok gyakorisága:')
for i in range(1, 91):
    print(szam_stat[i - 1], end=' ')
    if i % 15 == 0:
        print('\n')

print('Ki nem húzott prímszámok: ', set(i for i in range(2, 91) if prim(i)) - set(szamok))

Érettségi 2019 (Cégautók)

Feladat:

Egy cég 10 olyan autóval rendelkezik, amelyet a dolgozók igénybe vehetnek az üzleti ügyeik intézésére. Az autókat akár többnapos útra is elvihetik, illetve egy autót egy nap több dolgozó is elvihet. A rendszer az autók parkolóból való ki- és behajtását rögzíti. A parkoló a hónap minden napján 7-23 óra között van nyitva, csak ebben az időszakban lehet elvinni és visszahozni az autókat. Az autót mindig annak a dolgozónak kell visszahoznia, amelyik elvitte. Egyszerre csak egy autó lehet minden dolgozónál. Az autok.txt fájl egy hónap (30 nap) adatait rögzíti. Egy sorban szóközökkel elválasztva 6 adat található az alábbi sorrendben.

Folytatás: Leírás és forrásanyagok

Megoldás:

Biztos van egyszerűbb megoldás is, de hirtelen felindulásból erre futotta. :)

class Auto:
    def __init__(self, nap, ido, rendszam, szemely, km, irany):
        self.nap = nap
        self.ido = ido
        self.rendszam = rendszam
        self.szemely = szemely
        self.km = km
        self.irany = 'ki' if irany == '0' else 'be'

gr = []

# 1. feladat
with open('autok.txt') as f:
    for line in f:
        l = line.strip().split()
        gr.append(Auto(int(l[0]), l[1], l[2], l[3], int(l[4]), l[5]))

print('\n2. feladat')
x = [x for x in gr[::-1] if x.nap == 30 and x.irany == 'ki'][0]
print(f'30. nap rendszám: {x.rendszam}')

print('\n3. feladat')
nap = int(input('Nap: '))
print('Forgalom a(z) {nap}. napon:')
[print(x.ido, x.rendszam, x.szemely, x.irany) for x in gr if x.nap == nap]

print('\n4. feladat')
ki = [x.irany for x in gr].count('ki')
print(f'A hónap végén {ki - (len(gr) - ki)} autót nem hoztak vissza.')

print('\n5. feladat')
d = {}
for x in gr:
    if x.rendszam in d:
        d[x.rendszam].append(x.km)
    else:
        d[x.rendszam] = [x.km]
for k in sorted(d.keys()):
    print(k, max(d[k]) - min(d[k]), 'km')

print('\nHatodik feldat')
d = {}
for i in range(1, 31):
    n = [x for x in gr if x.nap == i]
    for m in n:
        if m.szemely in d:
            d[m.szemely].append([m.rendszam, m.km])
        else:
            d[m.szemely] = [[m.rendszam, m.km]]

sofor = {}
for k, v in d.items():
    v = v[::-1]
    sofor[k] = 0
    for i in range(len(v) % 2, len(v), 2):
        sofor[k] = max(sofor[k], v[i][1] - v[i + 1][1])

m = (sorted(sofor, key=sofor.get))
print(f'A leghosszabb út: {sofor[m[-1]]} km, személy: {m[-1]}')

print('\n7. feladat')
r = input('Rendszám: ').upper()
auto = [x for x in gr if x.rendszam == r]
sz = auto[0]
with open(r + '_menetlevel.txt', 'w') as f:
    f.write(sz.szemely + '\t')
    for k in range(1, len(auto) + 1):
        try:
            f.write(f'\t{sz.nap}.\t{sz.ido}\t{sz.km}\t')
            if auto[k].szemely != sz.szemely:
                f.write(f'\n{auto[k].szemely}\t')
            sz = auto[k]
        except IndexError: # ha nem hozták vissza
            pass

Római számok

Feladat:

Írjunk függvényt, ami a paraméterként megadott római számot arab számként adja vissza!

Megoldás:

def roman(r):
    r_nums = {'M': 1000, 'D': 500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1}
    num = 0
    prev_num = -1
    for n in r[::-1]:
        if prev_num <= r_nums[n]:
            num += r_nums[n]
        else:
            num -= r_nums[n]
        prev_num = r_nums[n]
    return num


print(roman('MMI'))         # => 2001
print(roman('XXI'))         # => 10
print(roman('MCMXVI'))      # => 1916
print(roman('XC'))          # => 90
print((roman('MCMLXV')))    # => 1965

Pascal-háromszög

Feladat:

Pascal-háromszög a matematikában a binomiális együtthatók háromszög alakban való elrendezése. A nyugati világ nagy részén Blaise Pascalról nevezték el, noha egyes indiaiperzsakínai és itáliai matematikusok már évszázadokkal Pascal előtt tanulmányozták.

via

Megoldás:

def make_next_row(row):
    result = []
    prev = 0
    for e in row:
        result.append(prev + e)
        prev = e
    result.append(prev)
    return result


def triangle(n):
    result = []
    current = [1]
    for i in range(0, n):
        result.append(current)
        current = make_next_row(current)
    return result


[print(row) for row in triangle(10)]

met.hu időjárás

Feladat:

Győr egy heti hőmérsékleti adatainak kinyerése a met.hu honlapról. A program futásához szükséges a selenium könyvtár illetve a chromedriver telepítése.

Megoldás:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import os

BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END, BOLD, REVERSE = '\33[94m', '\033[91m', '\33[97m', '\33[93m', '\033[1;35m', '\033[1;32m', '\033[0m', '\033[;1m', '\033[;7m'

logo = '''
::::    :::: :::::::::::::::::::::     :::    ::::::    ::: 
+:+:+: :+:+:+:+:           :+:         :+:    :+::+:    :+: 
+:+ +:+:+ +:++:+           +:+         +:+    +:++:+    +:+ 
+#+  +:+  +#++#++:++#      +#+         +#++:++#+++#+    +:+ 
+#+       +#++#+           +#+         +#+    +#++#+    +#+ 
#+#       #+##+#           #+#    #+#  #+#    #+##+#    #+# 
###       #############    ###    ###  ###    ### ########        
'''
print(BLUE,logo,END)
if os.name == 'nt':
    driver = webdriver.Chrome()
else:
    driver = webdriver.Chrome('/home/molla/chromedriver')

# driver.set_window_size(0, 0)
driver.get('http://www.met.hu/idojaras/elorejelzes/magyarorszagi_telepulesek/main.php')

telep = driver.find_element_by_id('tags')
telep.send_keys('Győr'+Keys.ENTER)

table = driver.find_element_by_class_name('meteogram')
ths = table.find_elements_by_class_name('m-idoful')
maxs = table.find_elements_by_css_selector('tr.hmax>td')
mins = table.find_elements_by_css_selector('tr.hmin>td')

for i in range(0,len(maxs)):
    print('\t{:<22} {}{:2}°C{} - {}{:<2}°C{}'.format(ths[i].text.replace('\n',' '), BLUE, mins[i].text, END, RED, maxs[i].text, END))

driver.close()

Háromszögszámok

Feladat:

háromszögszámoknak nevezik a matematikában azokat a számokat, amelyek előállnak az első valahány egymást követő természetes szám összegeként. A sokszögszámok közé tartoznak. Nevüket onnan nyerték, hogy kavicsokkal vagy más módon kirakva őket, szabályos háromszög alakba rendezhetőek.

via

Megoldás:

def triangular(n):
    return sum([x for x in range(1, n + 1)])


def rekurziv_triangular(n):
    return n if n < 2 else n + rekurziv_triangular(n - 1)


print(triangular(100))

print(rekurziv_triangular(100))
süti beállítások módosítása