This commit is contained in:
Philippe Torrel
2026-10-01 10:37:23 +02:00
parent 58bdd6018f
commit 02b3745b88
8 changed files with 197 additions and 9 deletions
@@ -8,6 +8,28 @@ const quotedCSV = '"very big, soft computer mouse","the cutest peripheral ever",
const mixedCSV = '"very big, soft computer mouse","the cutest peripheral ever",10,39.90';
const parseCSVRecord = (record) => {
const fields = [];
let field = '';
let inQuotes = false;
for (const character of record) {
if (character === '"') {
inQuotes = !inQuotes;
} else if (character === ',' && !inQuotes) {
fields.push(field);
field = '';
} else {
field += character;
}
}
fields.push(field);
return fields;
};
console.log(parseCSVRecord(quotedCSV));
console.log(parseCSVRecord(mixedCSV));
/*
Übung 25: CSV-Datensätze mit Anführungszeichen
Bisher haben wir die Felder in einem CSV-Datensatz einfach mit der Anweisung:
Binary file not shown.
+45 -1
View File
@@ -3,8 +3,52 @@ import zlib from 'node:zlib';
import color from 'chalk';
const data = fs.readFileSync('data/products.csv', 'utf-8');
const products = data.split('\n');
const header = products.shift().split(',');
// console.log('header', header); // => Code,Short Description,Tagline,Quantity,Price
const convertCsvToJson = (products, ar) => {};
const convertCsvToJson = (productRow) => {
// console.log('products', products);
// console.log('ar', ar);
const cols = productRow.split(/\s*,\s*/);
// console.log(product);
// let obj = {};
// for (let i = 0; i < header.length; i++) {
// obj[header[i]] = cols[i];
// }
const product = header.reduce((obj, str, idx) => {
obj[str] = cols[idx];
return obj;
}, {});
return product;
};
const entries = products
.filter((row) => row !== '') //
.map(convertCsvToJson);
console.log(entries);
// fs.writeFile('a.json', JSON.stringify(entries), 'UTF-8', (err) => {
// console.warn(err);
// });
const compressedData = zlib.gzipSync(JSON.stringify(entries));
try {
fs.writeFileSync('data/products.json.gz', compressedData);
console.log('compressed file');
} catch (err) {
console.error(err);
}
/*
Übung 27: Ohne Umwege
Die Datei products.csv soll in eine products.json umgewandelt werden und in products.json.gz komprimiert werden.
*/
/*
Übung 27: Ohne Umwege
+28
View File
@@ -0,0 +1,28 @@
{
"name": "u27_zlib",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "u27_zlib",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"chalk": "^6.0.1"
}
},
"node_modules/chalk": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
"license": "MIT",
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
}
}
}
@@ -1,16 +1,31 @@
// const crypto = require('node:crypto');
import crypto from 'node:crypto';
import _ from 'lodash';
const PASSWORD_LENGTH = 10;
const s = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ!.,;#$%/+*';
const buf = crypto.randomBytes(PASSWORD_LENGTH);
console.log('s.length:', s.length); // => 64
console.log('buf:', buf); // => <Buffer 9a 28 4f d6 32 7a 6d 44 f0 3e>
console.log('Array:', Array.from(buf)); // => [ 17, 181, 126, 182, 190, 212, 137, 233, 140, 75]
const password = Array.from(buf)
.map((byte) => s.charAt(byte % s.length))
.map((byte) => s.charAt(byte % s.length)) // => kZ+!+pbMed
.join('');
console.log(password);
const generatePassword = (length) => {
const chars = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ!.,;#$%/+*'.split('');
return _.shuffle(chars)
.slice(0, length + 1)
.join('');
};
const pwd = generatePassword(10);
console.log('Password: ', pwd);
// Übung 28: Passwortgenerator
// Was macht der folgende Code?
@@ -18,3 +33,7 @@ console.log(password);
// OK: Der Titel verrät es schon. Versuche dennoch, das Programm zu verstehen! Benutze die Dokumentation der Standardbibliothek, um nachzuschlagen, was crypto.randomBytes(…) genau macht!
// Bonusfrage: Warum sind in den Zeichen «1», «i» und «l» nicht enthalten, genau so wenig wie «0» und «o»?
// const asciiLetters = Array.from({ length: 26 }, (_, i) =>
// String.fromCharCode(65 + i) + String.fromCharCode(97 + i)
// ).join(''); // "AaBbCc..." oder getrennt sortieren
+17 -3
View File
@@ -8,9 +8,13 @@ const gzipCompressor = zlib.createGzip();
const inputStream = fs.createReadStream('data/products.html');
const outputStream = fs.createWriteStream('data/products.html.gz');
inputStream.on('data', (data) => {
console.log('Pakete (data chunks) werden geladen: ', data.length);
outputStream.write(zlib.gzipSync(data));
inputStream.on('data', (chunk) => {
console.log('Pakete (data chunks) werden geladen: ', chunk.length);
// outputStream.write(zlib.gzipSync(data));
});
outputStream.on('finish', () => {
console.log('Process finished');
});
inputStream.pipe(gzipCompressor).pipe(outputStream);
@@ -21,3 +25,13 @@ inputStream.pipe(gzipCompressor).pipe(outputStream);
// TIPP: Um eine Datei päckchenweise lesen- und schreiben zu können, gibt es für das fs Modul die Methoden createReadStream und createWriteStream.
// ÜBUNG BEREITS GELÖST!!!
// Die wichtigsten WritableStream-Events im Überblick
// - 'finish': Feuert, nachdem stream.end() aufgerufen wurde und alle gepufferten Daten erfolgreich auf das Ziellaufwerk geschrieben wurden.
// - 'close': Feuert, wenn der zugrundeliegende File Descriptor / die Ressource vollständig geschlossen wurde.
// - 'drain': Feuert, wenn der interne Puffer voll war (write() gab false zurück) und nun wieder bereit für neue Daten ist.
// - 'error': Feuert, wenn beim Schreiben ein Fehler auftritt (z. B. fehlende Schreibrechte oder volle Festplatte).
+55
View File
@@ -1,3 +1,58 @@
import os from 'node:os';
console.log(os.platform());
console.log(os.cpus().length);
console.log(`I am running on a machine with ${os.platform()} and ${os.cpus().length} cores.`);
console.log(`I am running on a machine with ${os.type()} and ${os.cpus().length} cores.`);
console.log(`I am running on a machine with ${os.version()} and ${os.cpus().length} cores.`);
// Weitere Informationen zum Betriebssystem
console.log('\n--- Betriebssystem ---');
console.log('Systemtyp:', os.type());
console.log('Systemversion:', os.release());
console.log('Architektur von Node.js:', os.arch());
console.log('Computername:', os.hostname());
// os.cpus() liefert Informationen zu den logischen CPU-Kernen.
const cpus = os.cpus();
console.log('\n--- Prozessor ---');
console.log('Logische CPU-Kerne:', cpus.length);
console.log('CPU-Modell:', cpus[0]?.model ?? 'Unbekannt');
// Die Speicherangaben kommen in Bytes. 1024 ** 3 Bytes entsprechen einem GiB.
const totalMemory = os.totalmem();
const freeMemory = os.freemem();
const usedMemory = totalMemory - freeMemory;
function formatMemory(bytes) {
return `${(bytes / 1024 ** 3).toFixed(2)} GiB`;
}
console.log('\n--- Arbeitsspeicher ---');
console.log('Gesamt:', formatMemory(totalMemory));
console.log('Frei:', formatMemory(freeMemory));
console.log('Belegt:', formatMemory(usedMemory));
// os.uptime() gibt die Laufzeit des Betriebssystems in Sekunden zurück.
const uptime = os.uptime();
const hours = Math.floor(uptime / 3600);
const minutes = Math.floor((uptime % 3600) / 60);
console.log(`\nSystemlaufzeit: ${hours} Stunden und ${minutes} Minuten`);
console.log('\n--- Benutzer und Verzeichnisse ---');
console.log('Benutzername:', os.userInfo().username);
console.log('Home-Verzeichnis:', os.homedir());
console.log('Temporäres Verzeichnis:', os.tmpdir());
// Jede Netzwerkschnittstelle kann mehrere IPv4- und IPv6-Adressen haben.
console.log('\n--- Netzwerkschnittstellen ---');
for (const [name, addresses] of Object.entries(os.networkInterfaces())) {
for (const address of addresses ?? []) {
console.log(`${name}: ${address.address} (${address.family}${address.internal ? ', intern' : ''})`);
}
}
// Übung 32: Information zum Betriebssystem und der Anzahl der vorhandenen CPUs
// Im Kontext einer Monitoring-Lösung benötigt ein Kunde eine kleine CLI (Command Line Interface)-Anwendung, die es erlaubt, das aktuelle Betriebssystem und die Anzahl der CPUs auf dem jeweiligen Rechner zu ermitteln.
@@ -5,7 +5,15 @@ import color from 'chalk';
// VARS =========
const STOCK_WARN_AMOUNT = 5;
const data = fs.readFileSync('data/products.csv', 'utf-8');
let data = '';
try {
data = fs.readFileSync('data/products.csv', 'utf-8');
} catch (error) {
console.log(color.red(error));
// Beendet den Prozess erfolgreich (Code 0)
process.exit(0);
}
const products = data.split('\n');
const headerAr = products.shift().split(/\s*,\s*/); // => [ 'Code', 'Short Description', 'Tagline', 'Quantity', 'Price' ]
@@ -60,9 +68,7 @@ const writeHtmlDocument = (content = '') => {
const listItems = products
.filter((row) => row !== '') // leere String Einträge rausfiltern
.map((row) => {
return recordToHtml(row);
});
.map(recordToHtml); // Funktionsreferenz
const htmlList = `<ul class="list-group">${listItems.join('')}</ul>`;