This commit is contained in:
@@ -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.
@@ -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
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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>`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user