Scope issue in TCL list - scope

I am having a list globally declared.
global triaAXCord
set triAXCord {}
a procedure setCordinates appending values to this list.
proc setCordinates {AX} {
lappend triAXCord $AX
puts "$triAXCord"
}
that puts gives the value inserted.
But from other procedures when $triAXCord is printed as blank list. Since the list is globally declared why the values are not getting updated.

Outside of the proc definition, your triAXCord variable is already at the global scope. No need to explicity declare it as belonging to the global scope.
Within the proc, you are in the proc's scope and cannot access the global scope's variable unless you make it explicit within the proc. That's different than Python where functions can access global variables by default.
Either of these two methods works within the proc:
global triAXCord. This allows you to use triAXCord as a variable name in the proc.
Use the :: prefix before the variable name, like lappend ::triAXCord $AX.
You could also use upvar if you need more flexibility in variable names or scopes.

Related

How a function in python can access the values which are declared outside its block and never passed as arguments during its call?

I have written a Python code in which a function without parameters can access the variable declared outside its scope. I want to know how Python interpreter can access this variable without giving any error like other programming languages(e.g. JAVA).
# Code 1:
def A():
# count accessed inside function
print(count)
# count declared outside function A
count = 23
A()
Output of code 1:
23
There is a bonus question also. In Python, if we declare any variable inside the loop then how it can used outside the loop. Because, as we know that the scope of any variable will remain under the block in which it is defined.
# Code 2:
for i in range(1):
# num declared inside for loop block
num = 23
# num can be accessed outside for loop block.
print(num)
Output of code 2: 23
Variable scope is inside-out. When you call a variable from inside a local scope like a function, first Python checks if there's a variable with that name in the local scope. If it doesn't find one, it expands the scope it checks in to the next outer scope. In your case, this is the global scope, the top-most level of scope. Declaring something absent of any context like a function or method defaults to the global scope, so that's where count lives.
If you want to be clear about which count it is you're referencing, you can add nonlocal count or global count to your function definition, making it explicit that you're referencing the a different scope.
Bonus question -- You can't reference a locally-scoped variable outside of its scope, so it doesn't work in reverse, sorry. However in your example you're using a loop, which does not have its own scope in Python (but Julia does, so if you ever make that switch heads up).

Tcl: How do I call a proc from a different namespace, while also passing my proc a variable from its namespace?

