Tutti gli altri (6-10)

This commit is contained in:
2026-02-03 00:08:30 +01:00
parent 0043f1f83f
commit e6f6f17769
54 changed files with 3205 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Calcolatrice JS</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold;">← Dashboard</a>
<div class="calcolatrice">
<input type="text" id="display" placeholder="Es: 10 + 5">
<div id="messaggio-errore" class="nascosto">⚠️ Formato errato! Usa: num spazio op spazio num</div>
<div class="tastiera">
<button class="tasto">7</button>
<button class="tasto">8</button>
<button class="tasto">9</button>
<button class="tasto op">/</button>
<button class="tasto">4</button>
<button class="tasto">5</button>
<button class="tasto">6</button>
<button class="tasto op">*</button>
<button class="tasto">1</button>
<button class="tasto">2</button>
<button class="tasto">3</button>
<button class="tasto op">-</button>
<button class="tasto" id="btn-cancella">C</button>
<button class="tasto">0</button>
<button class="tasto" id="btn-uguale">=</button>
<button class="tasto op">+</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,94 @@
// SELEZIONE ELEMENTI
const display = document.querySelector('#display');
const btnUguale = document.querySelector('#btn-uguale');
const btnCancella = document.querySelector('#btn-cancella');
const msgErrore = document.querySelector('#messaggio-errore');
// Selezioniamo tutti i tasti "normali" (numeri e operazioni) per farli scrivere nel display
const tasti = document.querySelectorAll('.tasto:not(#btn-uguale):not(#btn-cancella)');
// Array di operatori validi (utile per la validazione)
const operatoriValidi = ['+', '-', '*', '/'];
/**
* 1. FUNZIONE: Aggiungi caratteri al display
* Per ogni tasto, aggiungiamo un event listener che, quando cliccato,
* prende il testo del tasto e lo aggiunge al display.
* Bisono fare attenzione agli spazi per gli operatori.
*
* Passi:
* - Per ogni tasto, aggiungiamo un event listener
* - Quando clicchiamo, prendiamo il testo del tasto e lo aggiungiamo al display
* - Se è un operatore, aggiungiamo spazi prima e dopo per facilitare il calcolo
* - Altrimenti aggiungiamo solo il numero
*/
/**
* 2. FUNZIONE: Cancella display
* Quando clicchiamo il tasto "C", il display deve essere svuotato.
*
* Passi:
* - Aggiungiamo un event listener al tasto "C"
* - Quando clicchiamo, svuotiamo il valore del display
*/
/**
* 3. FUNZIONE: Calcola
* Prendiamo in input un numero, un operatore e un altro numero,
* e restituiamo il risultato del calcolo in base all'operatore.
* Se l'operatore non è valido, mostriamo un messaggio di errore.
*
* Passi:
* - Prendiamo in input il primo numero, l'operatore e il secondo numero
* - In base all'operatore, eseguiamo il calcolo
* - Restituiamo il risultato
* - Se l'operatore non è valido, mostriamo un messaggio di errore con mostraErrore() e restituiamo null
* Nota: Si può usare uno switch per semplicità senza break (dato che restituiamo subito il risultato)
*/
function calcola(num1, operatore, num2) {
}
/**
* 4. FUNZIONE: Calcola risultato
* Quando clicchiamo il tasto "=", dobbiamo prendere il testo del display,
* analizzarlo, eseguire il calcolo e mostrare il risultato.
*
* Passi:
* A. Prendi il testo del display e puliscilo (rimuovi spazi inutili all'inizio e alla fine)
* B. Spezza la stringa in parti (numero, operatore, numero) in base agli spazi
* C. Valida i dati:
* - Controlla che ci siano esattamente 3 pezzi
* - Controlla che i numeri siano validi (trasforma e controlla non NaN)
* - Controlla che l'operatore sia valido (tra quelli definiti)
* D. Esegui il calcolo chiamando la funzione calcola()
* E. Mostra il risultato nel display
*/
function calcolaRisultato() {
}
/****************************************************/
/********* FUNZIONI HELPER E EVENT LISTENER *********/
/****************************************************/
function mostraErrore() {
msgErrore.classList.remove('nascosto');
display.style.borderColor = "red";
setTimeout(() => {
display.style.borderColor = "#bdc3c7";
msgErrore.classList.add('nascosto');
}, 2000);
}
// Aggiungiamo gli event listener per il calcolo del risultato
btnUguale.addEventListener('click', calcolaRisultato);
// Permettiamo anche di premere "Enter" per calcolare
display.addEventListener('keypress', (e) => {
if (e.key === 'Enter') calcolaRisultato();
});

