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,ZeroDivisionErroritd.
- 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_fajlakoja bi sačuvala promenljive u.txtili.jsonfajl.
- Dodavanje komande
- Učitavanje vrednosti iz fajla
- Dodavanje komande
ucitaj ime_fajlaza vraćanje prethodno sačuvanih vrednosti.
- Dodavanje komande
Programski kod za konzolni_kalkulator.py
#konzolni_kalkulator.py
# The MIT License (MIT)
# Copyright (c) 2025 Aleksandar Maričić
#
# Ovim se omogućava bilo kome da koristi, kopira, menja, spaja, objavljuje,
# distribuira, daje podlicencu i/ili prodaje kopije ovog softverskog programa,
# uz uslov da u svim kopijama ili značajnim delovima softverskog programa bude
# uključena sledeća obavest:
#
# Copyright (c) 2025 Aleksandar Maričić
#
# Ovaj softverski program je pružen "takav kakav jeste", bez bilo kakvih garancija,
# izričitih ili impliciranih, uključujući, ali ne ograničavajući se na, garancije o
# prikladnosti za prodaju ili pogodnosti za određenu svrhu. U svakom slučaju, autori
# ili nosioci prava nisu odgovorni za bilo kakvu štetu ili druge obaveze koje mogu nastati
# usled upotrebe ovog softverskog programa.
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…
