def prijava_na_sistem():
    """ Funkcija prijava_na_sistem podrazumeva unos šifre profesora ili broja indeksa, 
        kao korisničkog imena, i unos lozinke
    """
    print("\nPrijava na sistem")
    korisnicko_ime = None
    while True:
        try:
            korisnicko_ime = int(
                input(
                    "Unesite korisničko ime (ceo broj) - šifra profesora ili broj indeksa: "
                ))
            break
        except ValueError:
            continue
    lozinka = input("Unesite lozinku: ")
    # provera postojanja datog korisnickog imena i lozinke u bazi profesora
    profesori = ucitaj_listu_profesora()
    for profesor in profesori:
        prof_korisnicko_ime = int(profesor.split(";")[0])
        prof_lozinka = profesor.split(";")[1]
        if korisnicko_ime == prof_korisnicko_ime and lozinka == prof_lozinka:
            print("- Uspešno prijavljivanje profesora")
            meni_profesora(korisnicko_ime)
            return
    # provera postojanja datog korisnickog imena i slozinke u bazi studenata
    studenti = ucitaj_listu_studenata()
    for student in studenti:
        if korisnicko_ime == student["broj indeksa"] and lozinka == str(
                student["lozinka"]):
            print("- Uspešno prijavljivanje studenta")
            meni_studenta(korisnicko_ime)
            return
    print("- Neuspešno prijavljivanje")
def dodavanje_ocene(sifra_profesora):
    """ Funkcija dodavanje_ocene najpre omogućava profesoru da pretražuje studente spram imena,
        a zatim i doda ocenu, u opsegu od 5 do 10, jednom od ponuđenih studenata (po broju indeksa)
    """
    print("\nDodavanje ocene studentu")
    ime = input("Unesite ime studenta (bez prezimena): ")
    studenti = ucitaj_listu_studenata()
    filtrirani_studenti = []
    filtrirani_brojevi_indeksa = []
    # pretrazivanje studenata sa unetim imenom
    for student in studenti:
        if ime.lower() == student["ime"].lower():
            filtrirani_studenti.append(student)
            filtrirani_brojevi_indeksa.append(student["broj indeksa"])
    # ukoliko ne postoji student sa unetim imenom program se prekida
    if not len(filtrirani_studenti):
        print("- Nema studenata se imenom", ime)
        return
    # ukoliko postoji student sa unetim imenom stampa se njegov broj indeksa, ime i prezime
    for i in range(len(filtrirani_studenti)):
        print(str(i + 1) + ".", filtrirani_studenti[i]["broj indeksa"], \
        filtrirani_studenti[i]["ime"], filtrirani_studenti[i]["prezime"])
    broj_indeksa = None
    while broj_indeksa not in filtrirani_brojevi_indeksa:
        try:
            broj_indeksa = int(input("Unesite broj indeksa studenta: "))
        except ValueError:
            continue
    # prikaz svih predmeta sa njihovom sifrom i nazivom
    predmeti = ucitaj_listu_predmeta()
    sifre_predmeta = []
    for i in range(len(predmeti)):
        sifra = predmeti[i].split(";")[0]
        naziv = predmeti[i].split(";")[1].strip()
        sifre_predmeta.append(sifra)
        print(str(i + 1) + ".", sifra, naziv)
    # unos sifre predmeta i provera njenog postojanja u listi predmeta
    sifra_predmeta = input("Unesite šifru predmeta: ")
    if sifra_predmeta not in sifre_predmeta:
        print("- Ne postoji uneta šifra predmeta")
        return
    # unos i provera validnosti ocene
    ocena = None
    while ocena not in (5, 6, 7, 8, 9, 10):
        try:
            ocena = int(input("Unesite ocenu (5-10): "))
        except ValueError:
            continue
    for student in studenti:
        # dodavanje ucene odgovarajucem studentu
        if broj_indeksa == student["broj indeksa"]:
            nova_ocena = {
                "sifra_predmeta": sifra_predmeta,
                "sifra_profesora": sifra_profesora,
                "ocena": ocena
            }
            student["ocene"].append(nova_ocena)
            sacuvaj_listu_studenata(studenti)
            print("- Uspešno dodavanje ocene")
