2. Sučelje

2.1. Bilježnice i ćelije

Bilježnica (notebook) je skup računalnog kôda s rezultatima i tekstualnim opisom koji je

  • prikazan na jednoj stranici u WWW pregledniku
  • može se pohraniti u jednu datoteku (ekstenzija .ipynb)

Račun, tj. računalni kôd radnog lista je organiziran u tzv. ćelije (cell). Svaka računska (input) ćelija je ograđena pravokutnikom i izvršava se kao cjelina na nekoliko načina:

  1. pritiskom na kombinaciju tipki shift-Enter dok je kursor bilo gdje u ćeliji (Pritisak samo na Enter otvara novi redak u ćeliji),
  2. pritiskom na kombinaciju tipki alt-Enter. To onda dodatno i otvara novu ćeliju.
  3. klikom mišem na gumb s ikonom Play
  4. klikom mišem na izbornik Cell pa Run Cells

Rezultat se nakon izvršavanja ispisuje neposredno ispod ćelije. Ako se eksplicitno ne zatraži drugačije (npr. naredbom print), bit će ispisan samo rezultat zadnjeg računa/komande/retka u toj ćeliji (ali izvršit će se naravno cijela ćelija).

../_images/notebook.png

Otvaranje novih ćelija se izvodi putem ikone Plus ili izbornika Insert. Nove ćelije su po defaultu izvršne (Code) tj. sadrže računalni kôd. Ukoliko želimo u bilježnicu dodati slobodni tekst i komentare, ćeliju prvo pretvaramo u tekstualnu putem izbornika na traci s alatima (Code pretvorimo u Markdown ili Heading ukoliko želimo staviti naslov odjeljka) ili putem tipke M.

Zadatak 1

Kreirajte novu input ćeliju i izračunajte 2+3. Kreirajte zatim tekstualnu ćeliju s nekim tekstom iznad ove. Izbrišite obje ćeiije.

Važno svojstvo Jupyter sučelja je da svaku ćeliju možemo i naknadno editirati i onda ponovno izvršiti. To je onda sve skupa sličnije radu u tabličnom kalkulatoru (spreadsheet) nego standardnom programiranju. Osim samog sadržaja ćelija bilježnice, trenutno stanje je određeno i stanjem python jezgre ( kernela), a ono općenito ovisi o redosljedu kojim su ćelije izvršene. Resetiranje tog stanja se izvodi putem izbornika Kernel pa Restart. (Što je korisna operacija u trenucima kad se Jupyter počne neočekivano ponašati.) Zbog toga je po završetku rada dobro prekontrolirati konzistentnost i reproducibilnost cijelog računa tako da resetiramo jezgru i izvršimo sve ćelije odjednom pomoću izbornikai Kernel pa Restart & Run All.

Svakoj bilježnici pripada nezavisni kernel proces s nezavisnim varijablama. Ovisno o instalaciji Jupytera, osim Python jezgri na raspolaganju mogu biti i jezgre drugih programskih jezika.

2.2. Elementarno računanje

Python se može koristiti kao obični kalkulator proizvoljne preciznosti:

>>> 3*2+1
7

>>> 13**23
41753905413413116367045797

>>> 13.**23
4.175390541341312e+25

Uočite različit tretman cijelih (integer) i brojeva s pomičnom točkom (floating point). Cijeli brojevi se tretiraju egzaktno, bez zaokruživanja ili odbacivanja nekih znamenaka.

Napomena

Pythonov prompt znak >>> u gornjim primjerima nije potrebno unositi u Jupyter ćelije (makar ne smeta). On se u ovom tekstu pojavljuje samo zato da se omogući automatsko testiranje prikazanog koda.

Napomena

Jupyter automatski ispisuje samo rezultat posljednje komande u datoj ćeliji. Ukoliko trebamo i ispis nekih unutarnjih komandi, treba upotrijebiti funkciju print.

print(2+3)
2-3  # Zadnja linija pa je print ovdje nepotreban
5
-1

Za zapis velikih brojeva može se koristiti standardni Fortran/C zapis po kojem se npr. \(3.2\cdot 10^4\) zapisuje ovako

>>> 3.2e4
32000.0

Mnoge standardne matematičke funkcije mogu se pozivati tek nakon uključenja dodatnog Python paketa

>>> from scipy import *
>>> sqrt(9)
3.0

>>> sin(radians(90))
1.0

Umjesto scipy paketa mogli bi koristiti i pakete math ili cmath, (koji su manji i brži i također sadrže osnovne matematičke funkcije), ili paket numpy koji je srednje rješenje, vidi tablicu, ali scipy pruža unificiraniji pristup kompleksnim i realnim brojevima, a koristiti ćemo ga ionako i za brojne druge svrhe. U slijedećoj tablici uspoređujemo ove pakete. Redak brzina je vrijeme u mikrosekundama za izvrijednjavanje logaritma sto slučajnih brojeva, a redak distributivnost označava da li funkcije mogu primiti liste brojeva kao argumente (pa se automatski distribuiraju po elementima).

Paket math numpy scipy
brzina 37.4 89.1 968
distributivnost NE DA DA
sqrt(-1) ValueError nan 1j
log(-1) ValueError TypeError 3.14159j