View File

@@ -0,0 +1,79 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.calcolatrice {
background: #ecf0f1;
padding: 20px;
border-radius: 10px;
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
width: 300px;
}
#display {
width: 100%;
padding: 15px;
font-size: 1.5rem;
text-align: right;
margin-bottom: 10px;
border: 2px solid #bdc3c7;
border-radius: 5px;
box-sizing: border-box; /* Importante per il padding */
}
#messaggio-errore {
color: red;
font-size: 0.8rem;
text-align: center;
margin-bottom: 10px;
height: 20px; /* Per non far saltare il layout */
}
.nascosto {
visibility: hidden; /* Nasconde ma tiene lo spazio */
}
.tastiera {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 colonne uguali */
gap: 10px;
}
.tasto {
padding: 20px;
font-size: 1.2rem;
border: none;
background: white;
border-radius: 5px;
cursor: pointer;
transition: 0.2s;
}
.tasto:hover {
background-color: #dfe6e9;
}
.tasto.op {
background-color: #f39c12;
color: white;
}
.tasto.op:hover {
background-color: #e67e22;
}
#btn-uguale {
background-color: #27ae60;
color: white;
}
#btn-cancella {
background-color: #c0392b;
color: white;
}

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Username Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold;">← Dashboard</a>
<div class="card-generator">
<h2>🆔 Crea il tuo Username</h2>
<p>Inserisci i tuoi dati, genereremo un nome utente sicuro.</p>
<div class="input-group">
<label>Nome</label>
<input type="text" id="input-nome" placeholder="Es: Mario ">
</div>
<div class="input-group">
<label>Cognome</label>
<input type="text" id="input-cognome" placeholder="Es: Rossi Esposito">
</div>
<button id="btn-genera">Genera Username</button>
<div id="box-risultato" class="hidden">
<p>Username suggerito:</p>
<div id="output-username" class="username-box">...</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,56 @@
// SELEZIONE ELEMENTI DOM
const inputNome = document.querySelector('#input-nome');
const inputCognome = document.querySelector('#input-cognome');
const btnGenera = document.querySelector('#btn-genera');
const boxRisultato = document.querySelector('#box-risultato');
const outputUsername = document.querySelector('#output-username');
/**
* FUNZIONE: Genera Username
* Obiettivo: Creare un username formato da:
* [Prime 3 lettere Nome] + [Cognome Pulito] + [Numero Random]
* Tutto in minuscolo.
* * Passi da completare:
* 1. Recupera i valori degli input (nome e cognome).
* 2. Validazione: se uno dei due è vuoto, avvisa con alert() e fermati.
* 3. Pulizia NOME:
* - Rimuovi spazi vuoti ai lati (.trim())
* - Prendi solo le prime 3 lettere (.slice(0, 3) oppure .substring(0, 3))
* - Converti in minuscolo (.toLowerCase())
* 4. Pulizia COGNOME:
* - Rimuovi spazi vuoti ai lati (.trim())
* - Sostituisci eventuali spazi interni (es. "De Luca") con un punto o niente (.replace(" ", "") oppure .replaceAll)
* - Converti in minuscolo
* 5. Genera un numero casuale tra 10 e 99 (Math.random, Math.floor).
* 6. Unisci tutto (Nome + Cognome + Numero) e mostralo nell'output.
*/
btnGenera.addEventListener('click', function() {
// --- SCRIVI QUI IL TUO CODICE ---
// 1. Leggi
// let nome = ...
// let cognome = ...
// 2. Valida
// 3. Elabora Nome (trim, slice, toLowerCase)
// let parteNome = ...
// 4. Elabora Cognome (trim, replace, toLowerCase)
// let parteCognome = ...
// 5. Numero Random (tra 10 e 99)
// Formula: Math.floor(Math.random() * (max - min + 1)) + min
// let numero = ...
// 6. Output
// let risultato = ...
// outputUsername.textContent = risultato;
// --- FINE CODICE ---
// Mostra il risultato
boxRisultato.classList.remove('hidden');
});

