Dobio sam zadatak od žene da sračunam površinu zidova i plafona za krečenje te sam napravio prigodni konzolni interaktivni kalkulator u python3.10 koji omogućava dodeljivanje izraza promenljivama i kasnije korišćenje tih promenljivih u daljim izračunavanjima. Ovaj program omogućava:
Izlaz iz programa sa izlaz
.
Unos izraza u obliku ime=izraz
(npr. prozor=1.4*1.2
).
Korišćenje prethodno definisanih promenljivih u novim izrazima (npr. otvori=prozor1+vrata1+vrata2+prozor3
)
Prikaz svih promenljivih sa komandnom prikazi
.
variables = {} def evaluate_expression(expression): try: result = eval(expression, {"__builtins__": {}}, variables) return result except Exception as e: print(f"Greška u izrazu: {e}") return None def main(): print("Unesite izraze u formatu promenljiva=izraz (npr. prozor=1.4*1.2).") print("Za prikaz svih promenljivih unesite 'prikazi'. Za izlaz unesite 'izlaz'.") while True: unos = input(">> ").strip() if unos.lower() == "izlaz": break elif unos.lower() == "prikazi": for key, value in variables.items(): print(f"{key} = {value}") elif "=" in unos: ime, izraz = map(str.strip, unos.split("=", 1)) vrednost = evaluate_expression(izraz) if vrednost is not None: variables[ime] = vrednost else: print("Neispravan unos. Koristite 'ime=izraz' ili komande 'prikazi' i 'izlaz'.") if __name__ == "__main__": main()
Sledi primer proračuna dnevne sobe, trpezarije i kuhinje:

Funkcija evaluate_expression(expression)
ima sledeće funkcionalnosti:
- Evaluacija izraza
- Koristi
eval()
za izračunavanje izraza. - Zabranjuje pristup ugrađenim funkcijama Python-a (
{"__builtins__": {}}
), čime se smanjuje rizik od nebezbednog izvršavanja koda. - Omogućava korišćenje promenljivih koje su prethodno definisane u
variables
.
- Koristi
- Rukovanje greškama
- Ako dođe do greške prilikom evaluacije izraza (npr. nepostojeća promenljiva, sintaksna greška), ispisuje poruku o grešci i vraća
None
.
- Ako dođe do greške prilikom evaluacije izraza (npr. nepostojeća promenljiva, sintaksna greška), ispisuje poruku o grešci i vraća
- Vraćanje rezultata
- Ako je evaluacija uspešna, vraća izračunatu vrednost izraza.
U suštini, funkcija omogućava računanje izraza koji koriste brojeve i prethodno definisane promenljive, ali ne dozvoljava pozivanje ugrađenih funkcija Python-a radi sigurnosti.
Funkcija eval()
u Pythonu omogućava evaluaciju izraza koji su zadati kao string. Njene mogućnosti su široke, ali su u našem kodu ograničene radi sigurnosti. Evo šta eval()
može da izračuna:
1. Aritmetičke operacije
- Sabiranje, oduzimanje, množenje, deljenje:
eval("5 + 3 * 2") # 11 eval("10 / 2") # 5.0 eval("2 ** 3") # 8 (stepenovanje) eval("10 % 3") # 1 (modulo)
2. Korišćenje promenljivih
- Može koristiti već definisane promenljive:
variables = {"a": 10, "b": 5} eval("a + b", {"__builtins__": {}}, variables) # 15
3. Grupisanje i prioritet operacija
- Može obrađivati izraze sa zagradama:
eval("(2 + 3) * 4") # 20
4. Rad sa realnim brojevima
- Podržava decimalne brojeve:
eval("3.5 * 2.1") # 7.35
5. Negacije i apsolutne vrednosti
- Može obraditi negativne brojeve:
eval("-5 + 2") # -3
Šta eval()
ne može u našem kodu?
Pošto koristimo {"__builtins__": {}}
, eval()
ne može:
- Pozivati bilo koju ugrađenu funkciju (
print()
,open()
,exec()
,os.system()
, itd.). - Pristupati fajlovima ili sistemskim komandama.
- Izvršavati složenije Python izraze poput petlji (
for
,while
) ili definicija (def
,class
).
Ako želiš da podržiš i matematičke funkcije (sqrt
, sin
, cos
, itd.), možemo dodati podršku za math
modul na bezbedan način.
import math variables = {} def evaluate_expression(expression): try: allowed_functions = {name: getattr(math, name) for name in dir(math) if callable(getattr(math, name))} result = eval(expression, {"__builtins__": {}}, {**variables, **allowed_functions}) return result except Exception as e: print(f"Greška u izrazu: {e}") return None def main(): print("Unesite izraze u formatu promenljiva=izraz (npr. prozor=1.4*1.2).") print("Možete koristiti matematičke funkcije iz 'math' modula (npr. sqrt, sin, cos).") print("Za prikaz svih promenljivih unesite 'prikazi'. Za izlaz unesite 'izlaz'.") while True: unos = input(">> ").strip() if unos.lower() == "izlaz": break elif unos.lower() == "prikazi": for key, value in variables.items(): print(f"{key} = {value}") elif "=" in unos: ime, izraz = map(str.strip, unos.split("=", 1)) vrednost = evaluate_expression(izraz) if vrednost is not None: variables[ime] = vrednost else: print("Neispravan unos. Koristite 'ime=izraz' ili komande 'prikazi' i 'izlaz'.") if __name__ == "__main__": main()
Proširio sam funkcionalnost tako da sada možeš koristiti matematičke funkcije iz math
modula, kao što su sqrt
, sin
, cos
, log
, itd. Na primer:
>> x = sqrt(25) >> y = sin(3.14) >> prikazi x = 5.0 y = 0.0015926529164868282
Evo svih funkcija iz math
modula koje sada možeš koristiti u programu, uz primere:
1. Trigonometrijske funkcije
math.sin(3.14) # Sinus ugla (radijani) math.cos(3.14) # Kosinus ugla (radijani) math.tan(3.14) # Tangens ugla (radijani) math.asin(0.5) # Arkus sinus (vraća radijane) math.acos(0.5) # Arkus kosinus math.atan(1) # Arkus tangens math.atan2(1, 1) # Arkus tangens sa dve vrednosti (y, x) math.sinh(1) # Hiperbolički sinus math.cosh(1) # Hiperbolički kosinus math.tanh(1) # Hiperbolički tangens math.asinh(1) # Inverzni hiperbolički sinus math.acosh(2) # Inverzni hiperbolički kosinus math.atanh(0.5) # Inverzni hiperbolički tangens
2. Eksponencijalne i logaritamske funkcije
math.exp(2) # e^2 math.exp2(3) # 2^3 math.expm1(1) # e^x - 1, preciznije za male vrednosti x math.log(100) # Logaritam baze e (ln) math.log(100, 10) # Logaritam baze 10 math.log10(100) # Logaritam baze 10 math.log2(8) # Logaritam baze 2 math.log1p(0.5) # ln(1 + x), precizno za male x
3. Koreni i stepeni
math.sqrt(25) # Kvadratni koren math.cbrt(27) # Kubni koren math.pow(2, 3) # 2^3
4. Aritmetičke funkcije
math.fabs(-10.5) # Apsolutna vrednost math.ceil(4.3) # Zaokruživanje na više (5) math.floor(4.8) # Zaokruživanje na niže (4) math.trunc(4.8) # Odbacuje decimalni deo (4) math.modf(5.75) # Razdvaja decimalni i celobrojni deo (0.75, 5.0) math.remainder(10, 3) # Matematički ostatak pri deljenju math.fmod(10, 3) # Modulo (ostatak pri deljenju)
5. Kombinatorne funkcije
math.factorial(5) # Faktorijel (5! = 5×4×3×2×1) math.comb(5, 2) # Kombinacije: koliko načina da izaberemo 2 od 5 math.perm(5, 2) # Permutacije: koliko načina da rasporedimo 2 od 5 math.prod([1, 2, 3, 4]) # Proizvod svih brojeva u listi
6. Brojevne funkcije
math.gcd(48, 18) # Najveći zajednički delilac math.lcm(12, 15) # Najmanji zajednički sadržalac math.isqrt(10) # Celi broj kvadratnog korena (int)
7. Rad sa uglovima
math.radians(180) # Pretvara stepeni u radijane (π) math.degrees(math.pi) # Pretvara radijane u stepene (180°)
8. Specijalne funkcije
math.gamma(5) # Gama funkcija (faktorijel proširen za realne brojeve) math.lgamma(5) # Logaritamska gama funkcija math.erf(1) # Greška funkcija math.erfc(1) # Komplementarna greška funkcija
Naredni Python program omogućava unos matematičkih izraza i dodelu rezultata promenljivama, uz podršku za funkcije iz math
modula. Program čuva definisane promenljive i omogućava njihovo prikazivanje.
Poboljšanja:
- Podrška za korišćenje prethodno definisanih promenljivih
- Trenutno već definisane promenljive mogu da se koriste, ali nema zaštite od unosa nepostojećih promenljivih.
- Može se dodati provera i javljanje greške ako se pokuša koristiti nepoznata promenljiva.
- Bolja obrada grešaka
- Trenutno se sve greške prikazuju generički (
Greška u izrazu: ...
). - Može se dodati specifična obrada za
NameError
,SyntaxError
,ZeroDivisionError
itd.
- Trenutno se sve greške prikazuju generički (
- Formatiranje ispisa vrednosti promenljivih
- Može se podesiti broj decimala ili koristiti
f"{value:.2f}"
za bolji prikaz.
- Može se podesiti broj decimala ili koristiti
- Mogućnost izvoza promenljivih u fajl
- Dodavanje komande
sacuvaj ime_fajla
koja bi sačuvala promenljive u.txt
ili.json
fajl.
- Dodavanje komande
- Učitavanje vrednosti iz fajla
- Dodavanje komande
ucitaj ime_fajla
za vraćanje prethodno sačuvanih vrednosti.
- Dodavanje komande
import math import json import os variables = {} def evaluate_expression(expression): try: allowed_functions = {name: getattr(math, name) for name in dir(math) if callable(getattr(math, name))} result = eval(expression, {"__builtins__": {}}, {**variables, **allowed_functions}) return round(result, 2) # Formatiranje na 2 decimale except NameError as e: print(f"Greška: Nepoznata promenljiva ili funkcija. {e}") except ZeroDivisionError: print("Greška: Deljenje nulom nije dozvoljeno.") except SyntaxError: print("Greška: Sintaksna greška u izrazu.") except Exception as e: print(f"Greška u izrazu: {e}") return None def save_variables(filename): try: with open(filename, "w") as f: json.dump(variables, f, indent=4) print(f"Promenljive sačuvane u {filename}.") except Exception as e: print(f"Greška pri čuvanju: {e}") def load_variables(filename): global variables if os.path.exists(filename): try: with open(filename, "r") as f: variables = json.load(f) print(f"Promenljive učitane iz {filename}.") except Exception as e: print(f"Greška pri učitavanju: {e}") else: print("Fajl ne postoji.") def main(): print("Unesite izraze u formatu promenljiva=izraz (npr. prozor=1.4*1.2).") print("Možete koristiti matematičke funkcije iz 'math' modula (npr. sqrt, sin, cos).") print("Podržane funkcije:") print(" sqrt(x) - Kvadratni koren, npr. sqrt(16) = 4.0") print(" sin(x), cos(x), tan(x) - Trigonometrija u radijanima, npr. sin(3.14/2) = 1.0") print(" degrees(x) - Pretvara radijane u stepene, npr. degrees(3.14) = 180.0") print(" radians(x) - Pretvara stepene u radijane, npr. radians(180) = 3.14") print(" log(x) - Prirodni logaritam, npr. log(10) = 2.3") print(" log10(x) - Logaritam po bazi 10, npr. log10(100) = 2.0") print(" exp(x) - Eksponencijalna funkcija, npr. exp(2) = 7.39") print(" pow(x, y) - Stepenovanje, npr. pow(2, 3) = 8") print(" ceil(x) - Zaokružuje na sledeći ceo broj, npr. ceil(2.3) = 3") print(" floor(x) - Zaokružuje na manji ceo broj, npr. floor(2.7) = 2") print("Za prikaz svih promenljivih unesite 'prikazi'. Za izlaz unesite 'izlaz'.") print("Sačuvaj promenljive sa 'sacuvaj ime_fajla'. Učitaj sa 'ucitaj ime_fajla'.") while True: unos = input(">> ").strip() if unos.lower() == "izlaz": break elif unos.lower() == "prikazi": for key, value in variables.items(): print(f"{key} = {value:.2f}") elif unos.startswith("sacuvaj"): _, filename = unos.split(maxsplit=1) save_variables(filename) elif unos.startswith("ucitaj"): _, filename = unos.split(maxsplit=1) load_variables(filename) elif "=" in unos: ime, izraz = map(str.strip, unos.split("=", 1)) vrednost = evaluate_expression(izraz) if vrednost is not None: variables[ime] = vrednost else: print("Neispravan unos. Koristite 'ime=izraz' ili komande 'prikazi', 'sacuvaj', 'ucitaj' i 'izlaz'.") if __name__ == "__main__": main()
Dodao sam sve opisane funkcionalnosti! Sada možeš:
✔ Koristiti ranije definisane promenljive bez greške.
✔ Dobiti preciznije poruke o greškama.
✔ Videti formatirane rezultate sa dve decimale.
✔ Sačuvati promenljive u fajl (sacuvaj ime_fajla
).
✔ Učitati promenljive iz fajla (ucitaj ime_fajla
).
Za proveru programa evo jednog kompleksnijeg matematičkog izraza koji uključuje eksponencijalne funkcije, trigonometriju i kvadratne korene:

Unesi ga u program ovako:
x = (sin(45) + cos(30) * sqrt(25) - exp(2.1)) / (log(10) + tan(60))
Proba programa u konzoli bi trebala da izgleda ovako:

A sve je počeolo od sračunavanja površine zidova i plafona za krečenje…