Programeer opdrachtenOpdracht : opdr1_wijnand.txt

Terug naar de inzendingen
Opdracht 1, Wijnand Wiersma
2 Jan 2005
 
 
 ok, ik ben niet bijster slim, maar heb wel wat geprobeerd:
 
 1 
*****wijnandsnoep.pl*****
  
 2#!/usr/bin/perl
 3
 4# yes this is BSD licensed. Everyone may do what they want with it, I only want my name in the credits :-)
 5
 6#Copyright (c) 2005, Wijnand Wiersma
 7#All rights reserved.
 8
 9#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 10
 11#Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.#Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 12
 13#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ORBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 14
 15# thanks to Wouter ( http://wdeboer.nl) for thinking with me.
 16
 17use warnings;
 18use strict;
 19
 20my $clear = `clear`; # bewaar de output van clear zodat wij hiermee telkens opnieuw het scherm kunnen clear'en. Zie perlcookbook hoofdstuk 15.3
 21
 22my @toegestanemunten = qw ( 2.00 1.00 0.50 0.20 0.10 0.05 );
 23@toegestanemunten=sort{$b <=> $a } @toegestanemunten; # Moet altijd aflopend zijn, zorg ervoor dat dat ook zo is.
 24my $defaultmuntenaantal=15;
 25
 26my %muntjes; # hash waarin de muntjes worden bijgehouden, we gaan uit van een vers gevulde automaat
 27foreach my $munt (@toegestanemunten )
 28  { $muntjes{$munt}=$defaultmuntenaantal; }
 29
 30my %produkten; # hash voor de aanwezige produkten. We gaan weer uit van een net gevulde automaat.
 31$produkten{'1'}='rolletje drop';
 32$produkten{'2'}='zakje katjesdrop';
 33$produkten{'3'}='zakje engelse drop';
 34$produkten{'4'}='rolletje pepermunt';
 35$produkten{'5'}='reep chocolade';
 36
 37my $defaultvoorraad=10;
 38my %voorraad; # hierin hou ik bij hoeveel er van ieder produkt nog in de automaat zit.
 39$voorraad{'1'}=$defaultvoorraad;
 40$voorraad{'2'}=$defaultvoorraad;
 41$voorraad{'3'}=$defaultvoorraad;
 42$voorraad{'4'}=$defaultvoorraad;
 43$voorraad{'5'}=$defaultvoorraad;
 44
 45my %prijzen; # hash waarin bijgehouden wordt wat ieder produkt kost.
 46$prijzen{'1'}='0.75';
 47$prijzen{'2'}='1.25';
 48$prijzen{'3'}='1.50';
 49$prijzen{'4'}='0.75';
 50$prijzen{'5'}='1.00';
 51
 52# Hierbij de main loop, deze wacht iedere keer op een aktie en roept de bijbehorende functies aan.
 53sub main
 54{
 55  my $exit=undef;
 56  while ( ! $exit )
 57  {
 58    print $clear;
 59    print "Welkom bij de snoepautomaat\n";
 60    print "Maak uw keuze:\n";
 61    print "\t1) Produkt kopen\n";
 62    print "\t2) Automaat bijvullen\n"; # just for fun ;-)
 63    print "\t3) Automaat afsluiten\n";
 64    print "\nuw keuze? ";
 65    my $input=;
 66    chomp $input;
 67    if ( $input eq '3' ) { $exit='1';}
 68    elsif ( $input eq '1' ) { koop(); }
 69    elsif ( $input eq '2' ) { bijvullen(); }
 70    else { print "\nOngeldige invoer!\n"; }
 71  }
 72}
 73
 74# Deze functie handeld de aankoop van een produkt af
 75sub koop
 76{
 77  print $clear;
 78  my $done=undef; # hiermee kijken we of we klaar zijn met inwerpen of kiezen.
 79  my $betaald=0.00; # nu nog niks, komt nog wel
 80  my $moetgepast=moetgepast(); # checken voor de eerste inworp
 81  while ( ! $done )
 82  {
 83    print "Werp geld in\n";
 84    print "Gepast betalen svp\n" if $moetgepast; # als er gepast betaald moet worden kunnen we alleen waarschuwen, eigen risico gebruiker (net als echte automaten).
 85    printf ("Ingegooid bedrag: %.2f\n\n",$betaald); # printf gebruik ik om de precisie aan te kunnen geven.
 86    my $muntcount=0; # dit is voor de indexes in het menu
 87    my %geldigemunten; # ook handig voor het menu
 88    foreach  my $munt ( sort (keys ( %muntjes ))) # Laat de toegestane munten in oplopende volgorde zien
 89    {
 90      $muntcount++; # we voegen een munt toe
 91      $geldigemunten{$muntcount}=$munt; #
 92      print "\t$muntcount) $munt\n";
 93    }
 94    print "\t0) Klaar met inwerpen\n";
 95    my $inworp=;
 96    chomp $inworp;
 97    if ( $inworp ne '0' && exists $geldigemunten{$inworp}) # controleer of een munt geldig is en of er geen 0 is getypt
 98    {
 99      $betaald+=$geldigemunten{$inworp};  # dit is er tot nu toe betaald
 100      $muntjes{$geldigemunten{$inworp}}++; # en we hebben er een munt bij in het buisje
 101    }
 102    elsif ( $inworp eq '0' ) { $done=1; } # ok, klaar met ingooien.
 103    else { print "Ongeldige invoer!\n"; } # sukkel, dit mag je niet typen
 104  }
 105
 106  print $clear;
 107  $done=undef; # reset
 108  while ( ! $done ) # en weer checken we deze variabele om te kijken of er al iets goeds is gekozen
 109  {
 110    print "Kies het gewenste produkt\n\n";
 111    foreach  my $produkt ( sort (keys ( %produkten ))) # laat ieder produkt zien in een menu
 112    {
 113      print "\t$produkt) $produkten{$produkt}\n"; # hmm, is dit lekker?
 114    }
 115    print "\t0) Geld terug\n"; # kan gebeuren he
 116    my $produktkeuze=;
 117    chomp $produktkeuze;
 118    if ( $produktkeuze ne '0' && exists $produkten{$produktkeuze}) # ok, er is voor een bestaand produkt gekozen
 119    {
 120      if ( $voorraad{$produktkeuze} eq 0 ) # tja, wat er niet is kunnen we ook niet verkopen
 121      {
 122        print "Helaas, dit produkt is uitverkocht\n";
 123      }
 124      elsif ( $prijzen{$produktkeuze} > $betaald ) # tja, dat snap je toch zelf wel he :-)
 125      {
 126        print "Onvoldoende geld ingeworpen\n";
 127      }
 128      else # ok, niks mis met de keuze van de gebruiker, dus we kunnen leveren en wisselgeld teruggeven
 129      {
 130        $done=1; # We kunnen maar 1 produkt kiezen, net als bij iedere andere automaat dus we springen er hier uit.
 131        $voorraad{$produktkeuze}--;
 132        geefwisselgeld($betaald, $produktkeuze);
 133      }
 134    }
 135    else # ah, de gebruiker wil zijn geld terug ( ik kan het begrijpen )
 136    {
 137      geefwisselgeld($betaald); # dat wordt dokkuh
 138      $done=1;
 139    }
 140  }
 141}
 142
 143# Kijk wat de gebruiker aan wisselgeld moet terugkrijgen.
 144sub geefwisselgeld
 145{
 146  my $betaald=shift;
 147  my $produktkeuze=shift || 0; # als er geen produkt is gekocht moet de gebruiker alles terugkrijgen.
 148  my $betaalterug=$betaald - ( $prijzen{$produktkeuze} || 0 ); # als er geen produkt is zal hier ook geen bedrag uitkomen en dus is $betaalterug het volledige bedrag
 149  printf ("ik moet %.2f terugbetalen\n",$betaalterug); # printf gebruik ik om de precisie aan te kunnen geven.
 150
 151  foreach my $munt ( @toegestanemunten )
 152  {
 153    for ( my $i = 50 ; ( !minderdan5sensor($munt)) && ( $betaalterug > 0 && ( $i >= 0 )) ; $i--) # 50 is een absurd grote waarde, maar geeft genoeg ruimte. we gaan door zolang er nog meer dan 5 van een munt zijn zodat we altijd wisselgeld kunnen blijven geven.
 154    {
 155      my $waarde = $i * $munt; # betere leesbaarheid
 156      if (  ( $waarde eq $betaalterug) || ( $waarde <= $betaalterug) ) # raar dat ik eq moest gebruiken, maar ik had problemen om anders de 0.05 cent te matchen.
 157      {
 158        $betaalterug -= $waarde; # we gaan uitbetalen, dus we trekken dit van het nog te betalen bedrag af
 159        $muntjes{$munt} -= $i; # en dus ook minder munten
 160        print "Ik geef $i munt(en) van $munt terug\n" if $i > 0; # wel zo netjes om even te melden wat je teruggeeft
 161      }
 162    }
 163  }
 164}
 165
 166# spreekt voor zich, als een munt minder dan 5 in de buis heeft zitten geeft deze true terug.
 167sub minderdan5sensor
 168{
 169  my $munt=shift;
 170  if ( $muntjes{$munt} < 5 ) { return 1; }  #minder dan 5, dus waar
 171  else { return undef; } # dus vals
 172}
 173
 174# spreekt voor zich, als een munt meer dan 10 in de buis heeft zitten geeft deze true terug.
 175# momenteel niet in gebruik, misschien in latere versie
 176sub meerdan10sensor
 177{
 178  my $munt=shift;
 179  if ( $muntjes{$munt} > 10 ) { return 1; } # ja, van deze munt hebben we er minimaal 10
 180  else { return undef; } # dus vals
 181}
 182
 183# van de laagste 3 soorten munten kunnen we heel veel combinaties maken, zorg er dus altijd voor dat daar minimaal 5 van aanwezig zijn.
 184sub moetgepast
 185{
 186  foreach my $munt ( @toegestanemunten )
 187  {
 188    next if $munt eq '2.00';
 189    next if $munt eq '1.00';
 190    next if $munt eq '0.50';
 191    return 1 if minderdan5sensor($munt); #ja, van deze munt hebben we er minder dan 5
 192  }
 193  return undef;
 194}
 195
 196sub bijvullen
 197{
 198  # aanvullers hebben een sleutel, deze moeten ze nu tikken.
 199  my $sleutel=;
 200  chomp $sleutel;
 201  return if $sleutel ne 'blah blah blah';
 202  # zet de muntjes weer op hun plek
 203  foreach my $munt (@toegestanemunten )
 204    { $muntjes{$munt}=$defaultmuntenaantal; }
 205
 206  # en zet alle produkten weer in hun standaard hoeveelheid
 207  foreach  my $produkt ( keys ( %produkten ))
 208  {
 209    $voorraad{$produkt}= $defaultvoorraad;
 210  }
 211  print "De automaat is weer aangevuld, druk op enter om door te gaan\n";
 212  my $nietnuttig=;
 213}
 214
 215# roep main hier aan
 216main();
 217
 
 
Mijn commentaar
 
 Wijnand,
 Een interesante benadering van het probleem.
 Helaas maak je geen duidelijk onderscheid tussen het simulatie gedeelte,
 en het deel dat (jouw) besturing voorstelt.
 Dat maakt het implementeren van jouw software in een echte automaat lastig !
 Daar staat tegenover dat je uitvoerig uitlegt wat je doet en waarom.
 Voor een profesionele situatie waar je met colega's moet samen werken wel zo prettig.
 Mij is onduidelijk waarom je zo zuinig bent met nieuwe regels, zoals op #169 en #178, Dat komt de leesbaarheid niet ten goede.
 Mooi is dat je ondanks dat dit niet in de opdracht gevraagd wordt aangeeft waneer een produkt is uitverkocht.
 Dit deel kan niet gesimuleerd worden omdat er geen sensors voor zijn.
 jij houd het dan ook keurig zelf bij.
 Je keuze voor de merkwaardige combinatie van hashes en arrays gaat me even te boven,
 maar dat zal ongetwijfeld aan mij liggen.
 Ook van je je clear oplossing is mij het doel niet duidelijk, zal het eens in het genoemde boek opzoeken ;)
 Hoop dat je bij de volgende opdracht net zo creatief bent !