Modulok

Modulok használata

A modul első megközelítésben egy fájl, mely Python definíciókat, utasításokat tartalmaz. A fájl neve = a modul neve .py kiterjesztéssel. Modulon belül a modul nevét a __name__ változó tartalmazza. Természetesen mi magunk is tudunk írni modulokat, amelyeket mások is használhatnak.

Import

Ha telepítettük a Pythont, a bépített modulokat is megkapjuk. Ezeket egyszerűen tudjuk importálni, sőt sokat közülük már használtunk is.

A sys egy beépített modul, a rendszerrel kapcsolatos információkat tudjuk lekérdezni és használni (pl. parancssori argumentumok). Fent a sys.path változót irattuk ki, mely azon könyvtárak listája, ahol pl. a Python a modulokat keresi. Az import valami sor végrehajtásakor a Python a valami nevű modult először a beépített modulok között keresi, majd egy valami.py nevű fájlt keres a sys.path helyek egyikén. A sys.path akár változtatható is.

Létrehozhatjuk modulok úgynevezett csomagjait (packages), amelyek egy könyvtárstruktúrába szervezett fájlokból állnak (ld. a témáról bővebben: https://docs.python.org/3/tutorial/modules.html) Importálni lehet egy egész fájlt, azaz egy egész modult, egy részmodult, vagy akár ezeknek egy vagy több függvényét. A következő betöltési módok a leggyakoribbak:

import <modul>
import <modul> as <name>
from <modul> import <identifier>
from <modul.identifier> import <identifier>

Például:

Relatív import

Importálhatunk fájlokat abból a könyvtárból, ahol éppen vagyunk, ahonnan a Python, ill. a jupyter fut. Írjuk a következő kódot egy myfns.py nevű fájlba:

def foo():
    print("FoO")

def bar():
    print("BaR")

Ezután, betölthetjük őket az

import myfns

paranccsal, vagy csak egy függvényt a

from myfns import foo

paranccsal. A függvények elérése függ a betöltés módjától:

numpy alapok

A numpy numerikus számításokra tervezett Python modul. (Ha otthon szeretnénk használni, akkor az Anaconda ezt is tartalmazza mindhárom oprendszeren. Telepítés után keressünk egy szimpatikus mappát, ahova dolgozni szeretnénk, majd adjuk ki a jupyter notebook parancsot Windows command line-ban, illetve Linux parancssorban.)

Először importáljuk a numpy modult. Érdemes import numpy as np módon használni, hiszen ilyenkor numpy helyett elég az np.

A numpy legfontosabb összetevője az array, ami listák listájából 2D, listák listájánal listájából 3D... tömböt kreál (Python lista szteroidokon). A másik az arange, ami a range-hez hasonlóan működik, de azonnal tömböt hoz létre. Ez átméretezhető egy tömbbé a reshape függvénnyel:

A numpy.ndarray típusú változókon végezhetünk műveleteket, sőt, az alapműveletek többsége működik, de az ökölszabály az, hogy elemenként értelmezzük őket.

Hasonlóan lista és egy elem között is értelmezzük az alapműveleteket. Ilyenkor a lista minden elemére elvégezzük a műveleteket és az eredmény ez a lista.

Az előzőekből szinte kikövetkeztethető, hogy a mátrixszorzás sem a * művelettel történik, helyette a @ művelet vagy a .dot metódus használható:

A Python indexelési lehetőségei mellett további kényelmes megoldások is használhatók:

Sőt, indexelhetünk oszlopszinten is.

Függvényeket is hívhatunk elemenként. Sőt, a listaműveletek is elérhetők, persze np előtaggal, hiszen array típusra a normál Python függvények nem működnek. Átlagot, szórást is egy sorban számolhatunk.

A mátrixalapú nyelvek (Octave, Matlab) több parancsa itt is megjelenik: működik a zeros és a ones, az identikus mátrix az eye mögött rejtőzik (I, ejtsd áj, eye ejtsd áj).

Véletlen számokat, sőt véletlen vektorokat vagy mátrixokat is generálhatunk. Itt a $[0,1)$ intervallumból egyenletes eloszlás szerint:

Mindig ugyanazt a sorozatot generálja, ha előtte beállítjuk a seed értékét:

Egészek sorozata is generálható, például kockadobások:

Plot

Függvények ábrázolására a matplotlib csomagot használjuk. A matplotlib használatának módja változtatható a %matplotlib ún. magic függvénnyel. (A magic függvények az IPython függvényei, melyekkel a környezet viselkedése kezelhető, ezek egy részét a jupyter is használja.)

Először egy egyszerű plot.

Látjuk, hogy nem szinbolikusan számol, hanem egyszerűen összeköti a számokat vonalakkal. Szinuszgörbét is hasonlóan rajzolunk. Az np.sin a lista minden elemére számol szinuszt. Itt az arange helyett inkább a linspace függvényt használjuk, mely adott intervallumon helyez el adott számú osztópontot:

És a végére egy kis Monte–Carlo-módszer. Generálunk véletlen pontokat a $[-2,2]\times[0,1]$ téglalapban. A $[0,1]$ intervallumon egyenletes eloszlás szerint generált véletlen számokból egyszerű transzformációval kaphatunk a $[-2,2]$ intervallumon egyenletes eloszlásúakat. A J tömbben azon $(x,y)$ pontok indexeit tároljuk, ahol $e^{-x^2} > y$. Mivel a téglalap területe 4, az ilyen pontok aránya az teljes ponthalmazon belül, néggyel szorozva egy közelítést ad $\int_{-2}^2e^{-x^2}\,\mathrm{d}x$-re.

Felhasználjuk a np.where() függvényt, amelynek ha csak egyetlen, mátrix elemein logikai értéket visszaadó kifejezést adunk meg, akkor eredményül azoknak az elemeknek az indexeit adja vissza, ahol az érték igaz (vagy nem 0). Ha a tömb 2-dimenziós, a tuple első eleme az első indexek tömbjét, a második eleme a második indexek tömbjét adja vissza.

Ha a tömb egydimenziós, a tuple egyetlen tömböt ad vissza:

Ezzel még nem jutottunk sokra, mert $\operatorname{erf}x = \frac{2}{\sqrt\pi}\int_0^x e^{-t^2}\,\mathrm dt$. Viszont az n() metódus numerikus közelítést ad a kifejezésre:

Nézzük meg rajzon.