import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); } import { useState, useEffect, useCallback } from "react" import { Studente, Corso, Esame } from "./modelli" import { fetchAPI, handleError } from "./utils" const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:3000" const TIMEOUT = 5_000 async function fetchStudente(matricola: number): Promise<Studente | null> { try { const res = await fetch(`${API_BASE}/studenti/${matricola}`, { signal: AbortSignal.timeout(TIMEOUT), headers: { "Content-Type": "application/json" }, }) if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`) return (await res.json()) as Studente } catch (err) { handleError(err) return null } } export function useStudente(matricola: number) { const [studente, setStudente] = useState<Studente | null>(null) const [loading, setLoading] = useState(false) const [error, setError] = useState<string | null>(null) const load = useCallback(async () => { setLoading(true) setError(null) const data = await fetchStudente(matricola) if (data) setStudente(data) else setError("Studente non trovato") setLoading(false) }, [matricola]) useEffect(() => { load() }, [load]) return { studente, loading, error, reload: load } } def calcola_media(voti: list[float], pesi: list[float] | None = None) -> float: if not voti: return 0.0 if pesi is None: return sum(voti) / len(voti) if len(voti) != len(pesi): raise ValueError("voti e pesi devono avere la stessa lunghezza") return sum(v * p for v, p in zip(voti, pesi)) / sum(pesi) class Studente: __slots__ = ("nome", "cognome", "matricola", "_voti") def __init__(self, nome: str, cognome: str, matricola: int) -> None: self.nome = nome self.cognome = cognome self.matricola = matricola self._voti: list[tuple[str, float, int]] = [] def registra_voto(self, corso: str, voto: float, cfu: int) -> None: if not (18 <= voto <= 30): raise ValueError(f"voto non valido: {voto!r}") self._voti.append((corso, voto, cfu)) @property def media_ponderata(self) -> float: if not self._voti: return 0.0 return sum(v * c for _, v, c in self._voti) / sum(c for _, _, c in self._voti) def __repr__(self) -> str: return f"Studente({self.nome!r}, media={self.media_ponderata:.2f})" public class GestoreCorsi { private final Map<String, Corso> corsi = new HashMap<>(); private final List<Iscrizione> iscrizioni = new ArrayList<>(); public void aggiungiCorso(String codice, String nome, int cfu) { if (corsi.containsKey(codice)) throw new IllegalArgumentException("Corso già presente: " + codice); corsi.put(codice, new Corso(codice, nome, cfu)); } public Optional<Corso> trovaCorsoByCodice(String codice) { return Optional.ofNullable(corsi.get(codice)); } public List<Corso> corsiConPiuDi(int cfu) { return corsi.values().stream() .filter(c -> c.getCfu() > cfu) .sorted(Comparator.comparing(Corso::getNome)) .collect(Collectors.toList()); } public double mediaVotiStudente(int matricola) { return iscrizioni.stream() .filter(i -> i.getMatricola() == matricola) .mapToDouble(Iscrizione::getVoto) .average() .orElse(0.0); } } function mergeSort(arr: number[]): number[] { if (arr.length <= 1) return arr const mid = Math.floor(arr.length / 2) const left = mergeSort(arr.slice(0, mid)) const right = mergeSort(arr.slice(mid)) return merge(left, right) } function merge(left: number[], right: number[]): number[] { const result: number[] = [] let i = 0, j = 0 while (i < left.length && j < right.length) { result.push(left[i] <= right[j] ? left[i++] : right[j++]) } return result.concat(left.slice(i), right.slice(j)) } #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Nodo { int valore; struct Nodo *sinistro; struct Nodo *destro; } Nodo; Nodo *crea_nodo(int valore) { Nodo *n = malloc(sizeof(Nodo)); if (!n) { perror("malloc"); exit(EXIT_FAILURE); } n->valore = valore; n->sinistro = n->destro = NULL; return n; } Nodo *inserisci(Nodo *radice, int valore) { if (!radice) return crea_nodo(valore); if (valore < radice->valore) radice->sinistro = inserisci(radice->sinistro, valore); else if (valore > radice->valore) radice->destro = inserisci(radice->destro, valore); return radice; } void inorder(const Nodo *r) { if (!r) return; inorder(r->sinistro); printf("%d ", r->valore); inorder(r->destro); } int altezza(const Nodo *r) { if (!r) return 0; int sx = altezza(r->sinistro); int dx = altezza(r->destro); return 1 + (sx > dx ? sx : dx); }
Ripetizioni di programmazione online
Per superare l'esame capendo davvero
quello che
scrivi.Per superare l'esame capendo davvero
quello che
scrivi.
Tutoraggio individuale per studenti universitari e delle scuole superiori. Un metodo per pensare, non un linguaggio da memorizzare.
Inizia gratis →