Using a Variable Outside of the While Loop (Scope)

Using a variable outside of the while loop (scope)

You could try to define the variable before the loop, e.g.

$report = "";
while ($row = mysql_fetch_array($result)) {
$report .= "a"."b".$row["prevDOCid"]+1;
}
echo $report;

I hope this helps you!

Edit Use .= not +=

JAVA: Is it possible to use a variable outside a loop that has been initialised inside a loop?

The scope of a variable, limits the use of that variable to the scope it is defined in. If you want it used in a broader scope, declare it outside the loop.

However, since the name is initialized inside the loop, I cannot use it outside.

You have defined the variable outside the loop, so the only thing you need to do is to initialize it, as the error message you should get suggests.

String name = "not set";

while(loop) {
name = ...

if (condition)
// do something to break the loop.
}
// can use name here.

The basic problem is that the compiler cannot work out that the variable will be set in all possible code paths. There is two ways you can fix this without using a dummy value. You can use a do/while loop.

String name;
boolean flag = true;
do {
name = ...
// some code
if (test(name))
flag = false;
// some code
} while(flag);

or drop the condition, as you don't need a counter.

String name;
for (;;) {
name = ...
// some code
if (test(name)) {
break;
// some code if test is false.
}

Get variable from the outside of while loop

The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well.

For example:

let us assume in a file, example.php, you have the following:

<?php

$foo = "Hello World"; // global scope

function hello() {
echo $foo; // reference to local scope
}

hello();
?>

This script will not produce any output because the echo statement in the function hello() refers to a local version of the $foo variable, and it has not been assigned a value within this scope.

Now, if you want to gain access to the already defined or declared global scope variable, $foo, from within the function hello(), then you would need to declare the variable $foo using the global keyword from within the function, such as:

<?php

$foo = "Hello World"; // global scope

function hello() {
global $foo;
echo $foo; // reference to local scope
}

hello();
?>

Now invoking function hello() will produce:

Hello World

While-blocks don't have limited scope within its block, and therefore, same principle do not apply, but having the global keyword define variables inside a while-block at a time when the variables do not exist outside the while block do affect the variables.

So in your while block that you currently have:

while ($row = mysqli_fetch_array($result)) {
global $Lname, $Fname, $PhoneNumber, $Gender, $DOB, $Email;
$Lname = $row['Lname'];
$Fname = $row['Fname'];
$PhoneNumber = $row['PhoneNumber'];
$Gender = $row['Gender'];
$DOB = $row['DOB'];
$Email = $row['Email'];
echo 'nananananana';
}

Either define the variables $Lname, $Fname, $PhoneNumber, $Gender, $DOB, $Email, in global scope outside the while-block, or place the global variables outside of the while-block scope so you can have access to them, such as:

global $Lname, $Fname, $PhoneNumber, $Gender, $DOB, $Email;
while ($row = mysqli_fetch_array($result)) {
$Lname = $row['Lname'];
$Fname = $row['Fname'];
$PhoneNumber = $row['PhoneNumber'];
$Gender = $row['Gender'];
$DOB = $row['DOB'];
$Email = $row['Email'];
echo 'nananananana';
}

or, I would do something like this:

$Lname = '', $Fname = '', $PhoneNumber = '', $Gender = '', $DOB = '', $Email = '';
while ($row = mysqli_fetch_array($result)) {
global $Lname, $Fname, $PhoneNumber, $Gender, $DOB, $Email;
$Lname = $row['Lname'];
$Fname = $row['Fname'];
$PhoneNumber = $row['PhoneNumber'];
$Gender = $row['Gender'];
$DOB = $row['DOB'];
$Email = $row['Email'];
echo 'nananananana';
}

or even if you will not be calling other files within a file, the use of the global keyword in this case is really unnecessary, you can accomplish this in the following way:

$Lname = '', $Fname = '', $PhoneNumber = '', $Gender = '', $DOB = '', $Email = '';
while ($row = mysqli_fetch_array($result)) {
$Lname = $row['Lname'];
$Fname = $row['Fname'];
$PhoneNumber = $row['PhoneNumber'];
$Gender = $row['Gender'];
$DOB = $row['DOB'];
$Email = $row['Email'];
echo 'nananananana';
}

To think about it from an efficiency point of view, why would you want to invoke the global keyword at every while-loop iterative cycle? I would just define/declare the variables outside the while-loop, and assignment of values will be added in the while loop as it goes through the iterative process.

Variables scope can get a little tricky, hope this helps out.

Defining variables outside of the 'while' loop

In your first code block, each time you run total = 0 + end, you reset total

total = 0 + 10
total = 0 + 9
total = 0 + 8
...
total = 0 + 1

At the end of this, the last line run was total = 0 + 1 which equals 1

In the second loop, you are utilizing the previous value of total:

total = 0
total = 0 + 10
total = 10 + 9
total = 19 + 8
...
total = 54 + 1

With each pass through the loop, total is incremented and utilized. In the first one, you are over writing the total in each loop.

Variable defined outside a while loop not defined inside?

First let me give the solution:

There are three possible approaches

Approach 1. Prepend global before iter += 1 and change it to global iter += 1 and all will work (note however the comment below about δ - because it will not work correctly unless you also prepend global before δ = abs(x[iter] - x[iter + 1]), i.e. the code will run but will produce wrong results - approaches 2 and 3 do not have this problem).

Approach 2. Wrap your code inside a function like this:

f(x) = x^2.5 - 3x^1.5 - 10
fprime(x) = 2.5x^1.5 - 4.5x^0.5

function sol(f, fprime)
x = zeros(1000)
x[1] = 10
δ = 1 # a relatively large number compared to what we want the error to be
iter = 1
while δ > 1e-6
x[iter + 1] = x[iter] - f(x[iter])/fprime(x[iter])
iter += 1
δ = abs(x[iter] - x[iter + 1])

if iter == 100
break
end
end
println("The solution is ")
show(x[iter])
end

sol(f, fprime) # now we call it

Solution 3. Wrap your code in a let block by changing line function sol(f, fprime) in solution 2 to simply say let (you do not need to call sol then).

Now the reason why you have to do it.

In Julia 1.0 while introduces a new scope. The scoping rules in Julia 1.0 are that each variable that is assigned to inside a while loop is considered a local variable (this has changed, because Julia 0.6 distinguished hard and soft local scope, in Julia 1.0 this distinction is gone - all local scopes are the same).

In your code you assign values to two variables: iter and δ inside the loop. This means that they are treated by Julia as local so you are not allowed to access their value before they have a value assigned inside the loop.

You want to read iter in line x[iter + 1] = x[iter] - f(x[iter])/fprime(x[iter]) but assign a value to it only in the following line.

As for δ the thing is more tricky. You assign a value to it, but it is used in a loop condition while δ > 1e-6. However, this condition operates on variables defined in outer scope (global in the original case). So all will work, but the condition while δ > 1e-6 will always see that δ is equal to 1 as it looks at the value of the variable outside of the loop. So this condition will never trigger (and you will always run 100 iterations). In summary the code that does what you want is (although if you did not fix δ assignment you would not get a warning):

f(x) = x^2.5 - 3x^1.5 - 10
fprime(x) = 2.5x^1.5 - 4.5x^0.5
x = zeros(1000)
x[1] = 10
δ = 1 # a relatively large number compared to what we want the error to be
iter = 1
while δ > 1e-6
x[iter + 1] = x[iter] - f(x[iter])/fprime(x[iter])
global iter += 1
global δ = abs(x[iter] - x[iter + 1])

if iter == 100
break
end
end
println("The solution is ")
show(x[iter])

Finally notice that the line x[iter + 1] = x[iter] - f(x[iter])/fprime(x[iter]) works fine even if there is an assignment in it, because you do not rebind variable x in it, but only change one element of an array (so x points to the same address in memory and Julia treats it as a global variable all the time).

Also you might want to read this https://docs.julialang.org/en/latest/manual/variables-and-scoping/ in the Julia manual or the answer to this question Julia Variable scope is similar

declare variable inside or outside a loop, does it make big difference?

Yes. scope of variable i is different in both cases.

In first case, A variable i declared in a block or function. So, you can access it in the block or function.

In the second case, A variable I declared in a while loop. So, you can access it in while loop only.

Does it make big difference in terms of performance?

No, it will not matter performance-wise where you declare it.

For example 1:

int main()
{
int i, bigNumber;

while(bigNumber--) {
i = 0;
}
}

Assembly:

main:
push rbp
mov rbp, rsp
.L3:
mov eax, DWORD PTR [rbp-4]
lea edx, [rax-1]
mov DWORD PTR [rbp-4], edx
test eax, eax
setne al
test al, al
je .L2
mov DWORD PTR [rbp-8], 0
jmp .L3
.L2:
mov eax, 0
pop rbp
ret

Example 2:

int main()
{
int bigNumber;

while(bigNumber--) {
int i;
i = 0;
}
}

Assembly:

main:
push rbp
mov rbp, rsp
.L3:
mov eax, DWORD PTR [rbp-4]
lea edx, [rax-1]
mov DWORD PTR [rbp-4], edx
test eax, eax
setne al
test al, al
je .L2
mov DWORD PTR [rbp-8], 0
jmp .L3
.L2:
mov eax, 0
pop rbp
ret

Both generate the same assembly code.

While without global

As @Michael Paul and @crstnbr already replied in the comments, the scoping rules have been changed (Scope of variables in Julia). The for and while loop introduce a new scope and have no access to the outside (global) variables. You can get scope access using the global keyword but the recommended workflow is wrapping your code in functions.

One of the benefits of the new design is that the user is forced to avoid such global constructs which directly affect the performance of functions - which cannot be type stable when they access global variables.

One downside is the confusion when experimenting in the REPL and seeing such errors.

In my opinion the new behaviour is the cleaner one with respect to predictability. It was however a very tough and long-running discussion within the whole Julia community ;)

There is currently a discussion if the REPL will be changed to behave like the old one by making use of let-wraps: https://github.com/JuliaLang/julia/issues/28789
This is something which is not practical to be done manually (much more complicated then using the global keyword), see the example by Stefan Karpinski: https://github.com/JuliaLang/julia/issues/28789#issuecomment-414666648

Anyways, for the sake of completeness (although I would not recommend doing this) here is a version using global:

myfriends = ["Ted", "Robyn", "Barney", "Lily", "Marshall"]
i = 1;
N = length(myfriends)

while i <= N # you cannot even call a function here
# with a global, like length(myfriends)
global i, myfriends
friend = myfriends[i]
println("Hi $friend, it's great to see you!")
i += 1
end

Note however that this is also completely valid:

myfriends = ["Ted", "Robyn", "Barney", "Lily", "Marshall"]

greet(friend) = println("Hi $friend, it's great to see you!")

for friend in myfriends
greet(friend)
end


Related Topics



Leave a reply



Submit