def predmeti(broj_indeksa):
    """ Funkcija predmeti prikazuje korisniku sve položene ili nepoložene predmete
        prijavljenog studenta, na osnovu parametra broj_indeksa
    """
    print("\nPrikaz položenih ili nepoloženih predmeta")
    print("1. Položeni")
    print("2. Nepoloženi")
    opcija = None
    while opcija not in (1, 2):
        try:
            opcija = int(input("Izaberite jednu od navedenih opcija (1/2): "))
        except ValueError:
            continue
    studenti = ucitaj_listu_studenata()
    for student in studenti:
        # trazimo zapis student sa odgovarajucim brojem indeksa
        if broj_indeksa == student["broj indeksa"]:
            ocene = student["ocene"]
            # prikupljanje sifara polozenih predmeta
            sifre_polozenih_predmeta = []
            for ocena in ocene:
                sifre_polozenih_predmeta.append(ocena["sifra_predmeta"])
    predmeti = ucitaj_listu_predmeta()
    # u zavisnost da li je opcija 1 ili 2 ovde ce biti polozeni ili nepolozeni predmeti
    rezultirajuci_predmeti = []
    for predmet in predmeti:
        sifra_predmeta = predmet.split(";")[0]
        # trazenje studentovih polozenih ili nepolozenih predmeta u listi 
        # predmeta u zavisnosti od vrednosti opcije
        if opcija == 1 and sifra_predmeta in sifre_polozenih_predmeta \
        or opcija == 2 and sifra_predmeta not in sifre_polozenih_predmeta:
            ime_predmeta = predmet.split(";")[1]
            # dodavanje imena (ne)polozenog predmeta u listu rezultirajucih predmeta
            rezultirajuci_predmeti.append(ime_predmeta)
    if opcija == 1:
        print("\nPrikaz položenih predmeta")
    else:
        print("\nPrikaz nepoloženih predmeta")
    if len(rezultirajuci_predmeti) == 0:
        print("- Ne postoje traženi predmeti")
    else:
        for predmet in rezultirajuci_predmeti:
            # metod strip se koristi kako bi obrisali \n karaktere sa kraja stringa
            print("- " + predmet.strip()) 
def globalna_prosecna_ocena(broj_indeksa):
    """ Funkcija globalna_prosecna_ocena vrši računanje tako što se na osnovu svih 
        ocena prijavljenog studenta (na osnovu paramtera broj_indeksa) izračuna 
        prosečna ocena i prikaže se studentu
    """
    print("\nRačunanje globalne prosečne ocene")
    studenti = ucitaj_listu_studenata()
    for student in studenti:
        # trazimo zapis student sa odgovarajucim brojem indeksa
        if broj_indeksa == student["broj indeksa"]:
            suma = 0
            ocene = student["ocene"]
            for ocena in ocene:
                suma += ocena["ocena"]
    # ukoliko broj ocena nije jednak nuli delimo sumu ocena sa brojem
    # ocena studenata (ovako izbegavamo deljenje sa nulom)
    if len(ocene):
        print("- Globalna prosečna ocena studenta je", format(suma / len(ocene), ".2f"))
    else:
        print("- Student nema unesene ocene, te ni prosek")               
def prosecna_ocena_za_predmet(sifra_profesora):
    """ Funkcija prosecna_ocena_za_predmet prijavljenom profesoru najpre prikazuje sve 
        predmete sa šifrom i nazivom, a zatim profesor bira redni broj predmeta za 
        koji želi da se izračuna prosečna ocena
    """
    print("\nRačunanje prosečne ocene za predmet")
    predmeti = ucitaj_listu_predmeta()
    # prikazivanje svih predmeta sa sifrom i nazivom
    for i in range(len(predmeti)):
        sifra = predmeti[i].split(";")[0]
        naziv = predmeti[i].split(";")[1].strip()
        print(str(i + 1) + ".", sifra, naziv)
    redni_broj = None
    while redni_broj not in range(1, len(predmeti) + 1):
        try:
            redni_broj = int(input("Unesite redni broj predmeta (1/.../n): "))
        except ValueError:
            continue
    sifra_predmeta = predmeti[redni_broj - 1].split(";")[0]
    suma = 0
    broj_ocena = 0
    studenti = ucitaj_listu_studenata()
    # pretrazivanje unete sifre predmeta medju svima ocenama svih studenta
    # i njihovo sabiranje ukoliko se pronadju
    for student in studenti:
        ocene = student["ocene"]
        for ocena in ocene:
            if sifra_predmeta == ocena[
                    "sifra_predmeta"] and sifra_profesora == ocena[
                        "sifra_profesora"]:
                suma += ocena["ocena"]
                broj_ocena += 1
    # ukoliko je broj ocena različit od 0
    if broj_ocena:
        print("- Prosečna ocena za predmet šifre", sifra_predmeta, "je",
              format(suma / broj_ocena, ".2f"))
    else:
        print(
            "- Ne postoji nijedna ocena prijavljenog profesora za dati predmet"
        )
