3. hét: sztringműveletek

Czirkos Zoltán, Frey Balázs, Bulla Ádám · 2019.09.26.

Sztringekkel végzett műveletek. Sztringek beolvasása, darabolása, feldolgozása karakterenként.

1. Mindentegybevéve

Írj egy olyan programot, mely egy szövegből kiszedi a szóközöket!

Ennek megoldása – megoldási ötlete – kelleni fog a következő feladathoz.

Megoldás
szoveg = "H e l l o, vilag!"
spacenelkul = ""
for i in szoveg:
    if i != ' ':
        spacenelkul += i

print(spacenelkul)

2. Palindrom I.

Írj programot, amelyik eldönti egy szóról, hogy palindrom-e! Például az „abba” és a „görög” ilyenek: visszafelé olvasva ugyanazt a szót kapjuk.

3. Palindrom II.

Írj programot, amelyik egy mondatról eldönti, hogy palindrom-e. Közismert magyar nyelvű palindrom mondat az „Indul a görög aludni.” Ez abban különbözik az előző feladattól, hogy most a szóközöket és az írásjeleket ki kell szűrnöd, vagyis csak a betűket kell megtartani, és úgy kell vizsgálni a sztringet. És persze figyelni arra is, hogy a kisbetűk és a nagybetűk nem különböznek.

Megoldás

Első lehetőség: hibát keresünk a sztringben (van-e benne hiba: eldöntés tétele). Vagyis olyan betűpárt, aminek egyeznie kellene, de nem egyezik. Ehhez elmegyünk a sztring közepéig, és minden karaktert összehasonlítunk azzal, amelyik a végétől visszafelé számítva ugyanolyan kellene legyen.

szo = "görög"

hibas = False
index = 0
hossz = len(szo)
while index < hossz / 2 and not hibas:
    if szo[index] != szo[hossz - 1 - index]:
        hibas = True
    index += 1

if hibas:
    print("Nem palindrom")
else:
    print("Palindrom")

Másik lehetőség, hogy megépítjük a fordított sztringet, és összehasonlítjuk az eredetivel:

szo = "abcd"

forditva = ""
for c in szo:
    forditva = c + forditva     # a, ba, cba, dcba

if szo == forditva:
    print("Palindrom")
else:
    print("Nem palindrom")
Tipp

Érdemes előállítani a sztringnek egy olyan kisbetűsített változatát, amiben semmi nem marad meg a betűkön kívül – vagyis eltűnnek a szóközök és az írásjelek is. Betű-e – nézz szét a sztring típus függvényei között!

Megoldás
szoveg = "Indul a görög aludni."

csakbetuk = ""
for i in szoveg:
    if i.isalnum():
        csakbetuk += i.lower()

hibas = False
index = 0
hossz = len(csakbetuk)
while index < hossz / 2:
    if csakbetuk[index] != csakbetuk[hossz - 1 - index]:
        hibas = True
        break
    index += 1

if hibas:
    print("A megadott szó nem palindrom!")
else:
    print("A megadott szó palindrom!")

A fordított szöveg vizsgálata így is elvégezhető (előadáson nem szerepelt):

if csakbetuk != csakbetuk[::-1]:
    print("A megadott szöveg nem palindrom!")
else:
    print("A megadott szöveg palindrom!")

4. Madárnyelv

Írj programot, amely madárnyelven (mavadávárnyevelveven) írja ki a beírt szöveget! Ezt azt jelenti, hogy minden magánhangzó után tesz egy v-t is, és megismétli a magánhangzót. Pl. te → teve, ma → mava, labor → lavabovor.

Valósítsd meg ezt úgy, hogy a beolvasott sor alapján egy új sztringet állítasz elő, és végül azt írod ki! Használd a tanult sztringműveleteket!

Megoldás
beirt = input()

madar = ""
for c in beirt:
    madar += c
    cl = c.lower()
    if cl == 'a' or cl == 'e' or cl == 'i' or cl == 'o' or cl == 'u':
        madar += 'v' + c.lower()

print(madar)

Persze a magánhangzók vizsgálata megoldható másképp is, például:

    if "aeiou".find(c.lower()) != -1:

Kicsit előreszaladva az in operátorhoz, amely az előadáson majd szerepel, akár így is:

    if c.lower() in "aeiou":

5. Trimmer

Gyakori feladat, hogy egy sztring elejéről és végéről el kell távolítani a szóközöket. Ezt a függvényt gyakran trim-nek vagy strip-nek szokták hívni. Pythonban is van ilyen: " helló világ ".strip() értéke "helló világ".

A feladatod megírni ezt az algoritmust, hogy megértsd a működését! Írj olyan programot, ami kér egy szöveget, és eltávolítja annak elejéről és végéről a szóközöket. Írd ki utána idézőjelek között a vágott sztringet!

