You are on page 1of 29

Formalne metode u softverskom inženjerstvu

Programski jezik Python


Python – Hello world
• Izvršavanje sa zadatom putanjom .py fajla:
# primjer.py python primjer.py
print('Hello world') Hello world

• Ako se pokrene bez argumenta, programski kod se učitava sa standardnog ulaza i


izvršava u interaktivnom režimu (read-evaluate-print loop, REPL)
python
>>> print('Hello world’)
Hello world

• Ctrl+D (Unix), Ctrl+Z (Windows) ili quit() za zaustavljanje interpretera


• breakpoint() za debagovanje sa (step, next, continue itd.)
Python – evaluacija aritmetičkih izraza
>>> 2 + 2 >>> 5**2
4 25
>>> 100 - 10 * 5 >>> 25**0.5
50 5.0
>>> (100 - 10 * 5) / 5 >>> 4**2.5
10.0 32.0
>>> (100 - 10 * 5) / 4 >>> 64**(1/3)
12.5 3.9999999999999996
>>> # cjelobrojno dijeljenje >>> # zaokruživanje
>>> 50 // 4 >>> round(0.75)
12 1
>>> 50 % 4 >>> round(1.5)
2 2
>>> round(2.5)
2

>>> # eksponenciranje
Python primjer – primitivni tipovi

>>> type('Hello world')


<class 'str'>
>>> type(1)
<class 'int'>
>>> type(1.0)
<class 'float’>
>>> type('1.0')
<class 'str'>
Python – rad sa stringovima

>>> x = input() "int") to str


