Roblox if Statement not running - if-statement

I was wondering if I could get some help with this small script I tested.
For some reason, the if statement isn't executing, meaning the function won't run even if the value doesn't equal Rinzler. charData is a StringValue to be specific.
local charData = script.Parent.Data.CharacterData
local active = game.Workspace.Part
function change()
if not charData.Value == "Rinzler" then
charData.Value = "Rinzler"
print("Character has changed to Rinzler.")
end
end
active.Touched:Connect(change)
"Character has changed to Rinzler" isn't printing in the console no matter what I do.

The problem is here if not charData.Value == "Rinzler"
The not operator has higher priority than == in operator precedence list.
Update that code to:
function change()
if charData.Value ~= "Rinzler" then
charData.Value = "Rinzler"
print("Character has changed to Rinzler.")
end
end

Related

Google app script IF condition not matching 0, empty and null

I have issues with Google app script IF condition.
Problem i am facing its not returning value TRUE rather going to next/ Else statements.
Code i am having:
const numberOfRowsToUpdate = deliveryDate.length;
// For each item making the for loop to work
for (i=0 ; i < numberOfRowsToUpdate;i++) {
debugger;
var dp = depositAmount[i];
if(dp!==""|| dp!==0 || dp !==null || dp!==isblank())
{ .... <statements>
}
}
I want to check whether particular cell of the array is empty / zero / returning null value.
thanks in advance for the help.
SUGGESTION
I have used a similar script I'm using for a spreadsheet in which I need to search through every row for some data, but obviously adpating it to your case, and since I don't have your full code (and still can't comment asking for more info due to my recent joining in SO), I had to simplify it, in hope it will work for you.
What I did was use your incrementing i index from the for loop and use it to scan every row, while adjusting it to fit your array index, because we can't have i = 0 as a row index, and it would skip the first value on the array if left as i = 1).
SCRIPT
function test(){
const n = 6;
var depositAmount = [7,2,0,2,0,8];
// For each item making the for loop to work
var ss = SpreadsheetApp.getActive();
Logger.log(ss.getName());
for (var i=1 ; i <= n ;i++) {
debugger;
ss.getRange("A"+i).setValue(1);
var dp = depositAmount[i-1];
Logger.log(dp)
if(dp != "" || dp != 0 /*|| dp != null || dp != isblank()*/)
{
ss.getRange("B"+i).setValue(dp);
}
else
{
ss.getRange("C"+i).setValue("VOID")
Logger.log(i-1+"th index of array is "+ss.getRange("C"+i).getValue());
}
}
};
RESULTS
After running it with the four original conditions you used, i didn't get the expected result, as you must have, leading to this:
.
While studying your original code, I stumbled upon this question about the differences between == and ===, as well as != and !==.
So before I used this in our favor, I tried the old trial and error method, using only one condition at a time, and then stacking them up. Not only I managed to find out the !== operator didn't work properly for this case, but also the comparison with null and the isblank() function (at least in my case, because i haven't defined it, and I'm not sure it is a built-in function) also don't work with either operator.
Therefore, using the != operator helps you better than the strict !==.
The result of the final script is that:
.
NOTES
I also tried using a null value within the array ([7,2,0,2,,8]), but it would always break away from the loop, never scanning the whole array, and I don't know how to circle that.
Here is the Execution Log for this script:
EDIT
While fooling around, I found this question and the answer by Etienne de Villers might be even faster to apply, or at least more useful for your purposes.

The generate if condition must be a constant expression

I am trying to create an Immediate Generator for RISC-V assembly, but I have encountered an error with if statement.
Here is my code in Verilog:
module signextend(in, out, sel);
parameter nin = 32;
parameter nout = 32;
input [nin-1:nin-25] in;
input [2:0] sel;
output [nout-1:0] out;
if (sel == 3'b000)
begin
assign out[19:0] = in[31:12];
assign out[31:20] = {12{in[31]}};
end
else if (sel == 3'b001)
begin
assign out[11:0] = in[31:20];
assign out[31:12] = {20{in[31]}};
end
else if (sel == 3'b010)
begin
assign out[4:0] = in[24:20];
assign out[31:5] = 0;
end
else if (sel == 3'b011)
begin
assign out[3:0] = in[11:8];
assign out[4:9] = in[30:25];
assign out[10] = in[7];
assign out[11] = in[31];
assign out[31:12] = {20{in[31]}};
end
else if (sel == 3'b100)
begin
assign out[4:0] = in[11:7];
assign out[11:5] = in[31:25];
assign out[31:12] = {20{in[31]}};
end
else if (sel == 3'b101)
begin
assign out[9:0] = in[21:30];
assign out[10] = in[20];
assign out[18:11] = in[19:12];
assign out[19] = in[31];
assign out[31:20] = {12{in[31]}};
end
else
assign out = 32'hxxxx;
endmodule
The problem exists in each if statement:
The generate if condition must be a constant expression.
You need to put all your code inside an always block and remove the assigns:
always #(*) begin
if (sel == 3'b000)
begin
out[19:0] = in[31:12];
out[31:20] = {12{in[31]}};
end
else if (sel == 3'b001)
// etc
An always block contains a little bit of software (your if statements) that models a little bit of hardware (the resulting combinational logic).
It is legal to have an if statement outside an always (or initial) block, but then it means something different. Then it means conditional including of hardware, ie if some condition is true, include this hardware. Such a condition has to be static, ie fixed at compile time. It cannot be an input, like your sel. If you think about it, that makes total sense: how could you create some hardware that magically appears and disappears depending on the value of some input? You can't. That is why you are getting your error.
You need to remove the assigns, because while it is legal to have an assign inside an always block, it means something weird. Never do it.

How does this bool variable work exactly?

I am new to programming, so please forgive me if my question is too basic.
For the following code, I don't know how exactly the bool variable "more" works. It says that while loop will do the content of the loop whenever the "more" is true, but
how does the computer know that the more is true? Is it smart enough to know that "more" literally means when the user inputs additional value through keyboard? Also, does it know that a negative input is not considered "more" but only positive input is considered "more"?
Inside the while loop, it says that the more is false when the input value is 0. However, it does not logically make sense that more is false when it already goes through the while loop, which only runs when the more is true!
I learned that we will get an infinite loop when "while is always true". It seems like the while loop will always be true since more = true.
Please help me out with this question!!
vector<double> salaries;
cout << "Please enter salaries, 0 to quit:" << endl;
bool more = true;
while (more)
{
double s;
cin >> s;
if (s == 0)
more = false;
else
salaries.push_back(s);
}
(1): The computer (or the compiler) is not smart enough to connect more to a literal meaning.
(2): more can be changed inside the loop, which is what happens when you enter 0. After changing more to false, the condition in while (more) is re-evaluated. As more is now false, the loop is exited.
(3): No, more is not always true, see (2).
Ok, so point by point:
1) The compiler knows that more is true because on line 3 it says:
bool more = true;
This creates the bool more and gives it the value true.
2) more is then set to false if s is equal to zero. Although more is true at the beginning of the loop there is nothing to say it can't be changed within the loop (this is called mutability).
3) Because more gets set to false within the loop, the loop will stop executing. This will only happen if someone enters 0 for the input. If this doesn't happen you are correct, the loop will get run forever.
This is a fairly common while loop construct which allows an arbitrary number of values to be added to the vector salaries. In your question you hint that positive numbers should not be allowed, it is worth noting that there is nothing in the code enforcing this. Perhaps it would be better to change the line:
if (s == 0)
to:
if (s <= 0.0)
This way the loop will stop executing if a 0 value is entered or if a negative value is entered.
In your code snippet variable more is explicitly set two times: before the loop and inside the loop if s is equal to zero
bool more = true;
while (more)
{
//...
if (s == 0)
more = false;
//..
}
Thus when more will be set to false within the body of the loop
if (s == 0)
more = false;
the loop stops its iterations because the condition in while will not true
while (more)
Take into account that the condition above is equivalent to
while (more == true)
Though there is no great sense to write such a way because variable more is already a boolean expression.
Also take into account that according to the C++ Standard
4.12 Boolean conversions
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer
to member type can be converted to a prvalue of type bool. A zero
value, null pointer value, or null member pointer value is converted
to false; any other value is converted to true. For
direct-initialization (8.5), a prvalue of type std::nullptr_t can be
converted to a prvalue of type bool; the resulting value is false.
You could rewrite your code snippet in other way without using variable more. For example
vector<double> salaries;
cout << "Please enter salaries, 0 to quit:" << endl;
double s;
while ( cin >> s && s != 0 )
{
salaries.push_back(s);
}
Or the condition in while could be written even like
while ( cin >> s && s )
So according to the quote of the C++ Standard if s is not equal to 0 then it is converted to bool true. As for expression cin >> s then class std::istream has explicit conversion operator that converts std::cin to boolean value if the stream is not in erroneous state.
The variable more is explicitly set to true before the loop is entered. In the loop's body, if more is set false, nothing else is executed in the loop's body afterwards. The flow of execution goes again to the beginning of the loop, where the loop's condition is evaluated. As more is false, the loop's body is not executed again.
No, the computer(compiler, more appropriate) does not know the intent behind your coding, specifics behind your variables and functions, It only working on set of instructions, which need to be syntactically correct.
in while(more) it's job is to run the loop for as long as more boolean is true and skip to next instruction when false.
while(condition),here condition is checked once for every iteration, and during the iteration, the compiler does not bother to check and skip the rest of the code upon more being false. the condition is checked only before beginning an iteration.
Absolutely, just assume while(true){set of instructions;} the condition is always true and therefore the block of code is always executed and we call this an Infinite Loop.
Well, it seems that you don't really understand the way your compiler works.
First of all, your computer is not smart or dumb, it's merely a machine and interprets whatever you give them to. So, it all comes to the way you have programmed your program. Having said that we move on:
The
while(condition) {
commands;
}
loop works basically as follows:
It checks the condition whatever that might be at the time it your
program flow enters the loop.
It continues to execute whatever commands are if and only if the previous checked condition was true.
If it wasn't true then your programs continues to execute whatever command follow your while loop.
When the execution of commands have finished it goes again to check the condition in while.
Again, if it's true it carries on with commands.
If not, then again it continues to the following your while commands.
So, to sum up, your compiler, computer or your digital friend does not check for logical flows in how you name your variables, if false does not make sense, etc. It merely checks if condition is true. That's it.
Finally an infinite loop will occur if the initial condition was true when entering the loop and when exiting the loop always continues to be true (not does not change inside the loop because it could change and also get a true values when exiting the loop).
You have some misunderstandings with how things work in C++. You can think of your program as an abstract machine. Each variable is a storage location that maintains some state. The more variable is an example of this state. You can think of the variable as a location in memory that maintains the value that you give it. The total program state is allowed to change throughout the duration of the runtime of the program.
Each assignment (the = operator) sets the state of the variable to the value on the right hand side of the assignment.
So when you say:
bool more = true;
The storage location named more is set to the value true. The storage location will remain true until you assign a new value to it.
Note that in C++ statements are evaluated sequentially. Since the values of the variables may change over time, the order of the statements matters.
Later on when you say:
while (more)
{
// ...
}
The first time that more is evaluated, it is true, but again, since more is a variable, that value may change over time.
Once you are inside the while loop, the more variable is conditionally assigned false when the variable s is equal to 0. Notice that the == is truly an equality check unlike the = operator.
if (s == 0)
more = false;
Note that you should be aware that s is of type double and the literal 0 is of type int. Fortunately for you, this will work since C++ will automatically promote the int to a double type to do the equality comparison. However, it probably makes since to use a literal 0.0 to be clear that you expect for s to be a double.
Since the value of s is dependent on the value that is read from cin, the equality condition will sometimes be true and sometimes false depending on what is entered by the user. But if more is assigned false, it when then cause the while loop to terminate on its next iteration. In other words, when you reach the close brace } the program will repeat back to the beginning of the while and try to re-evaluate more, at that point, when more is false the while loop will end.
vector<double> salaries;
cout << "Please enter salaries, 0 to quit:" << endl;
bool more = true;
while (more)
{
double s;
cin >> s;
if (s == 0)
more = false;
else
salaries.push_back(s);
}
A while loop will iterate over and over until the condition between the ()is not met. When you start the cycle you start with bool more = true; That way you're telling the while(more) loop to keep iterating while more is true. Inside the code you ask for input with cin >> s; and if the input is 0 the variable more will change to false, it will iterate again and since while(more) is awaiting for the morevariable to be true the condition won't be true and the cycle will end. If you input other value than 0 the cycle will store that value into the vector<double> salaries vector.
One way for getting the values that were stored in the vector is:
for(int i = 0; i<salaries.size(); i++){
cout<< salaries[i] << endl;
}
In which case you're telling the compiler to iterate with a variable called i starting from the value 0 until the value of i is < than the value of salaries.size(), for each iteration, i will increase and when the condition is no longer met, the cycle will end.
As a recomendation, use the std namespace for your types, it will be of help in future code to avoid bringing everything from the std namespace into your code.
std::vector<double> salaries;
std::cout << "Please enter salaries, 0 to quit:" << std::endl;
bool more = true;
while (more)
{
double s;
std::cin >> s;
if (s == 0)
more = false;
else
salaries.push_back(s);
}
and
for(int i = 0; i<salaries.size(); i++){
std::cout<< salaries[i] << std::endl;
}

C++ variable value not changing

I'm using the following code (it's been super simplified to get to the root of my problem).
#include <iostream>
namespace std;
int user;
int submit(int);
int main() {
user = 1;
submit(user);
user = 2;
submit(user);
return(0);
}
int submit(int user) {
if (user = 1) {
printf("1");
} else if (user = 2) {
printf("2");
}
return(0);
}
I thought that this would print out "12" but instead I'm getting "11". Isn't the variable "user" getting redefined before the function is called for the second time?
What's going wrong here?
Use ==, not = to check the values of user. You're overwriting the values (with =) instead of comparing them (with ==).
You are using = not == in your function body.
if (user = 1) { //This assigns user the value of 1 and then prints 1
printf("1");
The correct test condition should be :
if (user == 1) { //This checks the value of user and then prints if the condition is true
printf("1");
While compiling, if using gcc, adding the option -Wall is helpful in such cases as it gives you a warning about assignments in test conditions.
As answered by the experts, You are using = instead of using == in your function body that's why you are getting wrong output.
Here, I would like to clear your concept why it happens:
I hope you know the difference between assignment operator and equality operator. If not, I'm going to describe it briefly.
Assignment operator (=):
The assignment operator assigns a value to a variable. e.g.
user = 1;
This statement assigns the integer value 1 to the variable user.
This statement will always be executed which indicates that it is logically TRUE statement (assuming variable user is declared already).
As there is no comparison or something like that, so if we use Assignment operator(=) as a condition, it will always return TRUE or 1
Equality operator(==):
The equality operator is used to compare two values to know if they are equal or not.
user == 1;
This statement will compare the value of variable user with 1 and it will return TRUE if the value of user is 1 otherwise it will return FALSE.
RESULT: Assignment operator will always return TRUE but comparison operator may return TRUE or FALSE.
Now coming back to your code:
int submit(int user) {
//as you're using assignmnt operator this if condition will always true regardless of input
if (user = 1) {
printf("1");
//because if condition is true, it will never go into else if condition
} else if (user = 2) {
printf("2");
}
return(0);
}
So, actually, whenever you call this function, it will print 1 each time regardless of the value of user passed to this function. Since, you have called this function 2 times. Therefore, it will print 11.

Creating an instance of an object within an if in C#

Can I create an instance of an object within an if statement?
I've made 2 checkboxes in order to controll which constructor I use, but i get the error message " The name "mth" does not exist in the current context "
if (checkBox1.Checked && checkBox2.Checked)
{
Facto mth = new Facto(label3, wait_time, progressBar1);
}
else if(checkBox1.Checked==false && checkBox2.Checked)
{
Facto mth = new Facto(label3,wait_time);
}
else if (checkBox1.Checked && checkBox2.Checked == false)
{
checkBox1.Checked = false;
Facto mth = new Facto();
}
else
{
Facto mth = new Facto();
}
int result = mth.Factorial(number);
What am I doing wrong? I'm new to C# and I don't really have the hang of it yet.
Any help would be appreciated.
Thanks in advance.
This is a scoping problem. The variable mth only exists within the scope (brackets in your case) that it's defined in. As soon as you leave the scope the variabel is no longer available. Since you use the mth variable at the end of your code (and outside the scope) you get this error. In order to fix this you need to define the variable at a higher scope. Note that you don't have to assign it there.
This leads to something like (Note that I reformatted your brackets to make it easier to see the scope levels)
Facto mth; // Define it as the most outer scope level you are using it
if (checkBox1.Checked && checkBox2.Checked)
{
mth = new Facto(label3, wait_time, progressBar1);
}
else
if(checkBox1.Checked==false && checkBox2.Checked)
{
mth = new Facto(label3,wait_time);
}
else
if (checkBox1.Checked && checkBox2.Checked == false)
{
checkBox1.Checked = false;
mth = new Facto();
}
else
{
mth = new Facto();
}
int result = mth.Factorial(number);
EDIT: I would advice to always use {} brackets on every if and else even if they are not strictly required like in your case. As you can see in the layout it's not so easy to see where your first else ends and that the "int result line isn't part of it.
The problem here is not creating instance inside if block.
The mth reference is declared in the if/else blocks. This restricts the visibility/scope only to that block. so mth is not available when you try to refer it in line int result = mth.Factorial(number);
Just declare mth outside the if block and only instantiate inside if/else blocks.
For ex:
Facto mth;
if (checkBox1.Checked && checkBox2.Checked)
{
mth = new Facto(label3, wait_time, progressBar1);
}
...
Refer http://msdn.microsoft.com/en-us/library/aa691132(v=vs.71).aspx for some basic information.