Tutti gli altri (6-10)
This commit is contained in:
@@ -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>
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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');
|
||||
});
|
||||
@@ -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); }
|
||||
}
|
||||
191
JS_Esercizi/JS_Esercizi 09 - Manipolazione Dati/index.html
Normal file
191
JS_Esercizi/JS_Esercizi 09 - Manipolazione Dati/index.html
Normal 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>
|
||||
116
JS_Esercizi/JS_Esercizi 09 - Manipolazione Dati/styles.css
Normal file
116
JS_Esercizi/JS_Esercizi 09 - Manipolazione Dati/styles.css
Normal 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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user