I've got two scripts defined: the first script calls a proc in the second script. The second script defines a namespace fooSpace, defines a variable fooValue within fooSpace, and defines a proc myProc within fooSpace as well.
In my first script, I want to call my proc with an argument of myValue. I want my proc to test if myValue exists in fooSpace as fooValue. If so, the function will use fooValue to do some stuff.
If I understand correctly, upvar references the caller's namespace, which in my case is not the same as the function's namespace. But I don't think I can do variable $myvalue within my proc, either, right? How do I get my proc to use a variable defined in fooSpace?
My code below returns "Can't read $fooSpace"
Here's what my first script (located in alpha.tcl) looks like:
source bravo.tcl
namespace import fooSpace::myProc
# call the fuction
myProc apples
Here's what my second script (located in bravo.tcl) looks like:
namespace eval fooSpace {
namespace export myProc
set apples "Apples are 3 for a dollar"
proc myProc {myValue} {
upvar $fooSpace::$myValue fruit
if {[info exists fruit] == 1} {
puts "$fruit"
} else {
puts "we don't have any $fruit today"
}
}
}
You can do what you want using namespace upvar, which is designed for looking at variables in another namespace:
namespace upvar $fooSpace $myValue fruit
Alternatively, you can use upvar to do it, but then you need to stop the substitution of the fooSpace variable name from including the namespace separator afterwards (or you end up talking about the variable with the empty name within that namespace, which probably doesn't exist). This control of quoting is done with ${…} like this:
upvar ${fooSpace}::$myValue fruit
(You could use ${fooSpace}::${myValue} too, it'd all work the same after parsing.)
I recommend that you use namespace upvar though: it's quite a bit more efficient because it doesn't have to reparse variable names at all.
How do I get my proc to use a variable defined in fooSpace?
Your use of upvar is bogus, you miss the level argument, #0:
upvar "#0" [namespace current]::$myValue fruit
In addition, $fooSpace is not referencing the namespace fooSpace, but a proc-local variable of that name (hence the can't read "fooSpace": no such variable error); therefore:
[namespace current]::$myValue
which turns into
::fooSpace::$myValue
But I don't think I can do variable $myvalue within my proc, either
It depends, if you want to work with a link variable fruit, no, the variable command won't give you that. But you can certainly reference namespaced variables like this:
variable $myValue
Minor suggestion: myValue would be better coined myVar or myVarName because the argument denotes (namespaced) variable names (not values stored by these variables).

Call nested Python 3 nested function from parent function

For Python 3. I want to call a nested function from a top-level function. NOT access a variable in a nested function but call a nested function (what I'd normally refer to as a subroutine) from a "parent" function.
Answers on SO and elsewhere describe how to use the global and nonlocal keywords to enable variables in nested functions to be accessed by "parent" functions. But I haven't been able to translate that technique to Python 3 nested functions.
What I'm hoping to achieve, largely for outer-to-inner readability, is:
def topLevelFunction(listOfStrings):
# Top-level function's code here.
desiredValue = nestedFunction(dataToModify)
return(desiredResult)
# This nested function's source code is visibly contained within its parent.
def nestedFunction(oneListEntry):
# Modify data passed to function.
return(fixedData)
This structure of course produces UnboundLocalError: local variable 'nestedFunction' referenced before assignment.
I've circumvented that with:
def topLevelFunction(listofStrings):
def nestedFunction(oneListEntry):
# nestedFunction's code goes here.
return(fixedData)
# topLevelFunction's code goes here.
# Only in this "upside down" structure can top-level function call nestedFunction?
return(desiredResult)
Part of the problem seems to be that the nonlocal / global keywords that enable me to reference variables outside of nested functions' scope haven't enabled me to do the same thing for nested functions themselves(?) Or if they do, the syntax is unique? If that's the case, thanks for a pointer to that specific syntax.
I've also made nestedFunction a stand-alone function at the same level / scope as topLevelFunction. But at least from a readability perspective both circumventions (I won't call them fixes) seem to require me to write "upside down" code where things that are used later in the program flow must be "higher" in the source code?
Perhaps I'm too accustomed to compiled languages that don't require this? Or must I instead create a Python 3 class?

What is the different between Empty String and none Created Variable

What is the different between Empty String and none Created Variable in Batch File?
and if they have any different, can you show me an example of using empty string vs none created string?
#echo off
title Empty String Vs None Created Variable
set String=
set variable=exist
if [%String%] == [] echo its be a Empty String
if [%variable%] == [] echo its be a Empty String
if [%none_exist_var%] == [] echo its be a Empty String
Thanks a Lot!
Variables in batch files can be
Defined: there is a value stored and a associated name used to retrieve the value, that is, the variable name.
Undefined: there is no value and in consecuence there is not any need for an associated name, so it does not exist.
This two simple rules handle how the environment block (where variables/value are stored) is updated. If there is a value, the environment block has an entry for the value and the name to retrieve it. Without a value, the environment block does not create the entry or, when setting the variable to nothing, the entry is removed.
So, if
a never defined variable has not any entry in the environment block
a variable with not value has not any entry in the environment block
there is not any difference between the two cases.
note: While the traditional way to check if a variable stores a value / a variable exists is (as dbenham has commented, this syntax is not recommeded as quotes inside the variable value lead to syntax problems)
if "%varName%"=="" ....
if command extensions are enabled (and the default configuration is to have them enabled) you can also use a safer alternative
if not defined varName ....
if defined varName ....
note that in this syntax, as we are not trying to read the value in the variable, varName is used, not %varName%
There is no difference. Read Delete a variable:
Type SET with just the variable name and an equals sign:
SET _department=
Better still, to be sure there is no trailing space after the = place
the expression in parentheses or quotes:
(SET _department=)
or
SET "_department="

How to modify immutable objects passed as **arguments in functions with Python3 the elegant way?

I am not sure what the problem is here, so I don't really know how I should call the subject for that question. Please offer a better subject if you know.
The code below is a extrem simplified example of the original one. But it reproduce the problem very nice. After the call of test() foo should be sieben.
I think I didn't know some special things about scopes of variables in Python. This might be a very good problem to learn more about that. But I don't know on which Python topic I should focus here to find a solution for my own.
#!/usr/bin/env python3
def test(handlerFunction, **handlerArgs):
handlerFunction(**handlerArgs)
def myhandler(dat):
print('dat={}'.format(dat))
dat = 'sieben'
print('dat={}'.format(dat))
foo = 'foo'
test(myhandler, dat=foo)
print('foo={}'.format(foo))
Of course I could make foo a global variable. But that is not the goal. The goal is to carry this variable inside and through sub-functions of different levels and bring the result back. In the original code I use some more complexe data structures with **handlerArgs.
A solution could be to use a list() as an mutable object holding the immutable one. But is this really elegant or pythonic?
#!/usr/bin/env python3
def test(handlerFunction, **handlerArgs):
handlerFunction(**handlerArgs)
def myhandler(dat):
print('dat={}'.format(dat))
# MODIFIED LINE
dat[0] = 'sieben'
print('dat={}'.format(dat))
# MODIFIED LINE
foo = ['foo']
test(myhandler, dat=foo)
print('foo={}'.format(foo))
The ** syntax has nothing to do with this. dat is local to myhandler, and assigning it doesn't change the global variable with the same name. If you want to change the module variable from inside the function, declare the variable as global at the beginning of the function body:
def myhandler(): # you don't need to pass dat as argument
global dat
print('dat={}'.format(dat))
dat = 'sieben'
print('dat={}'.format(dat))
Here's a relevant portion from the docs:
If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations.
If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module builtins. The global namespace is searched first. If the name is not found there, the builtins namespace is searched. The global statement must precede all uses of the name.
After your edit the question reads as: "how do I mutate an immutable object?"
Well, I think you've guessed it: you don't. Using a mutable object in this manner seems reasonable to me.

Resources