Passing values from function to function in JES/Jython - jython

I am learning Jython using a program called JES, and I am having trouble understanding how to return values from a function that can be used in another function.
For example:
def driver():
picture = makePicture(pickAFile())
input(picture)
changeRed(picture, reduceRedAmount)
def input(picture):
redReduceAmount = requestInteger("How much should I reduce red by?")
return redReduceAmount
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
I want to be able to just run the driver function in the command area, and have that function include the other functions. I understand that results in functions are local and don't pass through, but I though that if you use 'return' then it stores that value for later use. Am I on the wrong track here? Surely there is a way to pass information between functions?

Try this:
Any "-" just disregard them that is not part of the code, they are just there for spacing to help so that you don't get any syntax errors.
def driver():
picture = makePicture(pickAFile())
input(picture)
changeRed(picture, reduceRedAmount)
repaint(picture)`
or
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
repaint(picture)
or
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
show(picture)
or
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
return(picture)`
One of those repaint, return, show should work to display the new image.
To display other values in command area just use "print something here" for example print 1+1 or print value.

the way I do it is declare it as a global variable the line after the def functionName() and at the LAST line of the functionName() code before you reduce the indent, type return variableNameYouWant.
check this:
def functionName()
global variableNameYouWant
..
..
return variableNameYouWant
What we are doing by following this is declaring the function you want to be a global variable (which must be done before it is delcared with a value, so best to do at the start of the def.) and then before you close the def by decreasing indentation, return the variable outside of the def.
I know it's an old question but I'm striving for upvotes as a newbie. :)
Edit: Thanks for the downvote, anon.

Related

Can anyone tell me what's wrong with my code (I am a newbie in programming, pls do cooperate )

