How not to use GOTO function here - programming-languages

I know the global resentment of the goto logic.. but here it goes. Here is the case, say you have a function take in a status and decide which action you are going to take. This is a pseudo-code in python (as a joke.)
def function(status, condition, value):
if(status == A) :
goto actionA
if(status == B) :
goto actionB
if(value > 1 or condition == C):
goto actionA
...more conditions you got the idea.
return;
actionA:
dosthA
return
actionB:
dosthB
return
...more actions
My question is, how would you implement such code?
It needs to be easy to read. If later you decide to add an action or add an status or condition, you can do that with some confidence that it will not break earlier logic.

You are jumping out of the conditional and down to your labels after every condition so only one of these can run.
In order to avoid duplicating the actionA code and avoid goto, you can just move your conditions around. dosthA will execute if status == A or if the status is not B (because then the other block will run) and the third condition matchs. Careful to preserve the behavior I get this:
def function(status, condition, value):
if(status == A or (status != B && (value > 1 or condition == C))) :
dosthA
return
if(status == B) :
dosthB
return
...more conditions you got the idea.
return;
Also this is effectively a bunch of "else if"s or a switch since you're returning. Using "else if" or switch would probably increase clarity but in order to make the fewest changes an illustrate the actual important part of the answer I didn't make this into "else if"s.
By the way I'm a firm believer that the use of goto is a bad idea. It's worth reading Edsger W. Dijkstra's influential Go To Statement Considered Harmful.

Related

Why does the expression: If (A:=!A) evaluate differently each time a hotkey is pressed?

In an Autohotkey script, once a user presses the CapsLock key, a SplashText should pop up indicating that it is ON, or out when it is OFF, the problem here is not about the code that gets it to work but how much simpler it can get.
There are different ways that do it, some need about 25 lines, some use SetTimer and GetKeyState internal functions and several loops to get it to run, some just about five and no loops.
Simplest:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (Tog:=!Tog)
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
else
SplashTextOff
return
How does: If (Tog:=!Tog) get this code running so easily? Tog is just a variable not initiated, and each time the CapsLock is pressed it is continuously changing its value from 1 to 0
It seems to be acting as a Flag in the code? what am I missing in this line:
If (Tog:=!Tog)
What makes it evaluate different each time?
This is one below is another approach with A = 0 working as a switch, I made this one and it doesn't quite get as simple as I'd like it to be but it does the job.
Longer code:
#SingleInstance Force
SetCapsLockState, Off
~CapsLock::
If (A = 0)
{
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
A=1
}else
{
SplashTextOff
A=0
}
return
Longest code:
This last one gets the same result but checks the actual physical state of the key It wouldn't rely on SetCapsLockState, Off at the top of the script to make sure a switch will do the rest of the work in just one line as the simpler one.
#SingleInstance Force
#Persistent
SetTimer, StateCapsLockON_Timer, 100
Return
~CapsLock::
StateCapsLockON_Timer
If GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, 100
SplashTextOn ,350 ,35 , Wanted !, [CapsLock] Activated.
SetTimer, StateCapsLockON_Timer, Off
}
Return
StateCapsLockOFF_Timer:
If !GetKeyState("CapsLock", "T")
{
SetTimer, StateCapsLockOFF_Timer, Off
SplashTextOff
SetTimer, StateCapsLockON_Timer, On
}
Return
Any good ideas about the way If (Tog:=!Tog) works in the simplest of these three examples?
I got this now, check logical-not on this link:
https://lexikos.github.io/v2/docs/Variables.htm
If the operand (In this case Tog) is blank or 0, the result of applying logical-not (or !Tog) is 1, which means "true". Otherwise, the result is 0 (false)
if (Tog = 0)
Tog = 1
would bring the same result as:
If Tog:=!Tog
Because an operation was taking place before the If even checked the changed value, if wasn't just comparing data, the operation was happening before the if since the values inside the parenthesis were not just being read but were also being changed and the variable being reassigned.
(expression) Any sub-expression enclosed in parentheses. For example, (3 + 2) * 2 forces 3 + 2 to be evaluated first.
The key difference is the usage of the assignment operator := as opposed to the comparing operator =. Since, as you've seen, you can evaluate expressions in an if-statement, you can actually include both operators in the same if-statement. Here's an example:
f1::
If (( test := 3+2 ) = 5 )
MsgBox
Return
Here "test" is first being assigned the sum of 3+2, then compared to 5. So, the key is that if-statements allow assignments to take place and that assignments take place first, that is, before anything is compared and evaluated to be true or false.
If there is no comparing operator (= , <, >, <=, >=), as is the case in your toggle, it just evaluates whether the variable itself is true or false. If the variable is blank, 0, or false, it evaluates to false; everything else is true, even the string "false".
Now for the fun bit. We can actually reduce your code to one line if we use Progress with the "zh0" option.
~CapsLock::Progress , % ( Tog := !Tog ) ? "zh0 w350 h35" : "Off" ,, [CapsLock] Activated. , Wanted !
Unfortunately, this isn't possible with SplashText since these are actually two separate commands. But the upside is that Progress actually has a lot more options available, so you can change the font size and color, etc.

Why were Logical Operators created?