def prikaz_profesora():
    """ Funkcija prikaz_profesora korisniku prikazuje sve predmete, nakon čega on bira 
        šifru jednog predmeta, a funkcija štampa sve profesore koji predaju taj predmet
    """
    print("\nPrikaz podataka o profesoru koji predaje predmet")
    # prikaz korisniku svih predmeta 
    predmeti = ucitaj_listu_predmeta()
    for predmet in predmeti:
        sifra = predmet.split(";")[0]
        naziv = predmet.split(";")[1].strip()
        print("-", sifra, naziv)
    sifra_predmeta = input("Unesite šifru predmeta: ")
    print("\nPodaci profesora koji predaje predmet šifre", sifra_predmeta)
    studenti = ucitaj_listu_studenata()
    sifre_profesora = []
    # pretraga postojanja date sifre predmeta medju studentima i njihovim ocenima
    for student in studenti:
        ocene = student["ocene"]
        for ocena in ocene:
            # ukoliko se pronadje data sifra predmeta u niz se dodaje odgovarajuca sifra profesora
            if sifra_predmeta == ocena["sifra_predmeta"] and \
            "sifra_profesora" in ocena and ocena["sifra_profesora"] != "":
                sifre_profesora.append(ocena["sifra_profesora"])
    # ukoliko nije pronadjen nijedan profesor za datu sifru stampa se obavestenje o tome
    if sifre_profesora == []:
        print("- Nijedan profesor ne predaje taj predmet")
    else:
        profesori = ucitaj_listu_profesora()
        # stampanje profesora koji predaju predmet sa odgovarajucom sifrom
        for profesor in profesori:
            sifra_profesora = int(profesor.split(";")[0])
            if sifra_profesora in sifre_profesora:
                ime = profesor.split(";")[2]
                prezime = profesor.split(";")[3]
                email = profesor.split(";")[4]
                konsultacije = profesor.split(";")[5].strip()
                print("- Ime: " + ime + " " + prezime + ", email: " + email + ", konsultacije: " + konsultacije)
def brisanje_ocene(sifra_profesora):
    """ Funkcija brisanje_ocene najpre pretražuje profesoru studente spram imena,
        prikazuje sve ocene studenta naspram broja indeksa i omogućava brisanje prikazanih ocena
    """
    print("\nBrisanje ocene studentu")
    ime = input("Unesite ime studenta (bez prezimena): ")
    studenti = ucitaj_listu_studenata()
    filtrirani_studenti = []
    filtrirani_brojevi_indeksa = []
    # pretrazivanje studenata sa unetim imenom
    for student in studenti:
        if ime.lower() == student["ime"].lower():
            filtrirani_studenti.append(student)
            filtrirani_brojevi_indeksa.append(student["broj indeksa"])
    # ukoliko ne postoji student sa unetim imenom program se prekida
    if not len(filtrirani_studenti):
        print("- Nema studenata se imenom", ime)
        return
    # ukoliko postoji student sa unetim imenom stampa se njegov broj indeksa, ime i prezime
    for i in range(len(filtrirani_studenti)):
        print(str(i + 1) + ".", filtrirani_studenti[i]["broj indeksa"], \
        filtrirani_studenti[i]["ime"], filtrirani_studenti[i]["prezime"])
    # uneti broj indeksa mora odgovara unetom imenu
    broj_indeksa = None
    while broj_indeksa not in filtrirani_brojevi_indeksa:
        try:
            broj_indeksa = int(input("Unesite broj indeksa studenta: "))
        except ValueError:
            continue
    # brojac predstavlja broj ocena prijavljenog profesora
    brojac = 0
    for student in studenti:
        # trazenje izabranog studenta
        if broj_indeksa == student["broj indeksa"]:
            ocene = student["ocene"]
            # stampanje profesorovih ocena ukoliko postoje, prekid programa ako ih nema
            for ocena in ocene:
                if sifra_profesora == ocena["sifra_profesora"]:
                    brojac += 1
                    print(
                        str(brojac) + ".", ocena["sifra_predmeta"],
                        ocena["ocena"])
            if brojac == 0:
                print(
                    "- Prijavljeni profesor nema nijednu ocenu za odabranog studenta"
                )
                return
            # odabir ocene koja se brise
            redni_broj = None
            while redni_broj not in range(1, brojac + 1):
                try:
                    redni_broj = int(
                        input(
                            "Unesite redni broj ocene koju želite da obrišete(1/.../n): "
                        ))
                except ValueError:
                    continue
            # brojace se resetuje, i povecava dok se ne izjednaci sa rednim brojem odabrane ocene
            brojac = 0
            # trazenje i brisanje izabrane ocene
            for i in range(len(ocene)):
                if sifra_profesora == ocene[i]["sifra_profesora"]:
                    if redni_broj == brojac + 1:
                        student["ocene"].pop(i)
                        sacuvaj_listu_studenata(studenti)
                        print("- Uspešno brisanje ocene")
                        return
                    else:
                        brojac += 1
