Ahogy a természetes nyelveknél a készségszintű tudáshoz csak a rendszeres aktív gyakorlás vezet, ugyanez igaz a programozási nyelvek tanulására is. Nem elég csak olvasni a nyelv szabályait és kész kódokat, hanem írni is kell azokat, minél többet. Nyilván, ha valakinek ez a foglalkozása, akkor ez megvalósul, de azoknak, akik a nyelvet tanulják és olyan a napi elfoglaltságuk, hogy nem kell újabb és újabb programot fejleszteni, azoknak ajánlatos, hogy maguk találjanak ki feladatokat és oldják meg programmal.
Először mindig célszerű egyszerű dolgokkal kezdeni, hogy a megoldás sikerélménye az egyre nehezebb feladatok kódolására ösztönözzön. Ha más nem jut eszünkbe, akkor jó módszer viszonylag egyszerű megoldandó feladatnak, ha megpróbáljuk a Python által készen nyújtott függvények, metódusok vagy osztályok saját készítésű változatát létrehozni. A cél tehát az, hogy funkcionálisan ugyanazt valósítsa meg a mi definíciónk, mint a készen rendelkezésre álló. Meg fogjuk látni, hogy mennyi minden tanult ismeretet kell ilyenkor is már hasznosítani, ami ezáltal aktívvá teszi a tanultakat, és a szinte elkerülhetetlen hibázások, és azok javítása ezt csak tovább mélyítik.
Ennek szellemében gyakorlásképpen utánozzuk le mondjuk a karakterláncokra meghívható find() és count() metódusokat, vagyis írjunk egy-egy függvényt, amelyek ugyanazt tudják, mint ezek a metódusok. Azt, hogy ezek a metódusok pontosan mit csinálnak, milyen argumentumokat fogadnak és mi a visszatérési értékük a Python hivatalos dokumentációjában, vagy magyarul és kicsit bővebben kifejtve a Python tudásépítés lépésről lépésre című e-könyvben példákkal együtt megtalálható.
De röviden összegezve:
Ha egy szöveg nevű változó egy karakterláncot tartalmaz, akkor a szöveg.find(sub, start, end) metódus a sub argumentumban megadott karaktersorozat első előfordulásának indexével tér vissza, vagy ha nem található a szövegben a sub, akkor -1 lesz a visszaadott érték. A start és end paraméterekkel a keresést korlátozhatjuk a kezdő és vég indexek közé.
A szöveg.count(sub, start, end) metódus a find()-hoz hasonló argumentumokat fogad, és a visszatérési értéke, a sub adott kezdő és végindex közötti előfordulásainak a száma.
Mivel a start és end paramétereknek negatív indexet is meg lehet adni, a saját függvényeink készítéséhez nem árt, ha visszaidézzük, hogy sorozatokra hogyan működik a negatív indexelés. Ebben segít az alábbi ábra.

A következő kódsorokban a megvalósított find() és count() függvények definícióit látjuk. A kommentek segítik a működés megértését.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
def find(s: str, sub: str, start=None, end=None): # Meghatározzuk a nemnegatív kezdő- és végindexeket. k = (start if start >= 0 else len(s) + start) if start is not None else 0 v = (end if end >= 0 else len(s) + end) if end is not None else len(s) - len(sub) # Végighaladunk az indexeken a kezdőtől a végig. for i in range(k, v): # A karakterlánc aktuális indexpoziciójától képezzük a keresett karaktersorozat # méretével azonos szeletet, feltéve, hogy a szelet vége nem nyúlik túl a végindexen. szelet = s[i:min(i + len(sub), v)] # Ha a szelet megegyezik a keresett karaktersorozattal, akkor visszatérünk az # aktuális indexszel. if szelet == sub: return i # Ha a karaktersorozatban a megadott indextartományban nem volt a keresett # karaktersorozattal egyező részlet, akkor a -1 értékkel térünk vissza. return -1 def count(s: str, sub: str, start=None, end=None): # Meghatározzuk a nemnegatív kezdő- és végindexeket. k = (start if start >= 0 else len(s) + start) if start is not None else 0 v = (end if end >= 0 else len(s) + end) if end is not None else len(s) - len(sub) darabszám = 0 # Ez a változó tartja nyilván, hogy találat volt. # Addig keresünk a kezdő- és végindex között, amíg megtalálható a keresett # karaktersorozat. A kereséshez felhasználjuk a saját készítésű find() függvényt. i = k # A keresés kezdőindexét beállítjuk a megadott tartomány kezdetére. while (i := find(s, sub, i, v)) != -1: # Ha van találat, akkor eggyel növeljük a találatszámlálót. darabszám += 1 # A keresés kezdőindexét szintén növeljük eggyel, hogy megtalálhassuk a # következő előfordulást. i += 1 return darabszám # TESZT szöveg = 'abcdef_dehi_depq' keresett = 'de' for k, v in [(None, None), (3, None), (4, None), (5, None), (8, None), (-7, None), (None, 4), (None, 5), (None, 8), (None, 20), (5, -7)]: if szöveg.find(keresett, k, v) != find(szöveg, keresett, k, v): print('Eltérés a találati indexekben.') if szöveg.count(keresett, k, v) != count(szöveg, keresett, k, v): print('Eltérés a találati számban.') # Eredmény: nincs hibaüzenet kiírás, vagyis a saját készítésű függvények helyesen működnek. |
A függvénytörzs kódja egyik esetben sem túl bonyolult, mégis számos dolgot, nyelvi elemet és szerkezetet kell még ilyen esetben is ismerni, hogy előállítsuk a megfelelő kódot: használtunk feltételes kifejezést, for- és while-ciklust, értékadó kifejezést, feltételes elágazást, szeletképzést és kiterjesztett értékadást. De mindenekelőtt el kell gondolkodni a feladat megoldási módján, algoritmusán. Valójában ez határozza meg, hogy milyen nyelvi eszköztárat vetünk be a probléma megoldásához.
A függvényeink működését úgy teszteljük le, hogy bizonyos kezdő- és végindexet megadva összevetjük a visszatérési értéküket a megfelelő metódus visszatérési értékével. Ha ezek eltérnek, akkor hibás a függvényünk, amiről üzenetet jelenítünk meg. Jelen esetben a tesztadatokra nem kaptunk hibajelzést, ezért úgy tűnik, hogy a függvényeink az elvárások szerint működnek.