Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Koden over bruker flere variabler for å holde rede på tilstanden til programmet. Den viktigste variablen er operands, som refererer til lista med operander, som utvides og minskes ved gjennomgang av løkka. I tillegg har vi de to variablene token og operand, som holder det brukeren skrev inn som henholdvis (rå)tekst (string) og og konvertert til desimaltall (float). Mens det er viktig at operands-variablen beholder sin verdi for hver runde i løkka, så er det ikke viktig at token og operand gjør det. Tvert imot, så tenker en gjerne at disse er lokale for løkka, selv om Python ikke behandler dem annerledes enn operands i så måte. I andre språk, f.eks. Java, så er det mulig å opprette (deklarere) såkalt blokk-lokale variabler.

La oss se på hvordan variablene hånderes i detalj, når programmet utføres.

PlantUML Macro
object "rpncalc1" as rpncalc1
Ved oppstart av programmet tanker vi oss at det opprettes et slags notatark, med samme navn som programmet. Fra starten er arket tomt, som vist til venstre.
PlantUML Macro
object "rpncalc1" as rpncalc1 {
	operands = []
}
Når tilordningen til operands-utføres, så ut noteres navnet og verdien på notatarket.
PlantUML Macro
object "rpncalc1" as rpncalc1 {
	operands = []
	token = "1.0"
}

Når raw_input utføres så blir programmet liggende og vente til brukeren har skrevet inn tekst, og denne teksten tilordnes så til token.

Her antar vi at brukeren skriver inn 1.0.

PlantUML Macro
object "rpncalc1" as rpncalc1 {
	operands = []
	token = "1.0"
	operand = 1.0
}
token har nå verdien 1.0 (som tekst, altså en string) og denne lar seg konvertere til desimaltall (altså en float-verdi). Dermed blir operand-tilordningen utført for første gang, så operand får verdien 1.0.
PlantUML Macro
object "rpncalc1" as rpncalc1 {
	operands = [1.0]
	token = "1.0"
	operand = 1.0
}
På linjen deretter så legges operand til operands-lista. Her leses operands-variablen, men den endres ikke, det er det jo lista som gjør.
PlantUML Macro
object "rpncalc1" as rpncalc1 {
	operands = [1.0, 2.0]
	token = "2.0"
	operand = 2.0
}

Vi antar i andre runde av løkka at brukeren skriver inn 2.0. Siden token og operand allerede finnes, så vil disse få nye verdier. operands refererer fortsatt til samme liste, som igjen er utvidet med en ny operand.

PlantUML Macro
object "rpncalc1" as rpncalc1 {
	operands = [3.0]
	token = "+"
	operand = 2.0
}

Når brukeren i tredje runde i løkka skriver inn +, så utløses ValueError-unntaket før tilordningen av operand rekker å bli utført. Og derfor endres ikke operand, kun token. operands endrer fortsatt ikke verdi, men lista den refererer til endrer seg.

Hvis en hadde utført linja operands.append(operands.pop() - operands.pop()) i små steg, så ville en sett at lista faktisk endrer seg tre ganger: Først fra [1.0, 2.0] til [1.0] når pop kalles første gang, så fra [1.0] til [] når pop kalles andre gang og så til [3.0] når svaret legges til med append.

 

  
  
  

 

rpncalc2.py

fd