I learned the most of my programming from Verilog. Since Python simply runs nicely on Linux i’m trying to give it a chance. After two days of coding it’s doing strange stuff behind the scenes.
For instance, reference passing
A = 0
def module(A):
A = 1
module(A)
print (A)
A = 0 Where I would expect it to be A = 1, since the write operation should come with the A = 1 assignment. And would like it to be as well.
A = 0
def module(A):
A = 1
return A
A = module(A)
print (A)
Does result in a register transfer, so all seems fine. It performs a flip flop on memory addresses “instead of a mov operation?” But it is within small bounds alternating locations, so… ~
Now the next issue I run into, is the reason why I decided to make this post.
Say you export a tuple and decide to use it inside your code, using comparators.
if Variable:
if Variable[0] != Variable[1]:
print (Variable[3])
Will not result in Variable[3] being passed, instead I suppose the garbage collector has come to pick it up bc variable[3] is no longer referenced by the if statement? Are there workarounds to make memory persistent?
“Basically saying my papers are filed an my condiments are still in the cupboard, the guy that throws them out every day is no longer here ?”
And if you care why are there these errors, they don’t seem to affect performance?
Isn’t this just how global and local variables work in Python? It’s often a code smell, but you can alter a global variable from a function by prefixing it with global and dropping the function arg of the same name: e.g.
A = 0
def module():
global A
A = 1
module()
print (A)
Hi, and welcome to Python. I have also programmed in Verilog, but not as my first programming language.
Verilog is a very specialised language, and you will find some ideas and best practices don’t migrate over to Python.
In your first example, you being new to Python I’d ask you to understand that:
Python functions are not modules.
It’s not reference passing.
It seems that you are dabbling - which is good, but you need to start with one, (or more ), of the many beginner tutorials where they will gradually introduce you to the language and ensure you know enough to appreciate the examples as they give them.
I hope you grow to love Python, as I do; all the best
I would not consider these errors.
The reason A does not change in your first example, is that the people who made python (and me too) believed that functions should not have side effects unexpectedly.
You can override this behaviour with global and nonlocal keywords.
If you’re going into the weeds like this, you should also be aware that primitives like int are treated differently from “complicated” objects like lists and tuples.
Can you post some self-contained code with the tuple variable where it does something you do not expect?
Blockquote
Isn’t this just how global and local variables work in Python? It’s often a code smell, but you can alter a global variable from a function by prefixing it with global and dropping the function arg of the same name: e.g.
Thanks for the reply I learned a new thing. The difference is though I can’t use it in a headless format. Since the reference variable is inside the module body.
A = 0
def module():
global A
A = 1
module() # is now the only module ever to be used, since the integral A is dedicated to the module
print (A)
Different languages work differently. Probably concepts like register and address won’t be that helpful in understanding how Python variables and values work. This was how I explained it: Python Names and Values | Ned Batchelder
All values in Python are full objects, there are no “primitives”. The main difference in behavior people see is between mutable objects like lists and dict, and immutable objects like ints, strings and tuples. Mutable objects can be changed inside functions and the effect is seen in the caller. Immutable objects don’t allow that behavior.
Thanks for the reply, this worked for me too in the second example. It helps producing the necessary code to do signal functions.
I suspect example 3 is due to garbage collection and the variable “Variable[2]” is not reference by the nested if statement. Which is a returned tuple in some code above, return A,B,C into Variable
if Variable:
if Variable[0] != Variable[1]:
print (Variable[3])
After some experimentation I can exaggerate the point by:
def NHold(Input):
if Input:
return Input
if Variable:
Ref = NHold(Variable[2])
if Variable[0] != Variable[1]:
print (Ref)
Is there a way to say to Python, I want that value to output the last value. To ensure the value is persistent?
I suspect example 3 is due to garbage collection and the variable “Variable[2]” is not reference by the nested if statement.
Variable[2] is not a variable. Variable is a name that refers to a data structure, like a tupleor a list. Variable[2] is an expression refers to the 3rd item of that data structure. The garbage collector does not delete parts of a data structure, so your guess cannot be true.
Generally speaking, there is no need to tell Python that certain values should be persistent since values will only be deleted if the cannot be referenced anymore (unless you specifically use things like weak references).
Unfortunately, your 3rd example is not self-contained, so it is not possible to say what is going on there. Specifically, how is Variabledefined? Does it have 4 items in it?
Blockquote
Unfortunately, your 3rd example is not self-contained, so it is not possible to say what is going on there. Specifically, how is Variabledefined? Does it have 4 items in it?
Yes, Before the module there is code, outputting a return statement passing a tuple of more than 3 items. Returning them into Variable. So the scenario is there are more updates happening to the tuple than are values reflected to the module NHold(Variable[2]).
def NHold(Input):
if Input:
return Input
But since Input is Variable[2] the return Input function does not sample the data. By using the if statement. Where I would suspect that would be fine.
genuinely post the self-contained code and tell us how you’re running it if you want answers.
The code I posted is self-contained, I ran it in jupyter notebook. The first snipped prints nothing, the second prints 5.
Your code cannot run without errors, so it’s not the code you ran.
Edit: oops I didn’t actually post the “fixed” code that prints nothing initially. It is
A = 0
B = 0
C = 0
def FakeModule (A,B,C):
"Do stuff"
return A,B,C
Variable = FakeModule(A,B,C)
def NHold(Input):
if Input:
return Input
if Variable:
if Variable[0] != Variable[1]:
print (Variable[2])
interesting. My mental model of python worked really well for predicting python behaviour, and apparently it’s wrong.
What does it mean that all values are full objects? Do the primitives only exist in the C implementation? Is the value of even typical “primitives” such as floats stored in the heap instead of in the stack? Does it mean that all numbers have some container folded around them telling Python how to interpret that data?
I did read through your slides, but didn’t watch the video. If I adapt that explanation as a mental model, I have less intuition about why strings behave the way they do, but at least tuple += does feel more intuitive.
There must be something else.
This disproves the point.
A = 1
B = 2
C = 2
RUN = True
Variable = 1
Init = 1
def FakeModule (A,B,C):
#"Do stuff"
return A,B,C
def NHold(Input):
if Input:
return Input
while RUN == True:
if Init == 1:
Variable = FakeModule(1, 2, 2)
if Variable:
if Variable[0] != Variable[1]:
print (Variable[2])
print("Booted")
else:
Variable = FakeModule(1,2, 5)
if Variable:
if Variable[0] != Variable[1]:
print (Variable[2])
RUN = False
Init = 0
But the question lingers, so I have parameters stored in a tuple. And the tuple updating is actually the register change triggering the first module to “sample the data” and it samples 0 as a result. Because the entire tuple is passed as an argument, Variable[2]
Does this mean I have to discretize the whole tuple set. back into discrete variables in order to get a data? That doesn’t seem like a good thing to do?
We don’t know why that seems wrong to you, or what you wanted this code to do. It’s very abstract, a toy example with no inherent meaning we can understand.
Blockquote
We don’t know why that seems wrong to you, or what you wanted this code to do. It’s very abstract, a toy example with no inherent meaning we can understand.
That code runs fine, it was actually a proof it can work, and I was wrong about memory.
For the other code, If the tuple passes the entire tuple as an argument. And this is why the Variable[2] is more frequently evaluated as Variable[2] is expected to flag. If it where to be a discrete Variable[2].
Pulling it apart, or have a list calling functions seems wrong here. Since it involves pollers “loops”.
Are there things you can use in the code to tell it to evaluate the discrete Variable[2]?