View File

@@ -0,0 +1,91 @@
body {
font-family: 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.card-generator {
background: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
width: 350px;
text-align: center;
}
.input-group {
text-align: left;
margin-bottom: 15px;
}
label {
display: block;
font-size: 0.9rem;
color: #666;
margin-bottom: 5px;
}
input {
width: 100%;
padding: 10px;
border: 2px solid #eee;
border-radius: 8px;
font-size: 1rem;
box-sizing: border-box;
transition: 0.3s;
}
input:focus {
border-color: #6c5ce7;
outline: none;
}
button {
width: 100%;
padding: 12px;
background-color: #6c5ce7;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
margin-top: 10px;
transition: 0.2s;
}
button:hover {
background-color: #5649c0;
transform: translateY(-2px);
}
.hidden {
display: none;
}
#box-risultato {
margin-top: 25px;
padding-top: 20px;
border-top: 1px solid #eee;
animation: fadeIn 0.5s;
}
.username-box {
background: #f0f3f4;
color: #2d3436;
font-family: 'Courier New', monospace;
font-size: 1.4rem;
font-weight: bold;
padding: 10px;
border-radius: 8px;
letter-spacing: 1px;
border: 1px dashed #b2bec3;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}

View File

@@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hub Esercizi DOM</title>
<style>
/* RESET & BASE */
* {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
margin: 0;
padding: 40px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
/* CONTENITORE PRINCIPALE */
.hub-container {
background: white;
width: 100%;
max-width: 650px;
padding: 40px;
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 5px;
font-size: 2.5rem;
}
p.subtitle {
text-align: center;
color: #666;
margin-bottom: 40px;
font-size: 1.1rem;
}
/* LISTA CARD */
.exercise-list {
display: flex;
flex-direction: column;
gap: 15px;
}
/* CARD ESERCIZIO */
.card {
display: flex;
align-items: center;
text-decoration: none;
background: #fff;
border: 2px solid #f0f0f0;
border-radius: 12px;
padding: 20px;
transition: all 0.2s ease;
}
.card:hover {
transform: translateY(-3px);
border-color: #007bff;
box-shadow: 0 5px 15px rgba(0, 123, 255, 0.1);
}
/* ICONA E TESTI */
.icon {
font-size: 2rem;
margin-right: 20px;
width: 40px;
text-align: center;
}
.info {
flex: 1;
}
.info h3 {
margin: 0 0 5px 0;
color: #2c3e50;
font-size: 1.1rem;
display: flex;
align-items: center;
}
.info p {
margin: 0;
color: #7f8c8d;
font-size: 0.9rem;
}
/* TAG DIFFICOLTA' */
.badge {
font-size: 0.7rem;
font-weight: bold;
padding: 3px 8px;
border-radius: 6px;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-left: 10px;
}
.tutorial {
background-color: #e3f2fd;
color: #1565c0;
border: 1px solid #bbdefb;
}
/* Blu */
.easy {
background-color: #e8f5e9;
color: #2e7d32;
}
/* Verde */
.medium {
background-color: #fff3e0;
color: #ef6c00;
}
/* Arancione */
.hard {
background-color: #ffebee;
color: #c62828;
}
/* Rosso */
/* FRECCIA AL PASSAGGIO DEL MOUSE */
.arrow {
font-size: 1.5rem;
color: #ddd;
transition: 0.3s;
}
.card:hover .arrow {
color: #007bff;
transform: translateX(5px);
}
</style>
</head>
<body>
<div class="hub-container">
<h1>Esercizi DOM</h1>
<p class="subtitle">Corso Web Developer</p>
<div class="exercise-list">
<a href="tutorial.html" class="card">
<div class="icon">🧪</div>
<div class="info">
<h3>Tutorial<span class="badge tutorial">Tutorial</span></h3>
<p>Impara a pulire stringhe, gestire numeri e filtrare array.</p>
</div>
<div class="arrow"></div>
</a>
<a href="calcolatrice/index.html" class="card">
<div class="icon">🧮</div>
<div class="info">
<h3>Calcolatrice <span class="badge medium">Logica</span></h3>
<p>Validazione input, Parsing numeri, Switch case.</p>
</div>
<div class="arrow"></div>
</a>
<a href="generatore_utenti/index.html" class="card">
<div class="icon">👤</div>
<div class="info">
<h3>Generatore Utenti<span class="badge medium">Stringhe</span></h3>
<p>Manipolazione stringhe, generazione numeri casuali.</p>
</div>
<div class="arrow"></div>
</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,116 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f0f2f5;
color: #333;
max-width: 900px;
margin: 0 auto;
}
h1 {
text-align: center;
color: #1a73e8;
}
.controls {
text-align: center;
margin-bottom: 30px;
position: sticky;
top: 0px;
z-index: 100;
background-color: white;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}
button {
padding: 12px 24px;
font-size: 16px;
cursor: pointer;
background-color: #1a73e8;
color: white;
border: none;
border-radius: 10px;
margin: 5px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.1s;
}
button:hover {
transform: scale(1.05);
}
button:active {
transform: scale(0.95);
}
button#btn-reset {
background-color: #ea4335;
}
.step-card {
background: white;
border-radius: 12px;
padding: 20px;
margin-bottom: 25px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-left: 6px solid #1a73e8;
margin: 20px;
}
.step-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.step-title {
font-weight: bold;
font-size: 1.2em;
color: #1557b0;
}
.step-desc {
font-size: 0.95em;
color: #5f6368;
margin-bottom: 15px;
line-height: 1.5;
}
.output-box {
background: #2d3436;
color: #00c900;
padding: 10px;
font-family: 'Courier New', monospace;
border-radius: 6px;
min-height: 20px;
white-space: pre-wrap;
overflow-x: auto;
position: relative;
}
.output-box.loading::after {
content: "⏳ Attesa server...";
position: absolute;
top: 5px;
right: 5px;
font-size: 0.8em;
color: #e5c07b;
}
.output-box.error {
border: 2px solid #e06c75;
color: #e06c75;
}
.output-box.success {
border-left: 4px solid #98c379;
}
.label {
font-size: 0.8em;
color: #bbbbbb;
margin-bottom: 5px;
display: block;
font-weight: bold;
letter-spacing: 0.5px;
}

