0%

Hoofdstuk 8

Programma’s die argumenten accepteren

De interface van een programma is een contract

Hoofdstuk 7 eindigde met een echte converter, maar alleen voor de twee bestandsnamen die in main() stonden. Iemand kan geen andere invoer of uitvoer kiezen zonder het programma te bewerken. Dit hoofdstuk maakt van die vaste uitvoering een opdrachtregelinterface.

De shell zelf is niet opnieuw het onderwerp. Je weet al hoe je in een projecthoofdmap gaat staan en een Python-bestand uitvoert. Het nieuwe werk is bepalen wat het programma accepteert en wat elke mogelijke uitvoering terug belooft.

Schrijf de opdracht vóór de parser

Dit is de volledige interface die we bouwen:

python catalog.py INPUT_PATH OUTPUT_PATH [--minimum-quantity COUNT]

INPUT_PATH en OUTPUT_PATH zijn verplichte positionele argumenten. Hun betekenis volgt uit hun positie: eerst invoer, daarna uitvoer.

--minimum-quantity is een optie. De naam maakt de betekenis van de waarde zichtbaar; laat je de optie weg, dan wordt 0 gebruikt. Een aantal moet een geheel getal van nul of meer zijn. Het programma behoudt items waarvan de hoeveelheid minstens dat aantal is, zonder de volgorde te veranderen of duplicaten te verwijderen.

-h en --help tonen de interface zonder een conversie uit te voeren.

Twee uitvoerstromen en drie statussen

Een opdrachtregelprogramma heeft twee tekststromen. Gewone resultaten gaan naar stdout. Bruikbare foutmeldingen gaan naar stderr. Door ze te scheiden kan een ander hulpmiddel het geslaagde resultaat opslaan zonder er fouttekst doorheen te mengen.

Het programma eindigt ook met een exitstatus:

SituatiestdoutstderrStatus
Conversie slaagtWrote N items to PATH.leeg0
Invoer of catalogusgegevens zijn ongeldigleegCould not convert catalog: ...1
Argumenten ontbreken, zijn onbekend of ongeldigleeggebruiksuitleg en parserfout2
Hulp gevraagdhulptekstleeg0

Het uitvoerbestand is even precies afgesproken. Een geslaagde uitvoering schrijft gevalideerde UTF-8-JSON naar het gevraagde uitvoerpad. Een argumentfout start nooit een conversie. Een onverwachte programmeerfout krijgt nog steeds een traceback; die mag niet worden vermomd als beschadigde invoer.

Hoe weet het programma bij de opdracht python catalog.py source.csv result.json welk pad de invoer is?

Waarom hoort een verwachte melding over een onjuiste catalogus op stderr?

Hierna zet argparse de eerste twee onderdelen van dat geschreven contract om in waarden, zonder dat de converter CSV of JSON opnieuw hoeft uit te zoeken.

Probeer voordat je parsercode schrijft je interface in één zin aan Monty te beschrijven en vraag wat een gebruiker verrassend zou vinden. Interfaces zijn nu veel goedkoper te veranderen dan nadat ze bestaan.