Ha elkészültél, ellenőrizd, működik-e a programod olyan sztringre, ami csak szóközt tartalmaz, vagy esetleg eleve teljesen üres! Ha nem, javítsd ki!

Megoldás

A sztring végének kezelésénél jobban kell ügyelni. str[len(str)] már nem indexelhető, és a vágásnál is jobbról (végén) nyílt intervallumot kell megadni. A mintamegoldásban az eleje és vege változók azokra az indexekre állnak be a sztring elején és végén, ahol nem szóköz van; a vágásnál ezért vege+1-et kell írni.

szoveg = input("Írj be egy szöveget: ")

eleje = 0
while eleje < len(szoveg) and szoveg[eleje] == ' ':
    eleje += 1

vege = len(szoveg)-1
while vege >= 0 and szoveg[vege] == ' ':
    vege -= 1

vagott = szoveg[eleje:vege+1]
print('"{}"'.format(vagott))

Mi történik, ha az első ciklus feltételeit megfordítod? Miért?

Sok programozási nyelv a logikai műveleteknél nem ragaszkodik mindkét feltétel kiértékeléséhez, amennyiben az első után egyértelműen eldönthető, hogy az igaz vagy hamis lesz. Ha egy ÉS kapcsolatban az első feltétel hamis, a második értéke nem befolyásolja a végső eredményt, biztos, hogy hamis lesz. Ugyanez VAGY kapcsolatnál, amennyiben az első feltétel igaz. Ekkor a második feltétel kiértékelése nélkül meg tudjuk állapítani, hogy végül igaz eredményt kapunk. Erről még lesz szó előadáson.

6. Gipsz Jakab

A feladat: megcserélni egy névben a keresztnevet és a vezetéknevet, és az eredményt egy másik sztringben előállítani.

eredeti = "Gipsz Jakab"

... itt bármit csinálhatunk...

print("|" + forditott + "|")    # |Jakab Gipsz|
Megoldás

Első megoldás: vágással. Megkeressük a szóközt, és utána ott „megfelezzük” a sztringet.

szokoz = 0
while eredeti[szokoz] != ' ':
    szokoz += 1

forditott = eredeti[szokoz+1:] + ' ' + eredeti[:szokoz]

A szóköz megkereséséhez akár az eredeti.find(' ') kifejezést is használhatnánk.

Második megoldás: a sztringek .split() függvényével. Ez a megadott karakter mentén darabokra vágja a sztringet, és a darabokat egy listába teszi.

darabolt = eredeti.split(' ')
forditott = darabolt[1] + ' ' + darabolt[0]

7. SpONgEBob MOcKiNG MeMe

Írj programot, amelyik a beírt sorból olyan sztringet állít elő, amelyben VÉletLEnszErŰeN VÁLtAkoZnAK a kis- és nagybetűk! Használd az előadáson tanult sztringműveleteket!

Pythonban véletlenszámot a random modul (import random) egyik függvényével tudsz létrehozni. Ennek neve: random.randint(). Paramétere egy alsó és egy felső határ; random.randint(0, 1) véletlenszerűen 0-t vagy 1-et ad.

Tipp

Figyelj a feladatkiírás pontos értelmezésére: nem csak SpoNGyaBobOSAn kiírni kell a sztringet, hanem egy új sztringet kell előállítanod egy változóban, amely ilyen formában tartalmazza a szöveget!

Logikus lenne arra gondolni, hogy a beolvasott sztring karaktereit módosítod, de ilyet nem tudsz csinálni Pythonban: a sztring egyes karakterei nem írhatók felül. Egy üres sztringet kell létrehoznod, és ahhoz hozzáfűzni a karaktereket kisbetűsítve vagy nagybetűsítve.

Megoldás
import random

line = input()

mocking = ""
for ch in line:
    if random.randint(0, 1) == 0:
        mocking += ch.upper()
    else:
        mocking += ch.lower()

print(mocking)

Hasonló feladatok

Ha a fenti feladatok nehezen mentek, megoldhatsz pár hasonló feladatot a példatárból, mielőtt a következő feladatra rátérsz.

Vigyázz, a laborfeladatokat erősen ajánlott az utolsó feladatig megoldani, hogy a jövő hétre felkészült legyél. Ha nem sikerül, fejezd be őket otthon!

8. A beírt szavak

Készíts programot, amelyik szavakat kér a felhasználótól, és hozzáfűzi őket egy listához! A beolvasás álljon meg akkor, ha üres sort kap.

Írj be szavakat, majd jelezd üres sorral a lista végét!
alma
körte
barack

Ha megvan mind, írd ki a beírt szavakat vesszővel elválasztva! Ügyelj arra, hogy ne legyen sehol felesleges szóköz vagy vessző, és legyen pont a mondat végén! Ehhez nem lesz elég a print(lista), mert az egész más formátumban írja ki az adatokat.

A beírt szavak: alma, körte, barack.
Tipp

