Reevaluating or storing boolean in non-evaluated form in TI-BASIC program - ti-basic

I'm passing a boolean expression in terms of some variable I into a TI-BASIC program that manipulates I, but the boolean expression is only evaluated once - at the beginning of the program's execution.
Here is a sample program:
Prompt J
0 -> I
Lbl 1
1 + I -> I
Disp I
If J
Then
Goto 2
Else
Goto 1
End
Lbl 2
End
(This is not the actual program I'm writing, which is more complicated and thus cannot use a for loop; the above program could obviously be written more elegantly with a for loop.)
We increment I by 1, starting with the number 0. After every increment, we check whether J is true, and if so, we stop.
If I pass in J=I≠5, the program stops after printing 1.
If I pass in J=I=5, the result is not expected. I intend for the program to stop when I=5 is true, but instead the program continues indefinitely. This means that J is only evaluated at the beginning of the program.
Is it possible to reevaluate J in every execution of that loop?
I assume that J is being replaced with 0 and 1 as soon as it is passed in. To rephrase my question, is it possible to input/keep the boolean expression as an unevaluated string/literal? Then I would just call something like eval(J) within the program.

The assumption in your update is correct; The J is being replaced by a numerical value.
The answer to your rephrased question is yes, you can pass an expression, but you have to use a function variable instead of a real variable:
Prompt Y1
Whenever Y1 is called, it will re-evaluate, so if you store I=5 to Y1, then Y1 will return 0 whenever I≠5 and 1 when I=5.

DelVar IPrompt J
Yes I meant to not put a newline there. You don't need one. Trust me.
While not(J
I+1->I
Disp I
End
This is your program, optimized. Your problem is that J is never changed after your original prompt, so the loop will go around and around forever. Yes, you can reevaluate J in every iteration, but you do need to actually DO it, if you want your program to work.

I don't know why you're using Lbl/Goto loops here; I would advise that if a For loop doesn't work for you, then try to use While or Repeat loops instead. They're neater and faster.
With that aside,
You're incrementing I by 1 and checking J≠0 every time. I and J are entirely different variables, and they're not going to interact with each other unless you make them interact. If your initial input is J=0, then the program will run forever.
I intend for the program to stop when I=5 is true, but instead the program continues indefinitely.
But there is nothing in the code that checks if I=5. You should put an If I=5 somewhere if you want this to happen.
Is it possible to reevaluate J in every execution of that loop?
Yes, but you need to manually tell the calculator to do so.
I assume that J is being replaced with 0 and 1 as soon as it is passed in.
This is not the case. Rather, the If J in your code will output FALSE if J=0, and TRUE for any other value of J.
Also, you don't need the End at the end of your program; in TI-BASIC, the End command indicates the end of code blocks such as If:Then conditionals and For/While/Repeat loops.
I suggest you read here: http://tibasicdev.wikidot.com

Related

fpc: how to initialize a global variable before it is initialized

I am making a simple text game in pascal (a real beginner one). There is a general routine, that is repeated several times (the cycles variable, representing the levels). In the beginning of the routine there is a part where character`s name is asked. If the general repeat loop is complete or aborted at some level(1-4), the game goes back to the first sort of menu. I want the name to be asked only the first time, but, of course, I get the "variable "cycles" does not seem to be initialized" warning. Is there a way to restructure the code to avoid it?
Thanks.
The code excerpt (unnecessary details left behind):
program rpg_text_game;
var
game_action:char;
name:string;
cycles:1..5;
begin
repeat
writeln('Welcome to the game.');
writeln('To continue press "g",');
writeln('to read the license of this game press "i",');
writeln('and to quit press "q" and "enter": ');
readln(game_action);
case game_action of
'i', 'I':
{shows license}
'g', 'G':
{game begins}
if not (cycles in [2,3,4,5]) then
begin
writeln('Please enter your name: ');
readln(name);
end;
repeat
cycles:=1; //is initialized here
{actual game process - score is calculated based on *cycles* amount, that adds +1 with each tick ("if success then cycles:=cycles+1")}
{cycles - 1,2,3,4,5}
writeln('Do you want to try again, y/n?');
readln(game_action);
until(game_action='n') or (game_action='N');
until (game_action='q') or (game_action='Q');
writeln();
writeln('Press enter to quit');
readln();
end.
So, how to initialize/change the cycles variable (or even any other) to avoid that message and not to cheat by turning off the compiler hint option?
If cycles is a global variable, like in your example code, then simply do, in the main block of the program, before you start anything:
begin
cycles := 1;
game_action := Chr(0);
{ etc... }
...
end.
That is how you generally initialize global variables: in the main begin/end. block. Some versions of Pascal also allow (for global variables):
var
cycles: 1..5 = 1;
{ etc... }
but others don't. I don't know if your Pascal allows it. If it does, you won't have to initialize in the main block anymore. But note that that probably doesn't work for local variables of a function or procedure. There, you will probably have to use the (outer) begin/end; block of the function or procedure.
FWIW, the main block of a program can usually be found at the very end of the program, after all the const, type, var, procedure and function declarations and it ends with a dot (.).
Also note that the comment is right: split your program into separate functions and procedures, each with their own single task, and pass any information necessary to them. Do not write monolithic blocks of code. That is hard to read and hard to maintain. For instance, for each (or most) of your case items, create a separate procedure with the necessary parameters and call those from your case statement. That makes your code much easier to read, also for you.
In the first iteration of the loop in the code as is, cycles is read (by the IF NOT (cycles in [])) before being initialized. The compiler rightfully emits a warning for that.
The solution is simple, initialize it before the first REPEAT, or if you go more object pascal style, like Rudy says.

Efficient way of checking property from a large set of data inside a loop

Please, consider this generic piece of code:
for j = 0 to (Array.length myArray) - 1 do
if property.(id) then
(* do a bunch of stuff*)
done
Here, property is a very large array of boolean.
In this experiment, we have 2 cases:
in the 1st, property.(id) is always true.
In the second, property.(id) can be either true or false.
We want that the 2nd case win, since it skips code execution.
But this doesn't happen because of branch conditioning.
We have also tried partitioning property instead of a if statement, but the 1st case still wins.
(These are all suggestions by OCaml community members).
Our problem definition is: we can detect a property that allows us to skip part of the code. But using a large boolean array to save which element has this property makes the checking for the property itself slower than the saved code execution.
Thus, the question now is more general: what is the better way of implementing this problem?
We really appreciate any suggestion from the community.
In my opinion, there are two possible solutions for your problem:
If you still want to use the for-loop, then I suggest using exception to exit the for-loop
exception YourExn of something
try
for j = 0 to (Array.length property) - 1 do
if property.(id) then
(* do a bunch of stuff*)
else raise (YourExn result)
done
with YourExn res -> (* do something *)
exception YourExn of something
The other solution is to just write a recursive function instead of using for-loop. I suggest using this solution, as using recursive function is kind of a standard in functional programming.
let rec traverse property id =
if id > (Array.length property) then
(* exit *)
else if property.(id) then
(* do a bunch of stuff*)
traverse property (id + 1)
else
(* exit *) in
traverse property 0
After reading a similar question here Why is it faster to process a sorted array than an unsorted array?, the best solution for my code is to write a branchless condition, as proposed in section So what can be done? of that answer.

Maze Generation - Converting From C++

Ok, many of you may not know what Pawn is. I'm converting the source from here http://en.wikipedia.org/wiki/User:Dllu/Maze to work in my SA:MP server. Pawn is a very easy code to understand so don't run because you don't know the language.
For some reason, only the outside padding and first cell (which they should be) are set to be in the maze. So, all the walls are there, and that's good. The problem is that only one cell is in the maze, and that is the starting point.
Please help!
I pasted it on Pastebin because pastebin actually has a pawn syntax.
http://pastebin.com/wN6KFyFz
Also, it is supposed to support both backtrack and prim. Both have the same outcome. From what I tested I know that it never reaches the debug prints that look like this ("%i, %i | %x, %x, %x"). Well, it does reach the one in the while(!successful) loop, 1 time or 2-3 every once in a while.
It's not working because you have changed some of the do...while loops in the C++ code to while loops in Pawn, which is not logically equivalent. do...while loops always execute at least once, whereas while loops execute zero or more times.
For example this code assumes that it will be run at least once:
do{
//randomly find a cell that's in the maze
xcur=rand()%(xsize-2)+1;
ycur=rand()%(ysize-2)+1;
}while(!MAZE[xcur][ycur].in ||
MAZE[xcur][ycur-1].in&&MAZE[xcur][ycur+1].in&&
MAZE[xcur-1][ycur].in&&MAZE[xcur+1][ycur].in);
If you change that to a while loop then the loop condition will test false (because you start on a cell that's in the maze and isn't surrounded by cells that are) and so the loop will not be entered, xcur and ycur will never change and you will be stuck at the starting location forever!
If whatever version of Pawn you are using doesn't support do...while loops then you can fake them like this:
new bool:doOnce;
doOnce=true;
while(doOnce||(condition))
{
doOnce=false;
// do stuff...
}
is the same as
do
{
// do stuff...
} while(condition)
assuming that evaluating the condition does not have any side effects, like incrementing or assigning variables, or Pawn is able to short-circuit the evaluation when doOnce is true.
Or else you can do it like this:
while(true)
{
// do stuff....
if(!condition)
break;
}

What is the difference between call-by-reference and call-by-value-return

As the title says I'm curious about the difference between "call-by-reference" and "call-by-value-return". I've read about it in some literature, and tried to find additional information on the internet, but I've only found comparison of "call-by-value" and "call-by-reference".
I do understand the difference at memory level, but not at the "conceptual" level, between the two.
The called subroutine will have it's own copy of the actual parameter value to work with, but will, when it ends executing, copy the new local value (bound to the formal parameter) back to the actual parameter of the caller.
When is call-by-value-return actually to prefer above "call-by-reference"? Any example scenario? All I can see is that it takes extra memory and execution time due to the copying of values in the memory-cells.
As a side question, is "call-by-value-return" implemented in 'modern' languages?
Call-by-value-return, from Wikipedia:
This variant has gained attention in multiprocessing contexts and Remote procedure call: if a parameter to a function call is a reference that might be accessible by another thread of execution, its contents may be copied to a new reference that is not; when the function call returns, the updated contents of this new reference are copied back to the original reference ("restored").
So, in more practical terms, it's entirely possible that a variable is in some undesired state in the middle of the execution of a function. With parallel processing this is a problem, since you can attempt to access the variable while it has this value. Copying it to a temporary value avoids this problem.
As an example:
policeCount = 0
everyTimeSomeoneApproachesOrLeaves()
calculatePoliceCount(policeCount)
calculatePoliceCount(count)
count = 0
for each police official
count++
goAboutMyDay()
if policeCount == 0
doSomethingIllegal()
else
doSomethingElse()
Assume everyTimeSomeoneApproachesOrLeaves and goAboutMyDay are executed in parallel.
So if you pass by reference, you could end up getting policeCount right after it was set to 0 in calculatePoliceCount, even if there are police officials around, then you'd end up doing something illegal and probably going to jail, or at least coughing up some money for a bribe. If you pass by value return, this won't happen.
Supported languages?
In my search, I found that Ada and Fortran support this. I don't know of others.
Suppose you have a call by reference function (in C++):
void foobar(int &x, int &y) {
while (y-->0) {
x++;
}
}
and you call it thusly:
int z = 5;
foobar(z, z);
It will never terminate, because x and y are the same reference, each time you decrement y, that is subsequently undone by the increment of x (since they are both really z under the hood).
By contrast using call-by-value-return (in rusty Fortran):
subroutine foobar(x,y):
integer, intent(inout) :: x,y
do while y > 0:
y = y - 1
x = x + 1
end do
end subroutine foobar
If you call this routine with the same variable:
integer, z = 5
call foobar(z,z)
it will still terminate, and at the end z will be changed have a value of either 10 or 0, depending on which result is applied first (I don't remember if a particular order is required and I can't find any quick answers to the question online).
Kindly go to the following link , the program in there can give u an practical idea regarding these two .
Difference between call-by-reference and call-by-value

Is it a bad practice to use break in a for loop? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
Is it a bad practice to use break statement inside a for loop?
Say, I am searching for an value in an array. Compare inside a for loop and when value is found, break; to exit the for loop.
Is this a bad practice? I have seen the alternative used: define a variable vFound and set it to true when the value is found and check vFound in the for statement condition. But is it necessary to create a new variable just for this purpose?
I am asking in the context of a normal C or C++ for loop.
P.S: The MISRA coding guidelines advise against using break.
No, break is the correct solution.
Adding a boolean variable makes the code harder to read and adds a potential source of errors.
Lots of answers here, but I haven't seen this mentioned yet:
Most of the "dangers" associated with using break or continue in a for loop are negated if you write tidy, easily-readable loops. If the body of your loop spans several screen lengths and has multiple nested sub-blocks, yes, you could easily forget that some code won't be executed after the break. If, however, the loop is short and to the point, the purpose of the break statement should be obvious.
If a loop is getting too big, use one or more well-named function calls within the loop instead. The only real reason to avoid doing so is for processing bottlenecks.
You can find all sorts of professional code with 'break' statements in them. It perfectly make sense to use this whenever necessary. In your case this option is better than creating a separate variable just for the purpose of coming out of the loop.
Using break as well as continue in a for loop is perfectly fine.
It simplifies the code and improves its readability.
Far from bad practice, Python (and other languages?) extended the for loop structure so part of it will only be executed if the loop doesn't break.
for n in range(5):
for m in range(3):
if m >= n:
print('stop!')
break
print(m, end=' ')
else:
print('finished.')
Output:
stop!
0 stop!
0 1 stop!
0 1 2 finished.
0 1 2 finished.
Equivalent code without break and that handy else:
for n in range(5):
aborted = False
for m in range(3):
if not aborted:
if m >= n:
print('stop!')
aborted = True
else:
print(m, end=' ')
if not aborted:
print('finished.')
General rule: If following a rule requires you to do something more awkward and difficult to read then breaking the rule, then break the rule.
In the case of looping until you find something, you run into the problem of distinguishing found versus not found when you get out. That is:
for (int x=0;x<fooCount;++x)
{
Foo foo=getFooSomehow(x);
if (foo.bar==42)
break;
}
// So when we get here, did we find one, or did we fall out the bottom?
So okay, you can set a flag, or initialize a "found" value to null. But
That's why in general I prefer to push my searches into functions:
Foo findFoo(int wantBar)
{
for (int x=0;x<fooCount;++x)
{
Foo foo=getFooSomehow(x);
if (foo.bar==wantBar)
return foo;
}
// Not found
return null;
}
This also helps to unclutter the code. In the main line, "find" becomes a single statement, and when the conditions are complex, they're only written once.
There is nothing inherently wrong with using a break statement but nested loops can get confusing. To improve readability many languages (at least Java does) support breaking to labels which will greatly improve readability.
int[] iArray = new int[]{0,1,2,3,4,5,6,7,8,9};
int[] jArray = new int[]{0,1,2,3,4,5,6,7,8,9};
// label for i loop
iLoop: for (int i = 0; i < iArray.length; i++) {
// label for j loop
jLoop: for (int j = 0; j < jArray.length; j++) {
if(iArray[i] < jArray[j]){
// break i and j loops
break iLoop;
} else if (iArray[i] > jArray[j]){
// breaks only j loop
break jLoop;
} else {
// unclear which loop is ending
// (breaks only the j loop)
break;
}
}
}
I will say that break (and return) statements often increase cyclomatic complexity which makes it harder to prove code is doing the correct thing in all cases.
If you're considering using a break while iterating over a sequence for some particular item, you might want to reconsider the data structure used to hold your data. Using something like a Set or Map may provide better results.
break is a completely acceptable statement to use (so is continue, btw). It's all about code readability -- as long as you don't have overcomplicated loops and such, it's fine.
It's not like they were the same league as goto. :)
It depends on the language. While you can possibly check a boolean variable here:
for (int i = 0; i < 100 && stayInLoop; i++) { ... }
it is not possible to do it when itering over an array:
for element in bigList: ...
Anyway, break would make both codes more readable.
I agree with others who recommend using break. The obvious consequential question is why would anyone recommend otherwise? Well... when you use break, you skip the rest of the code in the block, and the remaining iterations. Sometimes this causes bugs, for example:
a resource acquired at the top of the block may be released at the bottom (this is true even for blocks inside for loops), but that release step may be accidentally skipped when a "premature" exit is caused by a break statement (in "modern" C++, "RAII" is used to handle this in a reliable and exception-safe way: basically, object destructors free resources reliably no matter how a scope is exited)
someone may change the conditional test in the for statement without noticing that there are other delocalised exit conditions
ndim's answer observes that some people may avoid breaks to maintain a relatively consistent loop run-time, but you were comparing break against use of a boolean early-exit control variable where that doesn't hold
Every now and then people observing such bugs realise they can be prevented/mitigated by this "no breaks" rule... indeed, there's a whole related strategy for "safer" programming called "structured programming", where each function is supposed to have a single entry and exit point too (i.e. no goto, no early return). It may eliminate some bugs, but it doubtless introduces others. Why do they do it?
they have a development framework that encourages a particular style of programming / code, and they've statistical evidence that this produces a net benefit in that limited framework, or
they've been influenced by programming guidelines or experience within such a framework, or
they're just dictatorial idiots, or
any of the above + historical inertia (relevant in that the justifications are more applicable to C than modern C++).
In your example you do not know the number of iterations for the for loop. Why not use while loop instead, which allows the number of iterations to be indeterminate at the beginning?
It is hence not necessary to use break statemement in general, as the loop can be better stated as a while loop.
I did some analysis on the codebase I'm currently working on (40,000 lines of JavaScript).
I found only 22 break statements, of those:
19 were used inside switch statements (we only have 3 switch statements in total!).
2 were used inside for loops - a code that I immediately classified as to be refactored into separate functions and replaced with return statement.
As for the final break inside while loop... I ran git blame to see who wrote this crap!
So according to my statistics: If break is used outside of switch, it is a code smell.
I also searched for continue statements. Found none.
It's perfectly valid to use break - as others have pointed out, it's nowhere in the same league as goto.
Although you might want to use the vFound variable when you want to check outside the loop whether the value was found in the array. Also from a maintainability point of view, having a common flag signalling the exit criteria might be useful.
I don't see any reason why it would be a bad practice PROVIDED that you want to complete STOP processing at that point.
In the embedded world, there is a lot of code out there that uses the following construct:
while(1)
{
if (RCIF)
gx();
if (command_received == command_we_are_waiting_on)
break;
else if ((num_attempts > MAX_ATTEMPTS) || (TickGet() - BaseTick > MAX_TIMEOUT))
return ERROR;
num_attempts++;
}
if (call_some_bool_returning_function())
return TRUE;
else
return FALSE;
This is a very generic example, lots of things are happening behind the curtain, interrupts in particular. Don't use this as boilerplate code, I'm just trying to illustrate an example.
My personal opinion is that there is nothing wrong with writing a loop in this manner as long as appropriate care is taken to prevent remaining in the loop indefinitely.
Depends on your use case. There are applications where the runtime of a for loop needs to be constant (e.g. to satisfy some timing constraints, or to hide your data internals from timing based attacks).
In those cases it will even make sense to set a flag and only check the flag value AFTER all the for loop iterations have actually run. Of course, all the for loop iterations need to run code that still takes about the same time.
If you do not care about the run time... use break; and continue; to make the code easier to read.
On MISRA 98 rules, that is used on my company in C dev, break statement shall not be used...
Edit : Break is allowed in MISRA '04
Ofcourse, break; is the solution to stop the for loop or foreach loop. I used it in php in foreach and for loop and found working.
I think it can make sense to have your checks at the top of your for loop like so
for(int i = 0; i < myCollection.Length && myCollection[i].SomeValue != "Break Condition"; i++)
{
//loop body
}
or if you need to process the row first
for(int i = 0; i < myCollection.Length && (i == 0 ? true : myCollection[i-1].SomeValue != "Break Condition"); i++)
{
//loop body
}
This way you can have a singular body function without breaks.
for(int i = 0; i < myCollection.Length && (i == 0 ? true : myCollection[i-1].SomeValue != "Break Condition"); i++)
{
PerformLogic(myCollection[i]);
}
It can also be modified to move Break into its own function as well.
for(int i = 0; ShouldContinueLooping(i, myCollection); i++)
{
PerformLogic(myCollection[i]);
}

Resources