Spaces:
Sleeping
Sleeping
| from feature_extraction import extract_all_features | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # UΔITAVANJE MODELA | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| MODEL_NAME = "Salesforce/codegen-350M-mono" | |
| def ucitaj_model(): | |
| try: | |
| from transformers import AutoTokenizer, AutoModelForCausalLM | |
| import torch | |
| print(f" UΔitavam model '{MODEL_NAME}'...") | |
| print(" (Pri prvom pokretanju ovo moΕΎe potrajati par minuta.)\n") | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_NAME, | |
| torch_dtype=torch.float32, # float32 radi na CPU bez GPU-a | |
| ) | |
| model.eval() # iskljuΔi dropout β samo inferenca, ne treniranje | |
| num_params = sum(p.numel() for p in model.parameters()) // 1_000_000 | |
| print(f" Model uΔitan ({num_params}M parametara).\n") | |
| return model, tokenizer | |
| except ImportError: | |
| print(" [UPOZORENJE] transformers ili torch nisu instalirani.") | |
| print(" Pokreni: pip install transformers torch\n") | |
| return None, None | |
| except Exception as e: | |
| print(f" [UPOZORENJE] Model nije mogao biti uΔitan: {e}\n") | |
| return None, None | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # UNOS KODA | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def ucitaj_kod() -> str: | |
| print("Zalijepi kod ispod, a kad zavrΕ‘iΕ‘ pritisni Enter dva puta:\n") | |
| linije = [] | |
| prazni_zaredom = 0 | |
| while True: | |
| linija = input() | |
| if linija == "": | |
| prazni_zaredom += 1 | |
| if prazni_zaredom >= 2: | |
| break | |
| linije.append(linija) | |
| else: | |
| prazni_zaredom = 0 | |
| linije.append(linija) | |
| return "\n".join(linije).strip() | |
| def ucitaj_iz_datoteke(putanja: str) -> str: | |
| try: | |
| with open(putanja, "r", encoding="utf-8") as f: | |
| sadrzaj = f.read() | |
| print(f" UΔitano {len(sadrzaj.splitlines())} linija iz '{putanja}'.") | |
| return sadrzaj | |
| except FileNotFoundError: | |
| print(f"\n [GREΕ KA] Datoteka '{putanja}' nije pronaΔena.") | |
| print( " Provjeri je li datoteka u istom folderu kao main.py.") | |
| return "" | |
| except Exception as e: | |
| print(f"\n [GREΕ KA] Problem pri Δitanju datoteke: {e}") | |
| return "" | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # ISPIS REZULTATA | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def ispisi_znacajke(features: dict) -> None: | |
| jezik = features.get("detected_language", "nepoznat") | |
| print(f"\n{'β' * 55}") | |
| print(f" Prepoznat jezik: {jezik.upper()}") | |
| print(f"{'β' * 55}") | |
| # ββ Stilska detekcija ββββββββββββββββββββββββββββββββββββββ | |
| print("\n [ STILSKA DETEKCIJA β komentari, imenovanje, formatiranje ]\n") | |
| stilske = [ | |
| ("Broj linija s komentarom", "num_comment_lines"), | |
| ("Udio komentara (%)", "comment_ratio"), | |
| ("Prosj. duljina komentara (rij.)", "avg_comment_length_words"), | |
| ("Udio komentara u znakovima", "comment_to_code_ratio"), | |
| ("Broj blok komentara", "num_block_comments"), | |
| ("Broj docstringova / JSDoc", "num_docstrings"), | |
| ("Prosj. duljina identifikatora", "avg_identifier_length"), | |
| ("Prosj. duljina naziva funkcija", "avg_function_name_length"), | |
| ("Udio jednoslovnih naziva", "single_char_name_ratio"), | |
| ("LeksiΔka raznolikost naziva", "lexical_diversity"), | |
| ("Udio snake_case stila", "snake_case_ratio"), | |
| ("Udio camelCase stila", "camel_case_ratio"), | |
| ("Konzistentnost imenovanja", "naming_consistency"), | |
| ("Ukupno linija", "total_lines"), | |
| ("Udio praznih linija", "empty_line_ratio"), | |
| ("Prosj. duljina linije (znakovi)", "avg_line_length"), | |
| ("Max duljina linije", "max_line_length"), | |
| ("Koristi tabove (1=da, 0=ne)", "uses_tabs"), | |
| ("Udio linija s trailing space", "trailing_whitespace_ratio"), | |
| ("Konzistentnost razmaka operatori", "operator_spacing_consistency"), | |
| ] | |
| for naziv, kljuc in stilske: | |
| val = features.get(kljuc, "N/A") | |
| if isinstance(val, float): | |
| print(f" {naziv:<38} {val:.4f}") | |
| else: | |
| print(f" {naziv:<38} {val}") | |
| # ββ Strukturna detekcija βββββββββββββββββββββββββββββββββββ | |
| print("\n [ STRUKTURNA DETEKCIJA β AST, sloΕΎenost, tok kontrole ]\n") | |
| strukturne = [ | |
| ("Dubina AST stabla", "ast_depth"), | |
| ("Broj Δvorova u AST stablu", "ast_node_count"), | |
| ("Raznolikost tipova Δvorova", "unique_node_type_ratio"), | |
| ("Broj funkcija / metoda", "num_functions"), | |
| ("Prosj. duljina funkcije (linije)", "avg_function_length"), | |
| ("Max duljina funkcije (linije)", "max_function_length"), | |
| ("Prosj. broj argumenata", "avg_args_per_function"), | |
| ("Broj klasa", "num_classes"), | |
| ("Broj importa", "num_imports"), | |
| ("Broj if naredbi", "num_if_statements"), | |
| ("Broj for petlji", "num_for_loops"), | |
| ("Broj while petlji", "num_while_loops"), | |
| ("Broj try/catch blokova", "num_try_blocks"), | |
| ("Broj lambda izraza", "num_lambdas"), | |
| ("Max dubina ugnijeΕΎΔenosti", "max_nesting_depth"), | |
| ("Prosj. dubina ugnijeΕΎΔenosti", "avg_nesting_depth"), | |
| ("Aproks. ciklomatska sloΕΎenost", "cyclomatic_complexity_approx"), | |
| ] | |
| for naziv, kljuc in strukturne: | |
| val = features.get(kljuc, "N/A") | |
| if isinstance(val, float): | |
| print(f" {naziv:<38} {val:.4f}") | |
| else: | |
| print(f" {naziv:<38} {val}") | |
| # ββ StatistiΔka detekcija ββββββββββββββββββββββββββββββββββ | |
| print("\n [ STATISTIΔKA DETEKCIJA β perplexity ]\n") | |
| perp = features.get("perplexity", -1.0) | |
| dostupan = features.get("model_available", 0) | |
| if dostupan == 0: | |
| print(" Model nije uΔitan β perplexity nije izraΔunat.") | |
| else: | |
| print(f" {'Perplexity':<38} {perp:.4f}") | |
| # Grubo tumaΔenje perplexityja za CodeGEN-350M | |
| if perp < 5: | |
| tumacenje = "vrlo nizak β vjerojatno AI" | |
| elif perp < 20: | |
| tumacenje = "nizak β moguΔe AI" | |
| elif perp < 60: | |
| tumacenje = "srednji β nejasno" | |
| else: | |
| tumacenje = "visok β vjerojatno Δovjek" | |
| print(f" {'TumaΔenje':<38} {tumacenje}") | |
| print(f"\n{'β' * 55}") | |
| print(f" Ukupno izvuΔeno znaΔajki: {len(features) - 1}") | |
| print(f"{'β' * 55}\n") | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # GLAVNI PROGRAM | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def main(): | |
| print("=" * 55) | |
| print(" Ekstraktor znaΔajki koda") | |
| print(" (za detekciju AI generiranog koda)") | |
| print("=" * 55) | |
| # Pitaj korisnika ΕΎeli li uΔitati model za perplexity | |
| print("\nΕ½eliΕ‘ li uΔitati model za izraΔun perplexityja?") | |
| print(" d β Da (skida ~700 MB pri prvom pokretanju)") | |
| print(" n β Ne (perplexity Δe biti preskoΔen)\n") | |
| odabir_model = input("Odabir (d/n): ").strip().lower() | |
| model, tokenizer = None, None | |
| if odabir_model in ("d", "da", "y", "yes"): | |
| model, tokenizer = ucitaj_model() | |
| # NaΔin unosa koda | |
| print("\nNaΔin unosa koda:") | |
| print(" 1 β Zalijepi kod direktno u terminal") | |
| print(" 2 β UΔitaj iz datoteke (npr. kod.txt)") | |
| while True: | |
| print() | |
| odabir = input("Odaberi naΔin unosa (1 ili 2): ").strip() | |
| if odabir == "1": | |
| kod = ucitaj_kod() | |
| elif odabir == "2": | |
| putanja = input("Putanja do datoteke (Enter za 'kod.txt'): ").strip() | |
| if putanja == "": | |
| putanja = "kod.txt" | |
| kod = ucitaj_iz_datoteke(putanja) | |
| else: | |
| print(" Unesi 1 ili 2.") | |
| continue | |
| if not kod: | |
| print(" Kod je prazan. PokuΕ‘aj ponovno.") | |
| continue | |
| print("\nIzvlaΔim znaΔajke...") | |
| znacajke = extract_all_features(kod, model=model, tokenizer=tokenizer) | |
| ispisi_znacajke(znacajke) | |
| odgovor = input("Ε½eliΕ‘ li analizirati joΕ‘ jedan isjeΔak koda? (da/ne): ") | |
| if odgovor.strip().lower() not in ("da", "d", "yes", "y"): | |
| print("\nZatvaram program.") | |
| break | |
| if __name__ == "__main__": | |
| main() | |