77 >>> print('You entered: ' + str(x))
>>> print('You entered: ' + x) You entered: 77
You entered: 77 >>> # f-stringovi
>>> y = 5 + x >>> print(f'You entered: {x}')
Traceback (most recent call last): You entered: 77
File "<stdin>", line 1, in <module> >>> # mogu i dvostruki navodnici
TypeError: unsupported operand type(s) for >>> print(f"You entered: {x}")
+: 'int' and 'str' You entered: 77
>>> x = int(x) >>> print("'test'")
>>> y = 5 + x 'test’
>>> y >>> print('"test"')
82 "test“
>>> print('You entered: ' + x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not
Python – rad sa stringovima
>>> # višelinijski string >>> print('C:\neka\putanja')
>>> print(""" C:
... multiline eka\putanja
... string >>> print(r'C:\neka\putanja')
... test C:\neka\putanja
... """) >>> # ponavljanje stringa
>>> "a" * 3
multiline 'aaa’
string >>> # konkatenacija literala bez +
Test >>> "a" "b"
'ab'
>>> """ >>> a = ('a b c'
... multiline ... 'd e f')
... string >>> a
... test 'a b cd e f'
... """
'\nmultiline\nstring\ntest\n'
>>> # raw (suvoparni) stringovi
Python – rad sa stringovima
>>> # stringovi su nizovi karaktera >>> w[3:7]
>>> w = 'Hello world’ 'lo w'
>>> len(w) >>> w[6:-1]
11 'worl'
>>> w[0] >>> w[6:-2]
'H' 'wor'
>>> w[6] >>> w[6:0]
'w’ ''
>>> w[len(w) - 1] >>> w[6:len(w)]
'd' 'world’
>>> w[-1] >>> w[6:]
'd' 'world’
>>> w[-2] >>> w[:5]
'l' 'Hello'
>>> # slicing (rezanje) nizova >>> w[-5:]
>>> w[0:5] 'world'
'Hello'
>>> w[0:len('hello')]
Python – rad sa stringovima

https://docs.python.org/3/tutorial/introduction.html
Python – rad sa stringovima
>>> # stringovi su imutabilni >>> w = 'h' + w[1:]
>>> w[0] = 'h' >>> w
Traceback (most recent call last): 'hello world'
File "<stdin>", line 1, in >>> # w postaje novi string
<module>
TypeError: 'str' object does not
support item assignment
>>> može se kreirati novi string
Python – metode za rad sa stringovima
>>> w = "hELLo WoRLd" False
>>> w.capitalize() >>> 'World' in w
'Hello world’ False
>>> w == 'hello world' >>> 'world' in w
False True
>>> w.lower() >>> w.find('world’)
'hello world' 6
>>> w.lower() == 'hello world' >>> w.find('bye')
True -1
>>> w.count('l') >>> w.find('l', 2)
0 2
>>> w = w.lower() >>> w.find('l', 3)
>>> w.count('l’) 3
3 >>> w.find('l', 4)
>>> w.endswith('rld') 9
True >>> w.find('l', 10)
>>> w.endswith('Rld') -1
False
>>> 'Bye' in w
Python – metode za rad sa stringovima
>>> "The sum of 1 and 2 is {0}, and their difference is {1}.".format(1+2, 1-2)
'The sum of 1 and 2 is 3, and their difference is -1.’
>>> ','.join(['abc', 'def', 'ghi'])
'abc,def,ghi’
>>> 'TestHook'.removeprefix('Test')
'Hook'
>>> 'BaseTestCase'.removeprefix('Test')
'BaseTestCase’
>>> 'MiscTests'.removesuffix('Tests')
'Misc’
>>> 'TmpDirMixin'.removesuffix('Tests')
'TmpDirMixin’
>>> 'What is it that it is which is that which isn\'t?'.replace('is', 'needs')
"What needs it that it needs which needs that which needsn’t?”
Python – metode za rad sa stringovima
>>> a = '1a,2b,3c'.split(',')
>>> a[0]
'1a'
>>> a[1]
'2b'
>>> a[2]
'3c'
Python primjer – varijable

• Varijable su nulabilne reference (pokazivači) na objekte


• Znak za dodjelu (operator =) dodjeljuje vrijednost varijabli, tako da
određuje šta ona referencira

>>> a = 2
>>> b = a * 4
>>> a * b
16
Python primjer – varijable

• Tipovi? Nema. Dinamička tipizacija. Ima type hints.


>>> a: int = 2
>>> b: int = a * 4
>>> a * b
16
• Type hint ne ograničava tip varijable. Samo daje nagovještaj programeru
po pitanju toga šta bi trebao biti tip varijable.
>>> a: float = 2
>>> b: str = a * 4
>>> a * b
16
>>> type(a)
<class 'int'>
>>> type(b)
<class 'int'>
Python primjer – ispis prostih brojeva
user_input = input("Enter a number: ")
user_input = int(user_input) # Convert the user input to an integer
numbers = range(2, user_input + 1) # Number range from 2 to the input number, inclusive.
primes = [] # An empty list for storing primes

def is_prime(number):
for i in range(2, int(number ** 0.5) + 1):
if number % i == 0:
return False
return True

for number in numbers:


if is_prime(number):
primes.append(number)
python main.py
print(primes)
Enter a number: 23
[2, 3, 5, 7, 11, 13, 17, 19, 23]
Python primjer – ispis prostih brojeva + type hints
from typing import Iterable

user_input: str = input("Enter a number: ")


user_input: int = int(user_input)
numbers: Iterable[int] = range(2, user_input + 1)
primes: Iterable[int] = []

def is_prime(number: int) -> bool:


for i in range(2, int(number ** 0.5) + 1):
if number % i == 0:
return False
return True

for number in numbers:


if is_prime(number): python main.py
primes.append(number)
Enter a number: 23
print(primes)
[2, 3, 5, 7, 11, 13, 17, 19, 23]
Python primjer – ispis prostih brojeva #2
user_input = input("Enter a number: ")
user_input = int(user_input)
numbers = range(2, user_input + 1)
def is_prime(number):
for i in range(2, int(number ** 0.5) + 1):
if number % i == 0:
return False
return True
primes = [number for number in numbers if is_prime(number)] # List comprehension
print(primes)

python main.py
Enter a number: 23
[2, 3, 5, 7, 11, 13, 17, 19, 23]
Python primjer – ispis prostih brojeva #3
user_input = input("Enter a number: ")
user_input = int(user_input)
numbers = range(2, user_input + 1)
def is_prime(number):
return all(number % i != 0 for i in range(2, int(number ** 0.5) + 1))
primes = [number for number in numbers if is_prime(number)]
print(primes)

python main.py
Enter a number: 23
[2, 3, 5, 7, 11, 13, 17, 19, 23]
Python kolekcije
• Lista (list), skup (set), mapa (dictionary), n-torka (tuple), string (string)

a = [1, 2, 3] python main.py


b = {1, 2, 3} [1, 2, 3]
c = {'a': 1, 4: 2, 'abc': 3} <class 'list'>
d = (1, 2, 3) {1, 2, 3}
e = '123' <class 'set'>
{'a': 1, 4: 2, 'abc': 3}
for i in [a, b, c, d, e]: <class 'dict'>
print(i) (1, 2, 3)
print(type(i)) <class 'tuple'>
123
<class 'str'>
• Dokumentacija
• Nad listama se takođe može vršiti slicing
JSON serijalizacija i deserijalizacija {
"a": 1,
"b": 2,
"3": "c",
import json with open('out.json', 'w') as fp: "d:": [
a = { # write pretty json 1,
'a': 1, json.dump(a, fp, indent=4) 2,
'b': 2, 3
3: 'c', ],
'd:': [1, 2, 3], "e": {
'e': { "f": 4,
'f': 4, "g": 5
'g': 5 },
}, "f": [
'f': (1, 2, 3), 1,
'h': None, 2,
'i': True, 3
'j': False ],
} "h": null,
# w - write, r - read, a - append "i": true,
"j": false
}
JSON deserijalizacija
with open('out.json', 'r') as fp:
b = json.load(fp)
print(b)

{'a': 1, 'b': 2, '3': 'c', 'd:': [1, 2, 3], 'e': {'f': 4, 'g': 5}, 'f': [1, 2, 3], 'h': None, 'i': True, 'j': False}
Domaća zadaća
• Pročitati Python Tutorial i Python FAQ
• Tok kontrole, lambda izrazi, strukture podataka, moduli, I/O, izuzeci,
klase, standardna biblioteka i virtuelna okruženja
• Rad sa argumentima komandne linije: argparse + argparse tutorijal
Formalne metode u softverskom inženjerstvu

Jedinično testiranje sa pytest


Jedinično testiranje
• Slično onome kada pišemo demonstracije u main funkciji – ali ih sada izdvajamo i pokrećemo nezavisno od main
funkcije, uz automatizovanu provjeru da li se zadovoljava očekivano ponašanje
• Test == funkcija koja testira dio ponašanja nekog API-ja
• Pad testa == dokaz kontraprimjerom da API ne funkcioniše kako treba za neki slučaj
• --- Razlozi za jedinično testiranje ---
• Ispitati da li funkcionalnosti rade pravilno, na lako ponovljiv način
• Automatski se provjerava da li se obradom dolazi do očekivanog stanja podataka, ne moramo ručno provjeravati
šta je izlaz za neki ulaz
• Ispitati da li funkcionalnosti rade pravilno nakon što se napravi izmjena/refaktorizacija u kodu
• Za čitaoca koda čini jasnijim kako kod treba da radi i kako se API upotrebljava
• Pokretanje testova se radi nezavisno od glavnog toka programa
• Testovi su međusobno nezavisni, tako da ako neki prođu, a drugi padnu moguće je lakše utvrditi u kojim
slučajevima program radi kako treba, a u kojim ne
• Smanjuje neophodan trud i vrijeme potrebno za razumijevanje i debagovanje koda
Jedinično testiranje
• Python frejmvorci za testiranje:
• unittest
• pytest
• U drugim jezicima:
• Java: JUnit, TestNG
• .NET (C#): NUnit, xUnit, MSTest
• C++: Google Test
pytest
• Instalira se kao PIP paket: python -m pip install pytest
• Pokreće se unosom komande pytest na konzoli
• pytest izvršava sve testne funkcije u projektu
• Kako ih podrazumijevano pronalazi?
• Rekurzivnom pretragrom se, počevši od trenutnog direktorijuma,
pronalaze svi izvorni fajlovi oblika test_*.py
• Skupljaju se, iz pronađenih fajlova, testne funckije sa prefiksom test
• Još jedan način jeste da se komandi pytest, kao argument, specificira
naziv fajla sa testovima
Primjer pokretanja testova
# f.py # test_a.py
def f(): import f
return False
def test_f():
assert f.f() == False
# f.py
def f(): # test_a.py

Primjer pokretanja testova return True import f

def test_f():
assert f.f() == False
Domaća zadaća
• Definisati pytest testove sa adekvatnim tvrdnjama za funkciju koja
izračunava ocjenu na osnovu broja bodova, a zatim definisati tu
funkciju tako da su tvrdnje u testovima ispunjene.

You might also like