The sheet requires us to parse RPN input into a readable expression.
What is the input sequence that instructs the device to define that
input as a program? How are variable values plugged into the
function?
The instruction sheet doesn't seem to specify these parts of the
requirements. Can anyone help here?
Thanks,
Jonathan
I'm not used to requests to hard-code.
I'm sure there are better ways to solve this problem but this one
about the only way I could think of doing it quickly.
Rob
I'm sure there are better ways to solve this problem but this one about the only way I could think of doing it quickly.
Rob
> --
> You received this message because you are subscribed to the Google Groups "iPhone Application Development Auditors" group.
> To post to this group, send email to iphone-appd...@googlegroups.com.
> To unsubscribe from this group, send email to iphone-appdev-aud...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/iphone-appdev-auditors?hl=en.
>
Had the same "huh" moment myself.
--
Craig
Sent from my mobile
I'm finishing up the second assignment, and am curious how others went
about a few points.
(1) According to hint #3, descriptionOfTopOfStack: should be less than
20 lines of code. I don't see how that's possible, considering all
the special cases you need to consider for parenthesis. Just the +/-
case requires 5-6 lines of code: the first if statement, then two more
conditionals and dealing with if the operand already as a "-" in
front.
(2) According to question #3c, the variable values dictionary should
be a property of the controller. Since we want
runProgram:usingVariableValues: to take this dictionary as an
argument, performOperation:operation also needs to take variableValues
as an argument; this seems messy. Does anyone know why variableValues
shouldn't just be a property of CalculatorBrain, instead?
(3) In question #4, we're told to remove the last element of the stack
(if userIsInTheMiddleOfEnteringNumber==NO). Since the stack may look
like: "3 8 +", removing the last element just causes the display to
show "8". Is this what others got as well?
Thanks,
Will
(1) I too am stumped on this one. I've been racking my brain on how
to keep it at 20 lines. Anyone else have hints on how to do this?
Without adding a bunch more lines of code, I'm not sure how to remove
extraneous parentheses.
(2) This one confused me for awhile. I did end up using a property in
the Controller and updated runProgram to this:
+ (double)runProgram:(id)program
{
return [self runProgram:program usingVariableValues:nil];
}
The reason is that the assignment states this:
"If there are variables in the specified program for which there are
no values in the specified NSDictionary, use a value of 0 for those
variables when you run the program. This should be the case if someone
calls the original runProgram: method (the one shown in the demo in
class)."
So runProgram:usingVariableValues accounts for nil and substitutes 0
in. Then when I hit any of the "test" buttons which populate my
Controller property, I call runProgram:usingVariableValues from there
and it updates the display with whatever the value is for the
variables used in the program. I'd be happy to send you the code or
post it here if others want to see it.
(3) I'm not that far yet as I'm still trying to figure out (1) :)
Regards,
James
Regards,
James
(1) I would love to see how it can be done in less than 20 lines of
code. That said, I have mine down to 28 (could be less depending on
coding style, i.e. "else" being on the same line as a closing "if"
bracket) and I only needed one "if" check for precedence. The key is
to remember what the last *operation* was as it recurses through.
This covers all the cases described in 2a through 2f in the assignment
(i.e. "π r r * *" yields "π * r * r", etc...).
(2) See my previous post, but here's a piece I left out. I do not need
to change performOperation: as it still calls runProgram:. I only
mention this because I've seen other threads where people modify that
function and it doesn't need to (the "test" buttons in the Controller
take care of that).
(3) Using your example, "3 8 +", hitting Undo also updates my display
back to 8 instead of 11 and my descriptionOfProgram output updates to
"8, 3" instead of "3 + 8".
I hope this helps. If you'd like, I could email the code to you
*privately*. ;)
My point was that performOperation: didn't need the variables
dictionary. It remains unchanged from the Demo lecture. It calls the
runProgarm: class method and runPrgram: calls
runProgram:usingVariableValues. Since performOperation: and
runProgram: don't have the dictionary, runPorgram: passes nil to
runProgram:usingVariableValues. At least that's how I (eventually)
interpreted this from the assignment:
"If there are variables in the specified program for which there are
no values in the specified NSDictionary, use a value of 0 for those
variables when you run the program. This should be the case if someone
calls the original runProgram: method (the one shown in the demo in
class)."
So the testVariableValues dictionary will then always produce 0 values
(as handled in the runProgram:usingVariableValues class method)
*until* a user presses one of the "test" buttons.
Regarding calling runProgram:usingVariableValues, that is exactly what
I do inside the "test" button IBAction. My original implementation
was exactly how you described. It simply populated the property in the
Controller and updated the label. However, I couldn't think of a way
to keep the model backwards compatible (which I assume the instructor
wanted) without modifying performOperation: to something like
performOperation:usingVariableValues or creating a property in the
model to hold its own testVariableValues and providing an instance
method to set it. I also considered changing operationPressed: in the
Controller to call runProgram:usingVariableValues. I didn't like any
of these ideas, though, as it didn't seem like it's what the
instructor would have wanted.
My final implementation is that I have an updateDisplay: method in the
Controller that handles updating the program description, updating the
testVariableValues label, and handling the display label when Undo is
pressed. I call updateDisplay: from within my testPressed:,
undoPressed:, enterPressed:, variablePressed:, and operationPressed:
IBActions.
I hope this helps!
Regards,
James
Thanks for your comments.
My solution was to change performOperation: to
performOperation:withVariableValues:, and just pass in the values
dictionary there. It didn't seem the cleanest way, but it works just
fine.
As for the descriptionOfProgram method, I created an updateDescription
method in my controller which calls descriptionOfProgram. I have it
called whenever the display setter or clearPressed is called.
Thanks,
Will
many thanks for the tip! I'm not yet comfortable with the notation
Objective C offers..
I'll try that.
I am still puzzled by the fact that a "program" is made up with
instance information.
I thought I read that class methods should not give access to instance
data.
Have I gotten it completely wrong or do any others also see that as a
conceptual problem?
Warm regards
Dimi
I don't see any instructions allowing us to include program in the
public API. Did I miss something?
I can code this on my own, but I'd feel better if I know I'm complying
with the expectations of the assignment.
Jonathan
You've pointed me to the first paragraph, which does answer my
question, but not exactly in the way you described.
The "@property (readonly) id program;" requirement explains how
program is to be accessed!
Jonathan
I'm having a bit of trouble figuring out all of this precedence
nonsense, and where to put those parentheses.
James mentioned that the trick was to remember what operation came
before the current one. However, I just can't fathom a way to do that.
Of course, you'd make some methods that do this, but I don't know what
exactly they would do. James said he only needed one check for
precedence, and that baffles me further.
So far I've got my descriptionOfTopOfStack:, which scoops out how many
operands an operation takes and from then on I format the result. If
the operation needs two operands I pass it to, the self made method,
descriptionForTwoOperandOperation:firstOperand:secondOperand:, if it
needs one then on to descriptionForOneOperandOperation:operand:.
Now these two methods should in some way remember the last operation
that was passed to them or figure out if parentheses are needed or
not. I just can't put my brain where my code is (or ought to be).
If any of you could help, it would be much appreciated.
You could keep track of the last operation by using a static variable
within descriptionOfTopOfStack: or change the method signature to
something like descriptionOfTopOfStack:lastOperation:. The first call
to it would pass nil for lastOperation and subsequent calls would pass
topOfStack (assuming topOfStack was an operation) as it recurses.
Once you know the current and previous operations, an if check against
them would tell you if you need parentheses or not.
Hope that helps.
Regards,
James
PS. Though Paul said you could implement the changes by adding around
50 lines of code, I certainly have gone over that amount. I guess I
could start shaving some lines off of it now...
How many lines do you guys implement fit in?