Factoring program (TI-84 plus) - ti-basic

My Program, just learning how to code calculators today, is not giving me any response but
"DONE"
PROGRAM:FACTORS
:ClrHome
:Input "A=", A
:Input "B=", B
:Input "C=", C
:For(D,1,100,1)
:For(E,1,100,1)
:If (D*E)=C and (D+E)=B
:Stop
:End:End:End
:Disp D
:Disp E

Two problems:
1: All of the ":end"s are on the same line. Do a different one for each
2: This is probably the biggest problem: The "stop" command. "Stop" is used to end the program altogether, and go back to regular function. I'm assuming what you want to do is make it stop looping once D*E=C and once D+E=B. In that case, you can do one of two things: write the breakout code into a repeat loop; for instance
:ClrHome
:Input "A=", A
:Input "B=", B
:Input "C=", C
:For(D,1,100,1)
:For(E,1,100,1)
:Repeat (D*E)=C and (D+E)=B
:End
:End
:End
:Disp D
:Disp E
Or, you can use a Goto command
:If (D*E)=C and (D+E)=B
:Goto Lbl A
And further down in your code, you would put the "Lbl A" above where you wanted it to display your variables

The problem you have is that stop ends the program entirely instead of just breaking the loops. To fix this, instead or using For loops, you could use Repeat loops:
:1→D
:Repeat (D*E=C and D+E=B) or D=100
::1→E
::Repeat (D*E=C and D+E=B) or E=100
:::E+1→E
::End
::1+D→D
:End
You can ignore the extra colons, they are just there for clarity, but if you leave them the code will still work because they function identically to newlines.
The Repeat loops will break by themselves when the condition D*E=C and D+E=B is met, but you have to handle the initialization and incrementing of the variables E and D yourself.
Also note that your factoring algorithm can fail if A does not equal one. Consider dividing both B and C by A, and then outputting A as a constant factor.
Another error with your code is that you have too many End statements, but fixing this would not fix the program, and it would still exit at the Stop. An If without a Then does not need an End, but only one line will be run if the condition is true. For example:
:If <condition>
:<one statement>
or
:If <condition>
:Then
:<statement 1>
:<statement 2>
:<statement ...>
:<statement n>
:End

Related

Trouble on "If" statement on TI-84 Plus C Silver Edition

