rinomina esercizi js
This commit is contained in:
93
javascript/09_Manipolazione Dati/tutorial/index.html
Normal file
93
javascript/09_Manipolazione Dati/tutorial/index.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<!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>
|
||||
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold;">← Dashboard</a>
|
||||
</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:"
|
||||
},
|
||||
{
|
||||
title: "6. Template Literals",
|
||||
description: "Creare stringhe dinamiche con variabili e espressioni.",
|
||||
outputLabel: "Card HTML:"
|
||||
}
|
||||
].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="script.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>
|
||||
164
javascript/09_Manipolazione Dati/tutorial/script.js
Normal file
164
javascript/09_Manipolazione Dati/tutorial/script.js
Normal file
@@ -0,0 +1,164 @@
|
||||
// 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
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* ======================================================
|
||||
* LIVELLO 6: Creazione Card Utente (Template Literals)
|
||||
* Crea una card HTML usando i template literals (backticks)
|
||||
* ======================================================
|
||||
*/
|
||||
const utente = {
|
||||
nome: "Mario",
|
||||
cognome: "Rossi",
|
||||
email: "mario.rossi@esempio.com",
|
||||
avatar: "https://randomuser.me/api/portraits/men/75.jpg"
|
||||
};
|
||||
|
||||
// TODO: Crea una card HTML usando i dati dell'utente e i template literals
|
||||
// Per fare i backticks usa ALT + 96 sulla tastiera
|
||||
// La card dovrebbe avere questa struttura:
|
||||
/*
|
||||
<div class="user-card">
|
||||
<img src="avatar_url" alt="Avatar" class="user-avatar">
|
||||
<div class="user-info">
|
||||
<h3>Nome Cognome</h3>
|
||||
<p class="user-email">📧 email</p>
|
||||
</div>
|
||||
</div>
|
||||
*/
|
||||
let cardHTML = null;
|
||||
|
||||
mostraOutput(6, {});
|
||||
let output = document.getElementById('output-6');
|
||||
output.className = '';
|
||||
output.innerHTML = cardHTML;
|
||||
}
|
||||
146
javascript/09_Manipolazione Dati/tutorial/styles.css
Normal file
146
javascript/09_Manipolazione Dati/tutorial/styles.css
Normal file
@@ -0,0 +1,146 @@
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #f0f2f5;
|
||||
color: #333;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #1a73e8;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.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);
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
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;
|
||||
max-width: 800px;
|
||||
margin: 0 auto 25px auto;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
border-left: 6px solid #1a73e8;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.user-card {
|
||||
background: #f5f5f5;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.user-avatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.user-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.user-name {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
.user-email {
|
||||
font-size: 0.9em;
|
||||
color: #777;
|
||||
}
|
||||
Reference in New Issue
Block a user