Huiswerk 3
Huiswerk 3
Voor deze opgave gelden volgende richtlijnen:
Je dient een zip bestand in met een individueel bestand voor elke oefening. Gebruik onderstaande naamgeving:
rxxxxxxx_oefening_xx.pyVul je r-nummer vooraan in en het volgnummer van de oefening achteraan. Gebruik voorloopnullen, oefening 1 krijgt dus bijvoorbeeld de naam r0636326_oefening_01.py.
De beoordeling van deze oefeningen gebeurt aan de hand van geautomatiseerde unit tests, daarvoor hanteren we volgende richtlijnen:
- Files met een foute naamgeving worden niet beoordeeld.
- De geautomatiseerde tests houden rekening met typo's. Zolang er minder dan 8 verschillen toont met de verwachte uitvoer, wordt de oplossing als correct beschouwd.
Dit huiswerk is een individuele opdracht, elke vorm van samenwerking is verboden.
Kommagetallen moeten via een f-string geformatteerd worden met twee decimalen. Gebruik volgende code als voorbeeld:
pi = 3.14159265358 print(f"{pi:.2f}") # Uitvoer 3.14De uitlijning van de kolommen in de tabellen moet correct zijn. Gebruik hiervoor f-strings met een breedteparameter. Onderstaande code voegt achteraan de tekst 'server' 4 spaties toe zodat de totale breedte 10 tekens is. De
<geeft aan dat de tekst links uitgelijnd moet worden.demo_variabele = "server" print(f"{demo_variabele:<10}|") # Uitvoer 'server |'De parameters voor afronding en uitlijning kunnen gecombineerd worden.
pi = 3.14159265358 print(f"Pi tot op 4 decimalen: {pi:>8.4f}") # Uitvoer Pi tot op 4 decimalen: 3.1416De startbestanden staan hieronder gelinkt. Je script gaat ervan uit dat die bestanden naast het script staan (open ze dus met
open('servers.csv', 'r')en niet met een volledig pad). De tests draaien telkens met een verse kopie van die map, bestanden die je script zelf aanmaakt of aanvult bestaan bij het testen dus nog niet.Starter code
Functies drukken niets af. Een functie berekent iets en geeft een resultaat terug met
return; het hoofdprogramma zorgt voor alle uitvoer.
Opgave 1
Schrijf een script dat een aantal bestanden analyseert en op zoek gaat naar een zoekterm.
Maak twee functies:
count_lines()ontvangt een bestandsnaam en geeft een tuple terug met het totale aantal regels, het aantal niet-lege regels en het aantal commentaarregels (regels die, zonder de spaties errond, met#beginnen). Een lege regel telt nooit mee als commentaar.count_matches()ontvangt een bestandsnaam, een zoekterm en een optionele parametercase_sensitivemet standaardwaardeFalse. De functie geeft het aantal regels terug waarin de zoekterm voorkomt. Staatcase_sensitiveopFalse, dan maakt het verschil tussen hoofd- en kleine letters niet uit.
Het hoofdprogramma vraagt eerst een zoekterm. Daarna vraagt het herhaaldelijk om een bestandsnaam tot de gebruiker STOP invoert.
Werd dat bestand al eerder gelezen, druk dan
<naam> werd al gelezenaf en ga verder.Bestaat het bestand niet, druk dan
Bestand <naam> niet gevondenaf, tel het als ontbrekend en ga verder.Anders druk je één regel af met de resultaten van beide functies (vervang alles tussen <> door de juiste waarden):
<naam>: <aantal> regels, <aantal> niet leeg, <aantal> commentaar, <aantal> keer "<zoekterm>"
Druk nadat de gebruiker STOP ingevoerd heeft een lijn van 50 streepjes af. Werd er geen enkel bestand gelezen, druk dan Geen bestanden gelezen af. Toon anders het aantal gelezen bestanden, het aantal niet-gevonden bestanden, het totale aantal regels, het gemiddelde aantal regels per bestand, het grootste bestand met zijn aantal regels, en het totale aantal keer dat de zoekterm gevonden werd.
Info
In onderstaande voorbeelden zijn de lijnen die volledig uitgeprint moeten worden door het programma gemarkeerd. De lijnen die de gebruiker om invoer vragen zijn niet gemarkeerd.
Voorbeeld 1:
Geef een zoekterm: linux
Geef een bestandsnaam (of "STOP"): servers.csv
servers.csv: 7 regels, 7 niet leeg, 0 commentaar, 5 keer "linux"
Geef een bestandsnaam (of "STOP"): notities.txt
notities.txt: 3 regels, 3 niet leeg, 0 commentaar, 0 keer "linux"
Geef een bestandsnaam (of "STOP"): servers.csv
servers.csv werd al gelezen
Geef een bestandsnaam (of "STOP"): onbekend.txt
Bestand onbekend.txt niet gevonden
Geef een bestandsnaam (of "STOP"): sshd_config
sshd_config: 6 regels, 6 niet leeg, 1 commentaar, 0 keer "linux"
Geef een bestandsnaam (of "STOP"): STOP
--------------------------------------------------
Bestanden gelezen: 3
Niet gevonden: 1
Totaal aantal regels: 16
Gemiddeld aantal regels: 5.33
Grootste bestand: servers.csv (7 regels)
Totaal aantal keer "linux": 5Voorbeeld 2:
Geef een zoekterm: permit
Geef een bestandsnaam (of "STOP"): sshd_config
sshd_config: 6 regels, 6 niet leeg, 1 commentaar, 1 keer "permit"
Geef een bestandsnaam (of "STOP"): STOP
--------------------------------------------------
Bestanden gelezen: 1
Niet gevonden: 0
Totaal aantal regels: 6
Gemiddeld aantal regels: 6.00
Grootste bestand: sshd_config (6 regels)
Totaal aantal keer "permit": 1Voorbeeld 3:
Geef een zoekterm: permit
Geef een bestandsnaam (of "STOP"): onbekend.txt
Bestand onbekend.txt niet gevonden
Geef een bestandsnaam (of "STOP"): STOP
--------------------------------------------------
Geen bestanden gelezenOpgave 2
Maak een rapport van servers.csv met csv.DictReader en gebruik hier vier functies voor:
read_rows()ontvangt een bestandsnaam en geeft alle rijen terug als een lijst van dictionaries;count_by_os()ontvangt die rijen en geeft een dictionary terug met het aantal servers per besturingssysteem;average_ram()ontvangt die rijen en geeft het gemiddelde RAM-geheugen terug;offline_servers()ontvangt die rijen en geeft een lijst terug met de hostnames van alle offline servers.
Het hoofdprogramma roept de functies op en drukt het rapport af. Bestaat het bestand niet, druk dan Bestand <naam> niet gevonden af. Is het bestand ongeldig (geen csv-bestand of een csv-bestand met foute kolommen), dan druk je Bestand <naam> is ongeldig af.
Voorbeeld 1:
Geef de naam van het CSV-bestand: servers.csvAantal servers: 6
linux: 5
windows: 1
Gemiddeld RAM: 24.00 GB
Offline: ['web02', 'mail01']Voorbeeld 2:
Geef de naam van het CSV-bestand: servers_oud.csvBestand servers_oud.csv niet gevondenVoorbeeld 3:
Geef de naam van het CSV-bestand: servers.txtBestand servers.txt is ongeldig.Opgave 3
Schrijf een script dat uit gebruikers.csv de useradd-commando's voor nieuwe gebruikers samenstelt. Gebruik csv.DictReader en drie functies:
is_valid_username()ontvangt een gebruikersnaam en een optionele parametermin_lengthmet standaardwaarde3. De functie geeftTrueterug wanneer de naam niet leeg is én minstensmin_lengthtekens telt.build_command()ontvangt een rij (een dictionary) en een optionele parameterhome_prefixmet standaardwaarde'/home', en geeft het commando terug:useradd -m -d <home_prefix>/<username> -s <shell> <username>process_users()ontvangt de bestandsnaam en eenmin_length, overloopt alle rijen metenumerate(csv_file, start=1)en geeft een tuple terug met de lijst commando's en de lijst foutmeldingen:- ongeldige gebruikersnaam →
Regel <nummer>: ongeldige gebruikersnaam voor <full_name> - lege shell →
Regel <nummer>: geen shell voor <username> - een ontbrekende kolom (
KeyError) →Regel <nummer>: verplichte kolom ontbreekt - ongeldige shell →
Regel <nummer>: ongeldige shell voor <username>. Enkel de shells/bin/bash,/bin/shen/bin/zshzijn geldig, alle andere shells worden afgekeurd.
Elke regel in beide lijsten eindigt op een newline, zodat ze met
writelines()geschreven kunnen worden.- ongeldige gebruikersnaam →
Het hoofdprogramma vraagt de bestandsnaam en de minimumlengte en doet het volgende:
- schrijf de commando's naar
useradd.sh(maak altijd een nieuw bestand aan) en stdout; - schrijf de foutmeldingen naar
fouten.log(voeg foutmelding toe aan bestaand bestand, maak anders een nieuw bestand aan) en stderr; - druk elk commando af, daarna een lijn van 50 streepjes, het aantal aangemaakte en geweigerde gebruikers, elke foutmelding en tot slot het slaagpercentage.
Het script moet fouten gracieus afhandelen. Als het bestand niet bestaat (FileNotFoundError exception), print dan Bestand niet gevonden en stop het programma. Als het ingegeven aantal tekens geen geldig geheel getal is, vraag dan opnieuw naar invoer en blijf dit herhalen tot de gebruiker een geldig geheel getal invoert. Blijf dit herhalen tot de gebruiker een geldig geheel getal invoert.
Voorbeeld 1:
Geef de naam van het CSV-bestand: gebruikers.csv
Hoeveel tekens moet een gebruikersnaam minstens tellen? 3useradd -m -d /home/jsmith -s /bin/bash jsmith
useradd -m -d /home/apatel -s /bin/sh apatel
useradd -m -d /home/ebakker -s /bin/bash ebakker
--------------------------------------------------
Aangemaakt: 3
Geweigerd: 3
Regel 2: ongeldige gebruikersnaam voor Maria Garcia
Regel 4: ongeldige gebruikersnaam voor Lisa Chen
Regel 5: geen shell voor ohassan
Slaagpercentage: 50.00%Voorbeeld 2:
Geef de naam van het CSV-bestand: gebruikers.csv
Hoeveel tekens moet een gebruikersnaam minstens tellen? 2useradd -m -d /home/jsmith -s /bin/bash jsmith
useradd -m -d /home/apatel -s /bin/sh apatel
useradd -m -d /home/ab -s /bin/bash ab
useradd -m -d /home/ebakker -s /bin/bash ebakker
--------------------------------------------------
Aangemaakt: 4
Geweigerd: 2
Regel 2: ongeldige gebruikersnaam voor Maria Garcia
Regel 5: geen shell voor ohassan
Slaagpercentage: 66.67%Voorbeeld 3:
Geef de naam van het CSV-bestand: gebruikers.csv
Hoeveel tekens moet een gebruikersnaam minstens tellen?
Hoeveel tekens moet een gebruikersnaam minstens tellen?
Hoeveel tekens moet een gebruikersnaam minstens tellen? a
Hoeveel tekens moet een gebruikersnaam minstens tellen? gdqdg
Hoeveel tekens moet een gebruikersnaam minstens tellen? 5useradd -m -d /home/jsmith -s /bin/bash jsmith
useradd -m -d /home/apatel -s /bin/sh apatel
useradd -m -d /home/ebakker -s /bin/bash ebakker
--------------------------------------------------
Aangemaakt: 3
Geweigerd: 4
Regel 2: ongeldige gebruikersnaam voor Maria Garcia
Regel 4: ongeldige shell voor jsmith
Regel 5: ongeldige gebruikersnaam voor Lisa Chen
Regel 6: geen shell voor ohassan
Slaagpercentage: 42.86%Voorbeeld 4:
Geef de naam van het CSV-bestand: ongeldig
Hoeveel tekens moet een gebruikersnaam minstens tellen?
Hoeveel tekens moet een gebruikersnaam minstens tellen? 20Bestand niet gevonden