Almost all programming languages are having the concept of logical operator
I am having a query why logical operators were created. I googled and found its created for condition based operation, but that's a kind of usage i think.
I am interested in the answer that what are the challenges people faced without this operator. Please explain with example if possible.
I am interested in the answer that what are the challenges people faced without this operator.
Super-verbose deeply nested if() conditions, and especially loop conditions.
while (a && b) {
a = something;
b = something_else;
}
written without logical operators becomes:
while (a) {
if (!b) break; // or if(b){} else break; if you want to avoid logical ! as well
a = something;
b = something_else;
}
Of if you don't want a loop, do you want to write this?
if (c >= 'a') {
if (c <= 'z') {
stuff;
}
}
No, of course you don't because it's horrible compared to if (c >= 'a' && c <= 'z'), especially if there's an else, or this is inside another nesting. Especially if your coding-style rules require 8-space indentation for each level of nesting, or the { on its own line making each level of nesting eat up even more vertical space.
Note that a&b is not equivalent to a&&b: even apart from short-circuit evaluation. (Where b isn't even evaluated if a is false.) e.g. 2 & 1 is false, because their integer bit patterns don't have any of the same bits set.
Short-circuit evaluation allows loop conditions like while(p && p->data != 0) to check for a NULL pointer and then conditionally do something only on non-NULL.
Compact expressions were a big deal when computers were programmed over slow serial lines using paper teletypes.
Also note that these are purely high-level language-design considerations. CPU hardware doesn't have anything like logical operators; it usually takes multiple instructions to implement a ! on an integer (into a 0/1 integer, not when used as an if condition).
if (a && b) typically compiles to two test/branch instructions in a row.

Condition in expect block

I just noticed that Spock does not assert the conditions if I add an if clause in the expect block as in
def myTest() {
given:
a = true
expect:
if ( a ) {
1 == 2
}
else {
1 == 1
}
}
The above test will pass since the conditions are not checked. Or the condition checking does not get forwarded pass the if statement.
The workaround to this is to add assert statements inside the if block, i.e. assert 1 == 2.
What I'm interested is, is why the functionality is like this? Is there some other way to workaround this? I'm assuming this has something to do with Groovy if statement functionality, but I don't know the language details well enough. Most probably the if statement does not return anything for the Spock's expect block to work with.
This has nothing to do with groovy. Spock's documentation clearly states that only top-level expressions are considered in then and expect as conditions. It is by design.
Search the link for top.

IF ELSE vs Select Case

I wish to know how this would impact my coding when handling large volumes of data, and how I would construct my logic arguments
Two questions:
1) What are the main differences between IF-ELSE and Select CASE? Does select case operate by evaluating all cases at the same time?
If I have a situation where, by nature of its construction, need to fulfill two or more cases at the same time, for e.g.
int = 5
Select case int
Case >0
Case 5
Case <0
Where I would need to "trigger" both Cases "1" and "2" for action, do I use CASE over IF ELSE?
2) Now for the other case, if I have a variable that will trigger more one case but I would like to restrict to only one case by priority, say I would only like Case "1" for action and exclude the rest, am I right to say that IF-ELSE would triumph in this regard?
EDIT - I realized that my question was phrased poorly. I did some edits to the code
Some clarification on Select Case before actually answering your question:
as you suggested, you can combine several values in one Case switch in VBA, e.g.: Case Is>40, 20, 10, 2 To 3, for more information see documentation on MSDN
It'll execute at most one Case, it'll exit after finding a match (e.g. in the example execute Case >0 then exit without even evaluating Case 5)
It'll only evaluate your variable / expression once and use this same value for all comparisons in contrary to nested if which evaluates multiple time
if you want to execute "both" for a value you can nest if within case:
Case Is > 0
<Common code>
If i = 5 Then
<code only for case 5>
End If
Advantage of Select Case
It's more efficient when your decision is about multiple values of a single variant / expression
it also can be very useful when your expression is e.g. result of a time consuming function, in this case you really can save time compared to if
Advantage of If
Basically it's the good option in all the cases which are not described for Select Case e.g.:
you have only two options to choose from (it's the same time with both if and select, but if is easier to read)
you have multiple expressions to consider during decision and you can't easily convert them to a single value
Similarly to Select Case you can also use elseif to prepare multiple comparisons, it'll also stops at first fullfilled criteria, but here your expression will be evaluated every time until finding the match and of course you can use more complex criteria.
If-Else and Switch statement are good in different cases.
For example, If-Else has logic conditions like:
if (n < 5 && a > 5) { } // && is a logical AND
and nested constructions like
if (n < 5) {
if (n < 0)
{
}
else
{
}
} else { }
You cannot do this in switch statement.
However, switch is better, more elegant and faster in some situations:
switch (a)
{
case 1:
case 2:
case 3:
// ...
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 10:
break;
default:
break;
}
would look very bad in if-else format:
if (a == 1 || a == 2 || a == 3)
{
}
else
if (a == 4)
{
}
else
// ...
I'm not sure about your case but in most languages switch statement is more performant.
Simply said, use switch statement every time it is possible and there are more than two cases. If there are only two cases or it is impossible to use switch - use if.

Variable assignment in 1st condition and using same variable in 2nd condition Well defined?

Is this well defined?
Streamreader ^reader = gcnew Streamreader("test.txt");
String ^line;
while ((line = reader->ReadLine()) != nullptr && line != "")
{
//do stuff
}
I believe that I read somewhere that it is not guaranteed that the assignment is executed before the 2nd conditional. It may be that I'm wrong or that this just applies for C.
Google did not help me with this, that is why I am asking here :)
With && and ||, it is guaranteed to evaluate the first condition (including the assignment) before evaluating the second condition.
With bitwise & and |, on the other hand, no such guarantees are made.
There is a related answer here with a number of good references: Is short-circuiting logical operators mandated? And evaluation order?
Short answer if you haven't overloaded && and || you'll get short-circuit evaluation, which goes from left to right. Take a look in the link.

Resources