Procedure for getting an output of a def function code in python version 3 - program-entry-point

I am attempting to do practice problems of how a def function code works. Although I believe my procedure so far is not correct.
Here is the code:
def main():
max=0
getMax(1,2,max)
print(max)
def getMax(v1,v2,max):
if (v1>v2):
max=v1
else:
max=v2
main()
And here is my reasoning through it.
Execution of the main function begins where max=0. The next line has initialized the (local variable?) getMax. v1 is replaced with 1, v2 is placed with 2, and max is replaced with 0. Going back to the main function, python prints max which is 0. Which is why the output is 0. The main function is now finished, and it returns the control to its caller(which is main()).
Is my procedure correct?
What is messing me up is I usually see the getMax(or the local variable I think it's called) first before I see the def main() function. does order matter here? Because the if loop was completely ignored in my opinion in the def main function.

the argument max in the function getMax() gets a copy of the value of the variable max in main(). Changes there are not propagated back to the caller.

Related

Why is numpy save not immediate, and can it be forced to save immediately?

I thought this question would have been asked already, but I can't find it, so here goes: I've noticed that numpy.save commands only trigger, i.e. the file to-be-created is actually created, after the entire code has finished running. This is bad when the code takes days or weeks to run, and I want to pin down exactly which function, and what arguments into the function, are causing the bottleneck.
There is a similar issue with the print() command; it doesn't write to the output file immediately but rather waits until the entire code is finished before writing. I can force it to write immediately with this code:
def printnow(*messages):
w=open("output.log","a")
for message in messages:
w.write(str(message))
w.write(" ")
w.write("\n")
w.close()
I was wondering whether it's possible to do an analogous thing, i.e. force an immediate save, for numpy arrays. No need for appending; overwriting with the current value of the numpy array is fine.
If it makes a difference, I'm not running the code on my personal computer but a group server, which I issue commands to and check on using Putty and WinSCP.
Thanks
Edit: I tried another package, shelve, and it encounters the same problem. I create a global variable called function_calls and initialize it to 0. Then, at the start of the function that I suspect is causing the bottleneck, I put in the following code:
global function_calls
file='function_inputs'+str(function_calls)
function_shelf=shelve.open(file,'n')
for key in dir():
function_shelf[key]=locals()[key]
function_calls+=1
This code is intended to create a new file that saves the function inputs, each time the function is called. Unfortunately, 9 hours into starting the run, no files have been created. So I suspect Python is just waiting until the whole run is finished before creating the files I asked it to.

numpy - reason to use 'with' for np.nditer

Please explain if tbere is a reason of using with for the nditer as shown in the NumPy document numpy.nditer.
It is to understand if there is a necessity that we have to use 'with' when using nditer. In my understanding, 'with' is to make sure a resource (e.g. open file descriptor) gets released. I am not sure what resource is to be released in the code.
def iter_add_py(x, y, out=None):
addop = np.add
it = np.nditer([x, y, out], [],
[['readonly'], ['readonly'], ['writeonly','allocate']])
with it: # <-----
for (a, b, c) in it:
addop(a, b, out=c)
return it.operands[2]
Update
As pointed out, the Iterating Over Arrays - Modifying Array Values says:
because the nditer must copy this buffer data back to the original
array once iteration is finished, you must signal when the iteration
is ended, by one of two methods. You may either:
use the nditer as a context manager using the with statement, and the
temporary data will be written back when the context is exited.
call the iterator’s close method once finished iterating, which will
trigger the write-back.

How to find out what arguments DM functions should take?

Through trial and error, I have found that the GetPixel function takes two arguments, one for X and one for Y, even if used on a 1D image. On a 1D image, the second index must be set to zero.
image list := [3]: {1,2,3}
list.GetPixel(0,0) // Gets 1
GetPixel(list, 0, 0) // Equivalent
How am I supposed to know this? I can't see anything clearly specifying this in the documentation.
This is best done by using the script function with an incorrect parameter list, running the script, and observing the error output:

writing a vector using "readTrajectory" function in Dymola

I write a vector in Dymola mos script in a simple manner like this:
x_axis = cell.spatialSummary.x_cell;
output: x_axis={1,2,3,4,5} // row vector
I want to do the same thing in a function.'x_cell' has 5 values which I want to store in a row vector. I use DymolaCommands.Trajectories.readTrajectory function to read x_cell values one by one in for loop (I use for loop because, readTrajectory throws an error when I try to read entire x_cell)
Real x_axis[:],axis_value[:,:];
Integer len=5;
for i in 1:len loop
axis_value:=readTrajectory(result,{"cell.spatialSummary.x_cell["+String(i)+"]"},1); //This intermediate variable returns [1,1] matrix
x_axis[i]:=scalar(axis_value);
end for;
I get an error:
Assignment failed x_axis[i] = scalar(axis_value);
what's wrong here? All I want to do is read all values of x_cell and write it into a vector. How can I do this in dymola function?
Thank you!
Solution: Initialize the vector with a certain value. In this case,
x_axis :=fill(0, len);
This solved the above problem for me.
Pre filling as in the other solution works, and is generally the best solution. However, in some cases you might have to append to the vector as follows:
x_axis=fill(0.0, 0);
for i in 1:len loop
axis_value:=readTrajectory(result,{"cell.spatialSummary.x_cell["+String(i)+"]"},1); //This intermediate variable returns [1,1] matrix
x_axis:=cat(1, x_axis, {scalar(axis_value)});
end for;
(This takes x_axis and concatenates a new element at the end. It is generally slower.)

Parameter 3 is not constant in call of system task $fwrite

I am using Xilinx ISE 10.1 to run some verilog code. In the code I want to write the register values of 3 registers in a file, cipher.txt. The following is the code snippet:
if (clk_count==528) begin
f1 = $fopen("cipher.txt", "w");
$fwrite(f1, "clk: %d", clk_count[11:0]);
$fwrite(f1, "plain: %h", plain[31:0]);
$fwrite(f1, "cipher: %h", cipher[31:0]);
$fclose(f1);
end
At the end of execution, the contents of cipher.txt is found as:
clk: %dplain: %hcipher: %h
There is no other error encountered, but a warning comes up corresponding to the 3 fwrite's:
Parameter 3 is not constant in call of system task $fwrite.
Parameter 3 is not constant in call of system task $fwrite.
Parameter 3 is not constant in call of system task $fwrite.
The values of the registers clk_count and cipher change on every clock cycle (value of register plain remains constant throughout), and the values are written to cipher.txt when clk_count equals 528 (indicated by the if statement)
Can anybody provide some insight and/or help me get past this hurdle?
Thanks.
It appears that ISE expects the arguments to $fwrite to be constant. The warnings are referring to clk_count[11:0], plain[31:0], and cipher[31:0], which are not constant. By definition they are changing each cycle so they are not known at compile time. This also explains why they are not printing and you are seeing %d and %h in the output.
There is nothing to my knowledge in the Verilog spec that requires the arguments to $fwrite be constant. The same code works as expected with Cadence Incisive. My guess is that it's a limitation of ISE, so you may want to check with Xilinx.
Possible work-arounds:
1) Use $swrite to create a string with the proper formatting. Then write the string to the file.
2) Try using an intermediate variable in the calls to $fwrite. Maybe the part-selects are throwing it off. e.g.
integer foo;
foo = clk_count[11:0];
$fwrite(... , foo , ...);
Either of those might work, or not.
Out of curiosity, if you remove the part-selects, and try to print clk_count without the [11:0] , do you get the same warnings?