Kod učitavanja funkcija na način kao gore (from X import *) treba paziti da ne dođe do kolizije istoimenih funkcija iz različitih paketa. Pravilnije je učitavanje i korištenje modula na slijedeći način

>>> import scipy.special
>>> scipy.special.gamma(6)   # = (6-1)!
120.0

(Eulerova gama funkcija je poopćeni faktorijel.)

Paketu numpy se tradicionalno pri učitavanju skraćuje ime.

>>> import numpy as np
>>> np.random.random()
0.3745401188473625

(Tako se dobiva slučajni broj između 0 i 1.)

Pridruživanje vrijednosti varijablama izvodi se znakom jednakosti “=”.

>>> x = 4
>>> x
4

>>> x + 3
7

Primijetite da sama operacija pridruživanja ne rezultira nikakvim ispisom. Pridruživanje i naknadni ispis se mogu napraviti i u jednom redu korištenjem simbola ; koji odvaja naredbe:

>>> x = 4; x
4

Standardne matematičke funkcije i konstante imaju uobičajena imena i ponašanje:

>>> log(e)
1.0

>>> sin(pi)
1.2246467991473532e-16

Uočite da su ovi objekti floating point tipa i zadržavaju preciznost od oko 14-15 značajnih znamenki. Ukoliko trebamo veću preciznost možemo koristiti paket mpmath, a ukoliko želimo raditi s “apsolutno” točnim simboličkim objektima, koristimo paket SymPy ili Sage okruženje.

>>> import mpmath as mp
>>> mp.mp.dps = 30
>>> mp.sin(mp.pi)
mpf('1.69568553207377992879174029387737e-31')

S kompleksnim brojevima radimo jednostavno. Samo treba imati na umu da se imaginarni broj konstruira dodavanjem znaka j pa je tako imaginarna jedinica 1j.

>>> 1j**2
(-1+0j)

>>> sqrt(-4)
2j

Zadatak 2

Izračunajte \(\sqrt{2 \sqrt{e^\pi}}\).

Zadatak 3

Uvjerite se numerički da za proizvoljni realni \(x\) vrijedi

\[\sin(i x) = i \sinh(x).\]

Zadatak 4

Izvrijednite Eulerovu gama funkciju za z=1/2, dakle \(\Gamma(1/2)\). Uvjerite se da je rezultat jednak \(\sqrt{\pi}\).

Za upis matematičkih izraza u tekstualne čelije stavljamo LaTeX kôd unutar dolarskih znakova. Tako se upis

$\alpha$

unutar retka prikazuje kao \(\alpha\). Veće jednadžbe koje trebaju stajati u posebnom redu upisuju se između parova dolarskih znakova u novom redu. Tako se:

$$ E = \gamma m c^2 $$

prikazuje kao

\[E = \gamma m c^2\]

Za precizno formatiranje ispisa rezultata računa koristimo pretvorbu brojeva u stringove te standardno Python formatiranje. Npr. slijedeći kod formatira ispis broja \(\pi\) na 7 mjesta ukupno i 4 mjesta iza decimalne točke.

>>> print('{} = {:7.4f}'.format('Ludolfov broj', pi))
Ludolfov broj =  3.1416

2.3. Help sustav

Da bismo pronašli potrebnu funkciju te način i primjere njene upotrebe služimo se slijedećim pristupima Python dokumentaciji. Kao prvo, tu je TAB-nastavljanje (TAB-completion): započnemo li pisati ime neke funkcije, pritisak na tipku TAB dovršava pisanje njenog imena ako je nastavak jedinstven, a ako nije dobivamo popis svih mogućnosti (pa željenu odaberemo mišem ili kursorskim tipkama i tipkom Enter).

Dokumentaciju konkretne funkcije dobijemo tako da nakon imena funkcije stavimo upitnik i onda pritisnemo ctrl-ENTER. Iz dobivene dokumentacije možemo cut-and-paste-ati primjere u input ćelije. (Ukoliko umjesto jednog stavimo dva upitnika dobijemo cijeli ispis kôda koji definira tu funkciju.)

Za pretraživanje dokumentacije najefikasnije je koristiti Google.

2.4. Poruke o greškama

Ako se ogriješimo o matematička ili sintaktička pravila Python će nam uzvratiti porukom o grešci. Klik mišem lijevo od vrha te poruke daje opširnije informacije (inače, drugi klik potpuno skriva poruku što se može koristiti i za skrivanje svih nepregledno dugačkih ispisa rezultata računa.) Za interpretaciju opširnije poruke potrebno je znanje Python programskog jezika, no ključna informacija je obično u zadnjem retku, koji je odmah vidljiv.

>>> 1/0
Traceback (most recent call last):
  ...
ZeroDivisionError: division by zero
>>> sin[2.3]
Traceback (most recent call last):
  ...
TypeError: 'numpy.ufunc' object is not subscriptable

Početniku će te poruke izgledati nejasno, ali s vremenom će poprimati sve više smisla i treba ih uvijek čitati. Npr. gornja greška “object is unsubscriptable” je posljedica toga što smo za poziv funkcije sin umjesto okruglih zagrada upotrijebili uglate, koje služe za pristup elementima (tj. indeksima, subskriptima) polja i matrica.