I've got a small code in TI BASIC on my TI-84 Plus C Silver Edition calculator that will determine correct dosage of drugs based on the patient's weight. For example, if aspirin is given at 5 mg per kg of patient weight (it isn't), then the code should tell me to give a 100kg patient 500mg of aspirin.
However, the code is solving for every possible drug. Here it is:
PROGRAM:DRUG1
:Input "PATIENT WEIGHT: ",W
:Input "AGENT NAME: ",A
:If A=IPPI
:Disp "DOSAGE",W*2
:If A=NEVO
:Disp "DOSAGE", W*0.5
So in this case, the two drugs are IPPI and NEVO. If I give a patient weight of 100kg, and choose IPPI, then I would expect to see
DOSAGE 200
However, what I do see is
DOSAGE 200
DOSAGE 50
so apparently both "if" statements are running, even though I've given a only one value (IPPI). [The same error occurs when I set A as NEVO].
I've tried enclosing both If statements within Then...End as well, so the code would look like:
PROGRAM:DRUG1
:Input "PATIENT WEIGHT: ",W
:Input "AGENT NAME: ",A
:If A=IPPI
:Then
:Disp "DOSAGE",W*2
:End
:If A=NEVO
:Then
:Disp "DOSAGE", W*0.5
:End
but that changes nothing.
I'm pretty new to BASIC, so I'm sure there's a simple error that I can't see, but I'm stumped at the moment.
You need to change the second Input command so the information is stored to a string instead of the numeric variable A. TI-84 series calculators have ten string variables in the [VARS][7] menu for this purpose.
Note also that you must compare the string against the string "IPPI" rather than the sequence of letters (numeric variables) IPPI. So your code could be:
:Input "PATIENT WEIGHT: ",W
:Input "AGENT NAME: ",Str1
:If Str1="IPPI"
:Disp "DOSAGE: ",W*2
:If Str1="NEVO"
:Disp "DOSAGE: ",W*0.5
or more concisely:
:Input "PATIENT WEIGHT: ",W
:Input "AGENT NAME: ",Str1
:Disp "DOSAGE:"
:If Str1="IPPI"
:Disp 2W
:If Str1="NEVO"
:Disp .5W
You're trying to use variable names as strings.
:If A=IPPI
This isn't comparing a string to "IPPI", it's comparing a numeric variable A to the numeric value I*P*P*I, which I'm guessing results in 0 in your case.
Similarly, when you take input, if you enter IPPI, it's going to multiply those variables and assign A to be that product.
You'll need to use a string variable and quotes.
The main problem with your program is that you aware assigning a string to a variable that only supports numbers. That leaves the new value of the variable the Boolean value of the string, True, which in the case of TI-BASIC is the value, 1. To fix this you need to assign it to a variable which supports characters in a string, in this case you can use STR1.

Syntax error on simple If Else

I get an error at the 'Else' on a TI-84 Plus.
I can't figure out why this doesn't work.
I'm writing a GCD program just as an exercise in programming a TI calculator.
It's recursive (or as recursive as TI-BASIC gets).
If B=0
Disp A
Else
C->B
B->remainder(A,B)
A->B
prgmGCD2
TI-Basic is often rather picky about the syntax of if statements.
There are three general formats for an If statement.
Single Statement If
:If <boolean>
:<expression>
Note that <expression> consists of exactly one line of code.
Multi Statement If
:If <boolean>
:Then
:<expresion>
:<expresion>
:End
As opposed to the first option, this option can contain any number of lines of code after the If.
If Else
:If <boolean>
:Then
:<expresion>
:<expresion>
:Else
:<expresion>
:<expresion>
:End
As with the previous option, any number of statements can be put after the If and after the Else.
You are obviously trying to use an if else statement. The correct syntax for this is:
:If B
:Then
:C->B
:B->remainder(A,B)
:A->B
:prgmGCD2
:Else
:Disp A
:End

iPart( and int( returning 0 for 1?

Ok, here's my problem. I wrote an advanced Pythagorean Theorem program, but it apparently is having exceptions. Here's an instance of my problem. When I input A? √(3) and B? 2, I get 0 back. Here's the code:
:Prompt A,C
:(C^2-A^2)->B
:If B<0
:Then
:Disp "THAT IS N
OT A VALID TRIA
ANGLE
:Else
:If iPart(√(B))≠
√(B)
:Then
:Disp "B = √(",B
:Else
:Disp "B = ",√(B)
:End
:End
Therefore, if B = 1, then hypothetically it should output B = 1 but instead it outputs:
A=? √(3)
C=? 2
B = √(
1
Done
What am I doing wrong and how can I fix it?
When I quickly evaluate your program, it seems to work correctly when you get B≠1. For example if I want to calculate the famous 3,4,5 - triangle it shows:
A=?4
C=?5
B=
3
Done
Apparently the iPart( doesn't work correctly with √(1). You could include an extra statement to the If iPart( ... statement to rule this out. Like this.
:...
:If iPart(√(B))≠√(B) and B≠1
:...
Besides that I think the program looks cleaner and nicer if you use the Input, ClrHome and Output( commands.
:ClrHome
:Input "A: ",A
:Input "C: ",C
:(C^2-A^2)->B
:If B<0
:Then
:Output(4,1,"THA
T IS NOT A")
:Output(5,1,"VAL
ID TRIANGLE")
:Else
:If iPart(√(B))≠
√(B) and B≠1
:Then
:Output(3,1,"B:
√( )")
:Output(3,5,B)
:Else
:Output(3,1,"B:")
:Output(3,5,√(B))
:End
:End
:Pause
:ClrHome
Now the results screen looks something like this:
A: √(3)
C: 2
B: 1
I think this is cleaner, with the 3 aligned istead of in the bottom right corner. When you press ENTER everything will remove itself from the screen (due to the Pause command).

How to break outer cycle in Ruby?

In Perl, there is an ability to break an outer cycle like this:
AAA: for my $stuff (#otherstuff) {
for my $foo (#bar) {
last AAA if (somethingbad());
}
}
(syntax may be wrong), which uses a loop label to break the outer loop from inside the inner loop. Is there anything similar in Ruby?
Consider throw/catch. Normally the outside loop in the below code will run five times, but with throw you can change it to whatever you like, breaking it in the process. Consider this perfectly valid ruby code:
catch (:done) do
5.times { |i|
5.times { |j|
puts "#{i} #{j}"
throw :done if i + j > 5
}
}
end
What you want is non-local control-flow, which Ruby has several options for doing:
Continuations,
Exceptions, and
throw/catch
Continuations
Pros:
Continuations are the standard mechanism for non-local control-flow. In fact, you can build any non-local control-flow (subroutines, procedures, functions, methods, coroutines, state machines, generators, conditions, exceptions) on top of them: they are pretty much the nicer twin of GOTO.
Cons:
Continuations are not a mandatory part of the Ruby Language Specification, which means that some implementations (XRuby, JRuby, Ruby.NET, IronRuby) don't implement them. So, you can't rely on them.
Exceptions
Pros:
There is a paper that proves mathematically that Exceptions can be more powerful than Continuations. IOW: they can do everything that continuations can do, and more, so you can use them as a replacement for continuations.
Exceptions are universally available.
Cons:
They are called "exceptions" which makes people think that they are "only for exceptional circumstances". This means three things: somebody reading your code might not understand it, the implementation might not be optimized for it (and, yes, exceptions are godawful slow in almost any Ruby implementation) and worst of all, you will get sick of all those people constantly, mindlessly babbling "exceptions are only for exceptional circumstances", as soon as they glance at your code. (Of course, they won't even try to understand what you are doing.)
throw/catch
This is (roughly) what it would look like:
catch :aaa do
stuff.each do |otherstuff|
foo.each do |bar|
throw :aaa if somethingbad
end
end
end
Pros:
The same as exceptions.
In Ruby 1.9, using exceptions for control-flow is actually part of the language specification! Loops, enumerators, iterators and such all use a StopIteration exception for termination.
Cons:
The Ruby community hates them even more than using exceptions for control-flow.
No, there isn't.
Your options are:
put the loop in a method and use return to break from the outer loop
set or return a flag from the inner loop and then check that flag in the outer loop and break from it when the flag is set (which is kind of cumbersome)
use throw/catch to break out of the loop
while c1
while c2
do_break=true
end
next if do_break
end
or "break if do_break" depending on what you want
Perhaps this is what you want? (not tested)
stuff.find do |otherstuff|
foo.find do
somethingbad() && AAA
end
end
The find method keeps looping until the block returns a non null value or the end of the list is hit.
Wrapping an internal method around the loops could do the trick
Example:
test = [1,2,3]
test.each do |num|
def internalHelper
for i in 0..3
for j in 0..3
puts "this should happen only 3 times"
if true
return
end
end
end
end
internalHelper
end
Here you can do a check inside any of the for loops and return from the internal method once a condition is met.
I know I will regret this in the morning but simply using a while loop could do the trick.
x=0
until x==10
x+=1
y=0
until y==10
y+=1
if y==5 && x==3
x,y=10,10
end
end
break if x==10
puts x
end
The if y==5 && x==3 is only an example of an expression turning true.
You may consider adding a flag, which is set inside the inner loop, for controlling the outer loop.
'next' the outer loop
for i in (1 .. 5)
next_outer_loop = false
for j in (1 .. 5)
if j > i
next_outer_loop = true if j % 2 == 0
break
end
puts "i: #{i}, j: #{j}"
end
print "i: #{i} "
if next_outer_loop
puts "with 'next'"
next
end
puts "withOUT 'next'"
end
'break' the outer loop
for i in (1 .. 5)
break_outer_loop = false
for j in (1 .. 5)
if j > i
break_outer_loop = true if i > 3
break
end
puts "i: #{i}, j: #{j}"
end
break if break_outer_loop
puts "i: #{i}"
end

How to write 'if' without using 'then' or 'end' in Ruby

I've found three ways to write the same condition in Ruby:
#1
if 1==1
puts "true"
end
#2
puts "true" if 1==1
#3
if 1==1 then puts "true" end
Why can't I do this?
#4
if 1==1 puts "true"
I don't understand:
Why then and end are needed in #3, and,
Why I need to change the order to get #2 to work.
Statement #4 seems like the most natural way to write this. I don't understand why it's not possible.
The "if x then y end" syntax is meant for multiline conditionals while the "y if x" form is meant for concise single-line conditional statements. The then is necessary in the first case to tell Ruby that the condition is over (since Ruby doesn't require parens like C), and the end is necessary to tell Ruby that the whole if block is over (since it can be multiple lines).
You can replace the then with a semicolon, because an end-of-line also signals the end of the condition. You can't get rid of the end with a multiline if. Either use the second form or the ternary operator if you want a concise one-liner.
For example, suppose
x = true
the following will evaluate true, and return y
x ? y :
=> y
likewise, this will evaluate false and return nothing
!x ? y :
=>
add a term after the ':' for the else case
!x ? y : z
=> z
The thing is that both ways actually are a natural way to think:
if this is true then do something
do something if this is true
See? Ruby tries to get close to English syntax this way. The end is just necessary to end the block, while in the second version, the block is already closed with the if.
To actually answer your question, I think there is no chance to get the then and end removed. Remember Pascal / Delphi? You have a then there as well. It's typical only for C-style languages to not have it.
What about using a colon instead of then like this? http://www.java2s.com/Code/Ruby/Statement/layoutanifstatementisbyreplacingthethenwithacolon.htm
There are various ways you could short circuit if you wanted to do so.
The conditional statement is just part of the Ruby syntax to make it more English like.

Resources