def registracija():
    """ Funkcija registracija zahteva podatke koji opisuju profesora ili studenta,
        u zavisnosti od izbora korisnika
    """
    print("\nRegistracija")
    print("1. Profesor")
    print("2. Student")
    opcija = None
    while opcija not in (1, 2):
        try:
            opcija = int(input("Koga zelite da registrujete (1/2)? "))
        except ValueError:
            continue
    # pokusaj registrovanja profesora
    if opcija == 1:
        print("\nRegistracija profesora")
        while True:
            try:
                korisnicko_ime = int(
                    input(
                        "Unesite korisnicko ime (ceo broj) - šifra profesora: "
                    ))
                break
            except ValueError:
                continue
        profesori = ucitaj_listu_profesora()
        # provera postojanja datog korisnickog imena (sifre profesora) u bazi profesora
        for profesor in profesori:
            prof_korisnicko_ime = int(profesor.split(";")[0])
            if korisnicko_ime == prof_korisnicko_ime:
                print("- Korisnicko ime (sifra profesora) je zauzeta")
                return
        # ukoliko funkcija nije prekinuta (korisnicko ime nije zauzeto)
        # traze se preostali podaci, i novi_profesor se dodaje u bazu
        lozinka = input("Unesite lozinku: ")
        ime = input("Unesite ime: ")
        prezime = input("Unesite prezime: ")
        email = input("Unesite email adresu: ")
        konsultacije = input("Unesite termin konsultacija (dan, vreme): ")
        novi_profesor = str(
            korisnicko_ime
        ) + ";" + lozinka + ";" + ime + ";" + prezime + ";" + email + ";" + konsultacije + "\n"
        profesori.append(novi_profesor)
        sacuvaj_listu_profesora(profesori)
        print("- Uspešna registracija profesora")
    # pokusaj registrovanja studenta
    elif opcija == 2:
        print("\nRegistracija studenta")
        while True:
            try:
                korisnicko_ime = int(
                    input(
                        "Unesite korisnicko ime (ceo broj) - broj indeksa: "))
                break
            except ValueError:
                continue
        studenti = ucitaj_listu_studenata()
        # provera postojanja datog korisnickog imena (broj indeksa) u bazi studenata
        for student in studenti:
            stud_korisnicko_ime = student["broj indeksa"]
            if korisnicko_ime == stud_korisnicko_ime:
                print("- Korisnicko ime (broj indeksa) je zauzet")
                return
        # ukoliko funkcija nije prekinuta (korisnicko ime nije zauzeto)
        # traze se preostali podaci, i novi_student se dodaje u bazu
        lozinka = input("Unesite lozinku: ")
        ime = input("Unesite ime: ")
        prezime = input("Unesite prezime: ")
        email = input("Unesite email adresu: ")
        novi_student = {
            "broj indeksa": korisnicko_ime,
            "lozinka": lozinka,
            "ime": ime,
            "prezime": prezime,
            "email": email,
            "ocene": []
        }
        studenti.append(novi_student)
        sacuvaj_listu_studenata(studenti)
        print("- Uspešna registracija studenta")