I am making a little game where when events happen, rectangles get spawned at a random x and y point and I am having some trouble implementing functions into this. Here is some basic code:
xran = random.randint(5, 485)
yran = random.randint(5, 485)
xran1 = random.randint(5, 450)
yran1 = random.randint(5, 400)
def allRand():
#This REGENERATES those randoms making it 'spawn' in a new location.
xran = random.randint(0, 485)
yran = random.randint(0, 485)
xran1 = random.randint(5, 450)
yran1 = random.randint(5, 400)
char = pygame.draw.rect(screen, black, (x,y,15,15), 0)
food = pygame.draw.rect(screen, green, (xran,yran,10,10), 0)
badGuy = pygame.draw.rect(screen, red, (xran1,yran1,50,100), 0)
if char.colliderect(food):
score += 1
print "Your score is:",score
allRand()
Does calling a function that regenerates random numbers work for any of you? I know it regenerates them because I have had it print back the variables, for some reason my rects don't do there though.
Note: This is just snippet of my code it was just meant to give an idea of what I am trying to do.
Thanks!
You need to declare xran, etc. with global inside the allRand() function. Otherwise, it's just creating new variables inside function scope, assigning them random values, then throwing them away when the function returns.
Your allRand() method doesn't have any code. You must indent the lines you want in that function.
It's kinda working because you still call those statements below your def. But it's not because you're calling the function.
To add to Lee Daniel Crocker's answer, when you create variables in a function they exist only in that function. If you want them to exist outside you can either make them global variables as he suggested, you are can return them and catch them:
>>> def square(number):
squared = number*number
return squared
>>> square(3)
9
>>> ninesquared = square(3)
>>> ninesquared
9
>>>
Read more
It looks like you need to master your basics. I suggest doing that first before trying things in pygame.
EDIT:
If you define variables outside of the function, they will not effect any variables you define in the function either.
>>> x = 5
>>> def rais():
x = 10
>>> x
5
>>> rais()
>>> x
5
>>>
Notice how rais did nothing?
If we change the line in rais to be x = x + 1 then python will give us back an error that x is not defined.
If you want you're variables to get into the function you need to pass them in as parameters, but once again, they won't effect anything outside of the function unless you return and capture them. And once again, you can declare them as global variables and that will also work.
Related
I would like to log plot a function in Julia.
using Plots
x = 1:100
plot(x.^2, xaxis=:log)
I used the same logic as the working code from above but I got following error:
My guess is that I need to "transform" the function into a unit range (if that makes any sense). However, I am not sure how to do that.
using Plots
function test(a)
alpha = 1
for i in 1:a
alpha += 1
end
return alpha
end
a = 1:100
plot(test(a), xaxis=:log)
MethodError: no method matching (::Colon)(::Int64, ::UnitRange{Int64})
You need to broadcast test like this:
plot(test.(a), xaxis=:log)
(note a . after test)
Alternatively plot is smart enough to know how to plot a function just like this:
plot(test, 1, 100, xaxis=:log)
See here for more examples.
I'm a relative newcomer to Julia, and so far I am a fan of it. But coming from years of R programming, some scoping rules leave me perplexed.
Let's take this function. This behaves exactly as I would expect.
function foo1(x)
y = x
t = 1
while t < 1000
t += 1
y += 1
end
return 42
end
var = 0;
foo1(var)
# 42
var
# 0
But when doing something similar on an array, it acts as a mutating function (modifies it argument in the global scope!)
function foo2(x)
y = x
t = 1
while t < 1000
t += 1
y[1] += 1
end
return 42
end
var = zeros(1);
foo2(var)
# 42
var
# 999.0
I realize I can fix this by changing the first line to y = copy(x) , but what is the reason for such a (dangerous?) behaviour in the first place?
I would write an answer to this, but I think John Myles White has already done it better than I ever could so I'll just link to his blogpost:
https://www.juliabloggers.com/values-vs-bindings-the-map-is-not-the-territory-3/
In short x = 1 and x[1] = 1 are very different operations. The first one is assignment—i.e. changing a binding of the variable x—while the second is a syntactic sugar for calling the setindex! function, which, in the case of arrays, assigns to a location in the array. Assignment only changes which variables refer to which objects and never modifies any objects. Mutation only modifies objects and never changes which variables refer to which objects. This answer has a bit more detail about the distinction: Creating copies in Julia with = operator.
I need to solve this differential equation using Runge-Kytta 4(5) on Scilab:
The initial conditions are above. The interval and the h-step are:
I don't need to implement Runge-Kutta. I just need to solve this and plot the result on the plane:
I tried to follow these instructions on the official "Scilab Help":
https://x-engineer.org/graduate-engineering/programming-languages/scilab/solve-second-order-ordinary-differential-equation-ode-scilab/
The suggested code is:
// Import the diagram and set the ending time
loadScicos();
loadXcosLibs();
importXcosDiagram("SCI/modules/xcos/examples/solvers/ODE_Example.zcos");
scs_m.props.tf = 5000;
// Select the solver Runge-Kutta and set the precision
scs_m.props.tol(6) = 6;
scs_m.props.tol(7) = 10^-2;
// Start the timer, launch the simulation and display time
tic();
try xcos_simulate(scs_m, 4); catch disp(lasterror()); end
t = toc();
disp(t, "Time for Runge-Kutta:");
However, it is not clear for me how I can change this for the specific differential equation that I showed above. I have a very basic knowledge of Scilab.
The final plot should be something like the picture bellow, an ellipse:
Just to provide some mathematical context, this is the differential equation that describes the pendulum problem.
Could someone help me, please?
=========
UPDATE
Based on #luizpauloml comments, I am updating this post.
I need to convert the second-order ODE into a system of first-order ODEs and then I need to write a function to represent such system.
So, I know how to do this on pen and paper. Hence, using z as a variable:
OK, but how do I write a normal script?
The Xcos is quite disposable. I only kept it because I was trying to mimic the example on the official Scilab page.
To solve this, you need to use ode(), which can employ many methods, Runge-Kutta included. First, you need to define a function to represent the system of ODEs, and Step 1 in the link you provided shows you what to do:
function z = f(t,y)
//f(t,z) represents the sysmte of ODEs:
// -the first argument should always be the independe variable
// -the second argument should always be the dependent variables
// -it may have more than two arguments
// -y is a vector 2x1: y(1) = theta, y(2) = theta'
// -z is a vector 2x1: z(1) = z , z(2) = z'
z(1) = y(2) //first equation: z = theta'
z(2) = 10*sin(y(1)) //second equation: z' = 10*sin(theta)
endfunction
Notice that even if t (the independent variable) does not explicitly appear in your system of ODEs, it still needs to be an argument of f(). Now you just use ode(), setting the flag 'rk' or 'rkf' to use either one of the available Runge-Kutta methods:
ts = linspace(0,3,200);
theta0 = %pi/4;
dtheta0 = 0;
y0 = [theta0; dtheta0];
t0 = 0;
thetas = ode('rk',y0, t0, ts, f); //the output have the same order
//as the argument `y` of f()
scf(1); clf();
plot2d(thetas(2,:),thetas(1,:),-5);
xtitle('Phase portrait', 'theta''(t)','theta(t)');
xgrid();
The output:
I have a function called particle.new, and one of the parameters is called "colour". I need this to always be a table, but it isn't. This gives me an error because I'm using it with a function called love.graphics.setColor(), and I need to give it a table. I'm using my colour variable with it, which gives me an error because it is expecting a table and it thinks that colour isn't a table. Anyway, here's my code.
particle = {}
particle.__index = particle
function particle.new (x, y, colour, mass, drag)
local self = setmetatable({}, particle)
self.x, self.y, self.colour, self.mass, self.drag = x, y, colour, mass, drag
return self
end
function particle:draw ()
prevColor = love.graphics.getColor()
love.graphics.setColor(self.colour)
love.graphics.point(self.x, self.y)
love.graphics.setColor(prevColor)
end
function particle:update ()
end
function love.load()
gravity = -9.32
particles = {}
table.insert(particles, particle.new(50,50,{255, 0, 0, 255},1,0.2))
end
function love.draw()
for i = 1, table.maxn(particles) do
particles[i]:draw()
end
end
By the way, I'm using the Love2D game engine.
Your issue is not with self.colour not being a table, it's with this line
prevColor = love.graphics.getColor()
When you do that, prevColor is only getting one of the four returned values.
The solution to this is to enclose the function call in a table, so that all 4 values are kept. (Like what #EgorSkriptunoff said)
prevColor = {love.graphics.getColor()}
As for your question:
Use assert and type to check the variable type
assert(type(colour)=="table", "-Error message goes here-")
Do note however, assert will throw an error which will bring up the blue love2d screen and stop your program from running.
I want to pass function(string) from uicontrol via my GUI, and how properly use str2func to send function into my m file.
Piece of my GUI.m file
function functionbox_Callback(hObject, eventdata, handles)
fun= str2func(get(handles.functionbox, 'String'));
[x, y] = hessian(fun);
Piece of my hessian.m file where i want to pass function from GUI:
function [x, y] = hessian(fun)
f = #(x,y) fun;
blablabla
hold off
How I can do this kind of method.
If I understood correctly your question you have pretty much figured it out. What is missing from your code would be to call f with appropriate input arguments to obtain the outputs x and y.
Consider this code which is based on yours. The use enters a function in the lefthand box and the output (actually x+y...just for the demo) is displayed in the righthand box. Play around with it too see how the functions work together. Please ask if something is unclear.
Code:
function LoadFun
clear
clc
hfigure = figure('Position',[200 200 300 300]);
handles.TextFunction = uicontrol('Style','Text','Position',[20 220 100 20],'String','Enter function');
handles.functionbox = uicontrol('Style','edit','Position',[20 200 100 20],'String','');
handles.TextResult = uicontrol('Style','Text','Position',[140 220 100 20],'String','Output');
handles.resultbox = uicontrol('Style','edit','Position',[140 200 100 20],'String','');
handles.Button = uicontrol('Style','push','Position',[20 160 100 20],'String','Call function','Callback',#(s,e) ButtonCallback);
%// Call the function
function ButtonCallback
fun= str2func(get(handles.functionbox, 'String'));
[x,y] = hessian(fun);
%// Make other calculation and display output;
z = x+y;
set(handles.resultbox ,'String',num2str(z));
end
%// Your function
function [x,y] = hessian(fun)
%// Define handles. Inputs do not have to be x and y here.
f = #(a,b) fun(a) + fun(b);
%// Perform operations
x = f(pi,pi/2);
y = f(0,2*pi);
end
end
Screenshot:
Hope that is what you were after!
str2func works a lot like the function-handle #.
So if your input looks something like this:
'#(x,y) x+y'
or
'functionname'
it should work just fine.
To pass the, now, function handle to your GUI, you do not need to define it again:
function [x, y] = hessian(fun)
result=fun(data);
blablabla hold off
As for multiple Outputs of anonymous-functions:
it is possible, but, as far as I know, not inline.
Source:http://ch.mathworks.com/help/matlab/matlab_prog/anonymous-functions.html#f4-70159
But this is easily solved with arrays.