I am trying to write a code which calculates the HCF of two numbers but I am either getting a error or an empty list as my answer
I was expecting the HCF, My idea was to get the factors of the 2 given numbers and then find the common amongst them then take the max out of that
For future reference, do not attach screenshots. Instead, copy your code and put it into a code block because stack overflow supports code blocks. To start a code block, write three tildes like ``` and to end it write three more tildes to close. If you add a language name like python, or javascript after the first three tildes, syntax highlighting will be enabled. I would also create a more descriptive title that more accurately describes the problem at hand. It would look like so:
Title: How to print from 1-99 in python?
for i in range(1,100):
print(i)
To answer your question, it seems that your HCF list is empty, and the python max function expects the argument to the function to not to be empty (the 'arg' is the HCF list). From inspection of your code, this is because the two if conditions that need to be satisfied before anything is added to HCF is never satisfied.
So it could be that hcf2[x] is not in hcf and hcf[x] is not in hcf[x] 2.
What I would do is extract the logic for the finding of the factors of each number to a function, then use built in python functions to find the common elements between the lists. Like so:
num1 = int(input("Num 1:")) # inputs
num2 = int(input("Num 2:")) # inputs
numberOneFactors = []
numberTwoFactors = []
commonFactors = []
# defining a function that finds the factors and returns it as a list
def findFactors(number):
temp = []
for i in range(1, number+1):
if number%i==0:
temp.append(i)
return temp
numberOneFactors = findFactors(num1) # populating factors 1 list
numberTwoFactors = findFactors(num2) # populating factors 2 list
# to find common factors we can use the inbuilt python set functions.
commonFactors = list(set(numberOneFactors).intersection(numberTwoFactors))
# the intersection method finds the common elements in a set.

NoneType in MU5 on BBC Microbit

I have some code for a simple rev counter on the Microbit. When returning the variable rev_per_second, sometimes it is a NoneType (for reasons unknown). I try to trap this within the function, but it doesn't seem to work. Where am I going wrong please.
# part of the function revs()
if end_time < running_time():
try:
rev_per_second = rev_per_second
except TypeError:
rev_per_second = 1
return rev_per_second # make this value available to the main program
# main part of the program
while True:
rev_per_min = revs() # sometimes this is "None" Why??
display.scroll(str(rev_per_min))
The explanation is almost certainly that there is a path through the function that does not end in a return statement, so Python by default returns None.
Check that all paths from your revs() function end at a return statement, otherwise Python will return None if there is no return statement.

How can I use `apply` with a function that takes multiple inputs

I have a function that has multiple inputs, and would like to use SFrame.apply to create a new column. I can't find a way to pass two arguments into SFrame.apply.
Ideally, it would take the entry in the column as the first argument, and I would pass in a second argument. Intuitively something like...
def f(arg_1,arg_2):
return arg_1 + arg_2
sf['new_col'] = sf.apply(f,arg_2)
suppose the first argument of function f is one of the column.
Say argcolumn1 in sf, then
sf['new_col'] = sf['argcolumn1'].apply(lambda x:f(x,arg_2))
should work
Try this.
sf['new_col'] = sf.apply(lambda x : f(arg_1, arg_2))
The way i understand your question (and because none of the previous answers are marked as accepted), it seems to me that you are trying to apply a transformation using two different columns of a single SFrame, so:
As specified in the online documentation, the function you pass to the SFrame.apply method will be called for every row in the SFrame.
So you should rewrite your function to receive a single argument representing the current row, as follow:
def f(row):
return row['column_1'] + row['column_2']
sf['new_col'] = sf.apply(f)

Velocity Template engine - key-value-map

I have some problems wo use a key-value-map into Velocity.
Someone has an example of this functionality?
$myMap ={}
$myMap.put("mykey1", "myvalue")
$myMap.delete("mykey1")
$myMap.getValue("mykey1")
As Nathan said, you should use:
#set ($myMap = {})
to create a new map and assign it to a variable.
Now, why is the put call printed.
Anything that is not inside a directive, like #set(not printed) or #if(not printed) or #foreach(again not printed), is printed, including free text, variables, and method calls.
Velocity can't distinguish between the different semantics of $myMap.get('mykey') and $myMap.put('key', 'value') (reader vs. writer), so the result of the put call is printed, just like any other method.
Whenever something can't be properly evaluated, because a variable is not defined or somewhere along the line a method returns null, the code that failed to be evaluated is dumped literally into the output.
As the documentation of the put method states, the function returns the previous value stored for that key, or null if no value was set at all.
Summing it all up, it's normal to get that line printed.
To try this theory out, you can do this:
#set ($myMap = {})
$myMap.put('key', 'first value')
$myMap.put('key', 'second value')
$myMap.get('key')
This will be printed:
$myMap.put('key', 'first value')
first value
second value
There are two things you can do so that the line isn't printed:
Store the outcome of the function in a temporary variable: #set ($discard = $myMap.put('key', 'value')
Use the silent method call: $!myMap.put('key', 'value')
I'd recommend the first one, since the second one will still print something when you're replacing an existing value.
Did you try doing:
#set( $myMap = {} )
Also, make sure you are using a modern version of Velocity. Ancient ones did not have map syntax in VTL.
Just add ! to not print put:
$!myMap.put('key', 'second value')

How to comment on MATLAB variables

When I´m using MATLAB, sometimes I feel the need to make comments on some variables. I would like to save these comments inside these variables. So when I have to work with many variables in the workspace, and I forget the context of some of these variables I could read the comments I put in every one of them. So I would like to comment variables and keep the comments inside of them.
While I'm of the opinion that the best (and easiest) approach would be to make your variables self-documenting by giving them descriptive names, there is actually a way for you to do what you want using the object-oriented aspects of MATLAB. Specifically, you can create a new class which subclasses a built-in class so that it has an additional property describing the variable.
In fact, there is an example in the documentation that does exactly what you want. It creates a new class ExtendDouble that behaves just like a double except that it has a DataString property attached to it which describes the data in the variable. Using this subclass, you can do things like the following:
N = ExtendDouble(10,'The number of data points')
N =
The number of data points
10
and N could be used in expressions just as any double value would. Using this example subclass as a template, you could create "commented" versions of other built-in numeric classes, with the exception of those you are not allowed to subclass (char, cell, struct, and function_handle).
Of course, it should be noted that instead of using the ExtendDouble class like I did in the above example, I could instead define my variable like so:
nDataPoints = 10;
which makes the variable self-documenting, albeit with a little more typing needed. ;)
How about declaring another variable for your comments?
example:
\>> num = 5;
\>> numc = 'This is a number that contains 5';
\>> whos
...
This is my first post in StackOverflow. Thanks.
A convenient way to solve this is to have a function that does the storing and displaying of comments for you, i.e. something like the function below that will pop open a dialog box if you call it with comments('myVar') to allow you to enter new (or read/update previous) comments to variable (or function, or co-worker) labeled myVar.
Note that the comments will not be available in your next Matlab session. To make this happen, you have to add save/load functionality to comments (i.e. every time you change anything, you write to a file, and any time you start the function and database is empty, you load the file if possible).
function comments(name)
%COMMENTS stores comments for a matlab session
%
% comments(name) adds or updates a comment stored with the label "name"
%
% comments prints all the current comments
%# database is a n-by-2 cell array with {label, comment}
persistent database
%# check input and decide what to do
if nargin < 1 || isempty(name)
printDatabase;
else
updateDatabase;
end
function printDatabase
%# prints the database
if isempty(database)
fprintf('no comments stored yet\n')
else
for i=1:size(database,1)
fprintf('%20s : %s\n',database{i,1},database{i,2});
end
end
end
function updateDatabase
%# updates the database
%# check whether there is already a comment
if size(database,1) > 0 && any(strcmp(name,database(:,1)))
idx = strcmp(name,database(:,1));
comment = database(idx,2);
else
idx = size(database,1)+1;
comment = {''};
end
%# ask for new/updated comment
comment = inputdlg(sprintf('please enter comment for %s',name),'add comment',...
5,comment);
if ~isempty(comment)
database{idx,1} = name;
database(idx,2) = comment;
end
end
end
Always always always keep the Matlab editor open with a script documenting what you do. That is, variable assignments and calculations.
Only exceptions are very short sessions where you want to experiment. Once you have something -- add it to the file (It's also easier to cut and paste when you can see your entire history).
This way you can always start over. Just clear all and rerun the script. You never have random temporaries floating around in your workspace.
Eventually, when you are finished, you will also have something that is close to 'deliverable'.
Have you thought of using structures (or cells, although structures would require extra memory use)?
'>> dataset1.numerical=5;
'>> dataset1.comment='This is the dataset that contains 5';
dataset1 =
numerical: 5
comment: 'This is the dataset that contains 5'