Adding the remaining methods
We will not examine the code for the remaining methods. Instead, go ahead and add the following instance methods to STCalculator:
Method calculateAnswer:
calculateAnswer: aFunction
"Private - Calculate the answer based on lastValue, aFunction,
and the current value. Answer a String."
| answer last current realFunction |
last := self convertToNumber: lastValue.
current := self convertToNumber: (textWidget value).
aFunction = '='
ifTrue: [ realFunction := operation ]
ifFalse: [ realFunction := aFunction ].
state = #equals
ifTrue: [
answer := current
perform: (realFunction asSymbol)
with: last ]
ifFalse: [
answer := last
perform: (realFunction asSymbol)
with: current ].
answer class = Fraction
ifTrue: [ answer := answer asFloat ].
^answer printString
Method clear
clear
"Private - Clear the display and lastValue."
textWidget setString: ''. "No space between single quotes"
lastValue := nil.
Method close
close
"Shut down the calculator. Just for fun, use a pop-up confirmation
dialog."
(CwMessagePrompter
confirm: 'Really exit?'
title: 'Confirmation')
ifTrue: [
textWidget shell destroyWidget ]
Method convertToNumber:
convertToNumber: aString
"Convert aString to a number. Answer either an Integer or a Float."
| subStrings whole decimal exponent |
subStrings := aString subStrings: $. .
whole := (subStrings at: 1) asNumber.
subStrings size = 1
ifTrue: [ ^whole ]
ifFalse: [
decimal := subStrings at: 2.
(decimal includes: $e)
ifTrue: [
subStrings := decimal subStrings: $e.
exponent := (subStrings at: 2) asNumber.
decimal := subStrings at: 1 ]
ifFalse: [
exponent := 0 ].
^(whole +
(decimal asNumber /
(10 raisedTo: (decimal size))))
* (10 raisedTo: exponent) asFloat ].
Method doFunction:
doFunction: aFunction
"Private - The user has pressed a function button."
| temp |
aFunction = '+/-' ifTrue: [ ^self negate ].
aFunction = 'Clr' ifTrue: [ ^self clear ].
aFunction = 'Pi' ifTrue: [ ^self pi ].
aFunction = 'Off' ifTrue: [ ^self close ].
aFunction = '='
ifTrue: [
temp := textWidget value.
textWidget setString:
(self calculateAnswer: aFunction).
state = #equals
ifFalse: [ lastValue := temp ].
state := #equals ]
ifFalse: [
lastValue = nil
ifTrue: [
lastValue := textWidget value.
operation := aFunction ]
ifFalse: [
state = #equals ifFalse: [
textWidget setString:
(self calculateAnswer: operation)].
operation := aFunction.
lastValue := textWidget value ].
textWidget
setSelection: (0 @ (textWidget value size)).
textWidget
setHighlight: (0 @ (textWidget value size))
mode: XmHIGHLIGHTSELECTED.
state := #function].
Method negate
negate
"Private - The +/- button has been pressed. Change the sign of
the current number."
| string newString |
string := textWidget value.
string size > 0
ifTrue: [ string first = $- "Minus sign"
ifTrue: [ string size > 1
ifTrue: [
newString := string
copyFrom: 2 to: string size ]
ifFalse: [ newString := '' ]]
ifFalse: [ newString := '-' , string ]]
ifFalse: [ newString := '-' ].
textWidget setString: newString.
textWidget cursorPosition: (textWidget value size).
Method pi
pi
"The pi button has been pressed. Display its value."
self insert: (Float pi)
Last modified date: 11/22/2023