Végjeles vagy előre adott hosszúságú sorozatról van szó? Mit jelent ez, hogy „a beolvasás üres sornál áll meg”? Hogy jelenik meg ez a ciklusfeltételben?

Megoldás

A beolvasásnál: érdemes egy szót előre beolvasni külön. Akkor már értelmezhetővé válik a ciklusfeltétel.

A kiírásnál: az első szót külön kell kezelni, mert az elé nem kell vesszőt írni. Vagy esetleg elágazást kell tenni a ciklusba, amely vesszőt ír ki (ha nem az utolsó szóról van szó) vagy pontot ír ki (ha az utolsóról).

print("Írj be szavakat, majd jelezd üres sorral a lista végét!")
szavak = []
szo = input() # !
while szo != "":
    szavak.append(szo)
    szo = input()

if len(szavak) == 0:
    print("Nem írtál be semmit")
else:
    print("A beírt szavak: ", end="")
    print(szavak[0], end="") # !
    i = 1
    while i < len(szavak):
        print(", " + szavak[i], end="")
        i += 1
    print(".")

9. Lista léptetése

P i t a g o r a s z
i t a g o r a s z P
t a g o r a s z P i
a g o r a s z P i t
g o r a s z P i t a
o r a s z P i t a g
r a s z P i t a g o
a s z P i t a g o r
s z P i t a g o r a
z P i t a g o r a s

Írj egy programot, amely létrehoz egy tízelemű, sztringekből álló listát! Ebben egyetlen karakterből álló sztringek legyenek, bennük Pitagorasz nevének betűível: 'P', 'i' és így tovább. Írja ki a program ezt a listát a képernyőre, a betűket szóközökkel elválasztva!

Léptesd a lista összes elemét eggyel az eleje felé! A lista egyik végén kilépő elem jöjjön be a túlsó végén. Ismételd meg ezt a műveletet tízszer, közben mindig írd ki a listát! Az eredmény a jobb oldalon láthatóhoz hasonló kell legyen.

Vigyázz, nem az a feladat, hogy egy trükkös kiírást csinálj! A listát kell úgy megváltoztatni, hogy elmozduljanak benne az elemek. A kiírásnak mindig a lista elejétől a végéig kell haladnia, minden sorban. A kód felépítése tehát ez kell legyen:

CIKLUS 10-szer

    CIKLUS a kiírásához...  itt csak printek vannak, nem változik a lista

    CIKLUS a léptetéshez... itt változik a lista, és nincsenek printek

CIKLUS VÉGE
Tipp

Egyetlen listára van csak szükség, másikat nem kell létrehozni! Az első felülírható a másodikkal, a második a harmadikkal… Kérdés, az utolsó helyre ilyenkor mi kerül. Rajzold le, és gondold végig úgy, minek kell történnie!

Megoldás

A léptetésnél az elsőt félretesszük, aztán az egészet balra húzzuk, végül pedig a félretett elemet betesszük a végére. A ciklus azért rövidebb, mert [i + 1] indexelés is van benne!

lista = ['P', 'i', 't', 'a', 'g', 'o', 'r', 'a', 's', 'z']

# 10-szer
for _ in range(10):

    # kiírás
    for c in lista:
        print(c, end=" ")
    print()
    
    # léptetés
    temp = lista[0]
    for i in range(0, len(lista) - 1):
        lista[i] = lista[i + 1]
    lista[len(lista) - 1] = temp

Másik lehetőség: pop()-oljuk a nulladikat, aztán append()-eljük a végére:

lista = ['P', 'i', 't', 'a', 'g', 'o', 'r', 'a', 's', 'z']

for _ in range(10):
    for c in lista:
        print(c, end=" ")
    print()
    
    temp = lista.pop(0)
    lista.append(temp)

A karaktereket tartalmazó lista egyébként megépíthető így is:

karakterek = lista("Pitagorasz")

Ez azért működik, mert bármi, amin for ciklus használható, az listává is konvertálható egyesével. A sztring pont ilyen. Később erről lesz szó.

10. Caesar-féle kódolás

A Caesar-féle kódolás lényege, hogy a titkosítandó szövegben minden betű helyett ábécében a következőt vesszük. Így lesz az „barack” szóból „cbsbdl”: b→c, a→b, r→s és így tovább.

Írj programot, amelyik beolvas egy szót, és kiírja a titkosított változatát! Csak az angol ábécé kisbetűs karaktereivel kell foglalkozni, minden más maradjon változatlanul. A „z” betűből legyen „a” betű!

Tipp

Az ord() függvénnyel lehet lekérdezni a karakterkódot. Pl. a kis „a” betűnél ez 97, hozzáadva egyet 98-at kapunk, ami meg pont a „b” betű kódja. Ezt megadja a chr() függvény.

11. Szorgalmik

Ha mindennel elkészültél, dolgozhatsz a szorgalmi feladatokon is. Ezek plusz pontért küldhetők be.