View File

@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Manipolazione Dati</title>
</head>
<body>
<div class="controls">
<h1>Tutorial: Manipolazione Dati</h1>
<button id="btn-esegui">▶️ Esegui Codice</button>
<button id="btn-reset">🧹 Pulisci Console</button>
</div>
<script>
function mostraOutput(stepNumero, messaggio) {
const elemento = document.getElementById(`output-${stepNumero}`);
if (elemento) {
messaggio = messaggio || "❌";
let isObject = (typeof messaggio === 'object' && messaggio !== null);
elemento.textContent = isObject ? JSON.stringify(messaggio, null, 2) : String(messaggio);
elemento.classList.remove("loading");
elemento.style.transition = "";
elemento.style.backgroundColor = "#666";
setTimeout(() => {
elemento.style.transition = "background-color 1s ease";
elemento.style.backgroundColor = "#2d3436";
}, 0);
}
}
[
{
title: "1. Normalizzazione Stringhe",
description: "Pulizia spazi (trim) e gestione Maiuscole/Minuscole.",
outputLabel: "Stringa pulita:"
},
{
title: "2. Analisi ed Estrazione",
description: "Cercare parole (includes) e dividere testi (split).",
outputLabel: "Risultati Analisi:"
},
{
title: "3. Parsing Prezzi",
description: "Da stringa a numero: replace, parseFloat e toFixed.",
outputLabel: "Prezzo formattato:"
},
{
title: "4. Arrotondamenti",
description: "Gestire i decimali: round, ceil (eccesso) e floor (difetto).",
outputLabel: "Peso arrotondato:"
},
{
title: "5. Numeri Casuali",
description: "Generare numeri random e scalarli.",
outputLabel: "Numero casuale:"
}
].forEach((step, i) => {
document.write(`
<div class="step-card">
<div class="step-header">
<div class="step-title">${step.title}</div>
</div>
<div class="step-desc">${step.description}</div>
<span class="label">${step.outputLabel}</span>
<div id="output-${i + 1}" class="output-box"></div>
</div>
`);
});
</script>
<script src="tutorial_interattivo.js"></script>
<script>
document.getElementById('btn-reset').addEventListener('click', () => {
localStorage.clear();
location.reload();
});
document.getElementById('btn-esegui').addEventListener('click', () => {
const el = document.querySelectorAll('[id^="output-"]');
el.forEach(box => box.className = "output-box loading");
eseguiTutorial();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,131 @@
// TUTORIAL INTERATTIVO: Manipolazione Dati
// Funzione pricipale del tutorial
function eseguiTutorial() {
/**
* ======================================================
* LIVELLO 1: Normalizzazione (Stringhe Base)
* Spesso i dati arrivano "sporchi" o scritti male.
* Dobbiamo standardizzarli per poterli usare correttamente.
* ======================================================
*/
let nomeProdotto = " MacBook Pro M3 ";
// TODO 1: Rimuovi gli spazi iniziali e finali (trim)
let nomePulito = "";
// TODO 2: Converti tutto in MAIUSCOLO per il codice magazzino (toUpperCase)
let perMagazzino = "";
// TODO 3: Converti tutto in minuscolo per la ricerca (toLowerCase)
let perRicerca = "";
mostraOutput(1, {
originale: nomeProdotto,
trim: nomePulito,
upper: perMagazzino,
lower: perRicerca
});
/**
* ======================================================
* LIVELLO 2: Estrazione Dati (Stringhe Avanzate)
* Analizziamo una stringa complessa che contiene più informazioni.
* Stringa: "LAPTOP GAMING | 16GB RAM | SSD"
* ======================================================
*/
let descrizione = "LAPTOP GAMING | 16GB RAM | SSD";
// TODO 1: Controlla se la descrizione contiene la parola "SSD" (includes)
// Restituisce true o false
let haSSD = false;
// TODO 2: Spezza la stringa in un array usando il separatore "|" (split)
// Otterrai: ["LAPTOP GAMING ", " 16GB RAM ", " SSD"]
let caratteristiche = [];
mostraOutput(2, {
contiene_ssd: haSSD,
lista_parti: caratteristiche
});
/**
* ======================================================
* LIVELLO 3: Pulizia Prezzi (Parsing Numeri)
* Trasformiamo una stringa di valuta in un numero matematico.
* ======================================================
*/
let prezzoCartellino = "1499.95€";
// TODO 1: Rimuovi il simbolo "€" sostituendolo con niente "" (replace)
let prezzoSenzaSimbolo = prezzoCartellino;
// TODO 2: Converti la stringa rimasta in un numero decimale (parseFloat)
let prezzoNumero = 0;
// TODO 3: Formatta il numero come stringa con 1 solo decimale (toFixed)
// Nota: toFixed restituisce una STRINGA, non un numero!
let prezzoFormat = ""; // ... usa .toFixed(1)
mostraOutput(3, {
stringa_pulita: prezzoSenzaSimbolo,
numero_vero: prezzoNumero,
formattato: prezzoFormat
});
/**
* ======================================================
* LIVELLO 4: Arrotondamenti (Matematica)
* Gestiamo un peso per la spedizione. Spesso i corrieri arrotondano.
* Peso: 1.256 kg
* ======================================================
*/
let peso = 1.256;
// TODO 1: Arrotondamento classico (Math.round)
// 1.2 -> 1, 1.5 -> 2, 1.8 -> 2
let arrotondato = 0;
// TODO 2: Arrotondamento per ECCESSO (Math.ceil - "Soffitto")
// Utile per calcolare quanti pacchi servono (1.1 diventa 2)
let perEccesso = 0;
// TODO 3: Arrotondamento per DIFETTO (Math.floor - "Pavimento")
// 1.9 diventa 1
let perDifetto = 0;
mostraOutput(4, {
originale: peso,
round: arrotondato,
ceil: perEccesso,
floor: perDifetto
});
/**
* ======================================================
* LIVELLO 5: Il dado della fortuna (Random)
* Generiamo uno sconto casuale tra 0 e 100.
* ======================================================
*/
// TODO 1: Genera un numero casuale tra 0 e 1 (Math.random())
let randomBase = 0;
// TODO 2: Trasformalo in un numero tra 0 e 100
// Moltiplica randomBase * 100
let randomCento = 0;
// TODO 3: Rimuovi i decimali per avere un intero (Math.floor)
let scontoFinale = 0;
mostraOutput(5, {
random_puro: randomBase.toFixed(4), // Mostro solo 4 decimali per pulizia
scala_100: randomCento.toFixed(2),
sconto_intero: scontoFinale
});
}