How to handle a varying number of parameters on a function? - python-3.x

I'm trying to construct a code that gives a square's area and a rectangle's area with the same function, but I'm either running into missing positional argument error or something more exotic with whatever I do and I was flabbergasted by the potential solutions out there as I'm only a very basic level of python coder.
The biggest question is what kind of format should area() function be in order for me to be able to have it assume y is None if it's not given.
def area(x, y):
return x * x if y is None else x * y #Calculate area for square and rectangle
def main():
print("Square's area is {:.1f}".format(area(3))) #Square
print("Rectangle's area is {:.1f}".format(area(4, 3))) #Rectangle
main()

Do it like so:
def area(x, y=None):
return x * x if y is None else x * y #Calculate area for square and rectangle
By giving a default value, you may pass 1 less argument and it will be set to the default.

Related

how do I make a for loop understand that I want it to run i for all values inside x. x being a defined array

My code right now is as it follows:
from math import *
import matplotlib.pyplot as plt
import numpy as np
"""
TITLE
"""
def f(x,y):
for i in range(len(x)):
y.append(exp(-x[i]) - sin (pi*x[i]/2))
def ddxf(x,y2):
for i in range(len(x)):
y2.append(-exp(-x[i]) - (pi/2)*cos(pi*x[i]/2))
y = []
y2 = []
f(x, y)
x = np.linspace(0, 4, 100)
plt.title('Graph of function x')
plt.xlabel('x')
plt.ylabel('f(x)')
plt.plot(x, y, 'g')
plt.grid(True)
plt.show()
x0 = float(input("Insert the approximate value of the first positive root: "))
intMax = 100
i = 0
epsilon = 1.e-7
while abs(f(x0,y)) > epsilon and i < intMax:
x1 = x0 - (f(x0))/(ddxf(x0))
x0 = x1
i += 1
print (i)
print (x1)
I get this error when running the program. it seems that (len(x)) cannot be used if x isnt a string. which doesn't make sense to me. if the array has a len and isn't infinite, why (len(x)) cant read his length? anyway, please help me. hope I made myself clear
Regarding the error: You are using x before defining it. In your code, you first use f(x, y) and only after that you actually define what x is (namely x = np.linspace(0, 4, 100)). You probably want to swap these two lines to fix the issue.
Regarding the question in the title: len(x) should be fine to get the length of a list. However, in Python you don't need to go through a list like that. You can instead use for element_name in list_name: This will essentially go through list_name element by element and make it available to you with the name element_name.
There is also something called list comprehensions in Python - you might want to take a look at those and see whether you can apply it to your code.

How to enact pass by reference in python as we do in C/C++?

x,y = 30,40
def swap(x,y):
x = x+y
y = x-y
x = x-y
print(x,y) #Here it swaps but as soon as function ends they go back to their previous values
swap(x,y)
print(x,y) #still prints x as 30 and y as 40
In C/C++ we used & operator to pass their addresses to make this change, how can we do the same thing in python considering python follows pass by object reference model?

how to display a stack of 5 blocks using recursive function?

I am doing an exercise with recursive function and I don't quite get it. I need to update a function
def draw_stack(screen, x, y, height):
draw_block (screen, x, y)
In this function it should display a stack of 5 blocks in the screen anchored at the location x= 100, y =200.
How can I start this function? Can someone please explain how can I start my code?
def draw_stack(screen, x, y, height):
draw_block (screen, x, y)
for x in range(5): # This loop will run 5 times
draw_stack(screen, 100, 200, 50)# This will run your function. You need to specify functions arguments.
I if you want to change values while running loop you can to this:
for x in range(5): # This loop will run 5 times
draw_stack(screen, 100, 200+x, 50)# you can add or multiple any arg by x

How are the values being determined in this basic Python class?

I am new to Python and to OOP concept. I was doing a EdX course and came across this code. I have modified it a little bit here. But I need to understand what exactly is happening here.
Question-1: Why does print(baba.x) give 7 but not 3?
Question-2: What does print(X) (capital X) do here? In getX and init I am using 'x' and not 'X'. So where does print(X) get its value from? It seems it is getting this value from the X=7 assignment. But isn't that assignment happening outside of the method getX and also outside of the class Weird. So why is getX able to access X=7 value?
I have searched on scope in Python, but was getting too complicated for me.
class Weird(object):
def __init__(lolo, x, y):
lolo.y = y
lolo.x = x
def getX(baba,x):
print (baba.x)
print (x)
print (X)
X = 7
Y = 8
w1 = Weird(X, Y)
print(w1.getX(3))
The output of the above code is:
7
3
7
None
Read What is the purpose of the word 'self', in Python?
class Weird(object):
def __init__(self, x, y):
self.y = y
self.x = x
def getX(self,x):
print (self.x) # this is the x value of this instance
print (x) # this is the x value you provide as parameter
print (X) # this might read the global X
X = 7
Y = 8
w1 = Weird(X, Y) # this sets w1.x to X (7) and w1.y to Y (8)
print(w1.getX(3)) # this provides 3 as local x param and does some printing

Perlin Noise understanding

I found two tutorials that explains how the Perlin Noise works, but in the first tutorial I found not understandable mystery of gradients, and in the second one I found the mystery of surflets.
First case
The first tutorial is located here catlikecoding.com/unity/tutorials/noise. At first autor explains the value noise which is completely understandable, because all we need to do is to draw a grid of random colors and then just interpolate between the colors.
But when it comes to the Perlin Noise, we have to deal with gradients, not with single colors. At first I thought about gradiens as colors, so if we have two gradients and we want to make interpolation between them, we have to take a respective point of the first gradient and interpolate it with respective point of the second gradient. But if the gradients are the same, we will have a result which is the same as gradients.
In the tutorial author makes it in another way. If we have a 1d grid which consists of columns that are filled with the same gradient, and each gradient can be represented as transition from 0 to 1 (here 0 is black color, and 1 is white color). Then author says
Now every stripe has the same gradient, except that they are offset
from one another. So for every t0, the gradient to the right of it is
t1 = t0 - 1. Let's smoothly interpolate them.
So it means that we have to interpolate between a gradient which is represented as transition from 0 to 1, and a gradient which is represented as transition from -1 to 0.
It implies that every gradient doesn't start at position with value of 0 and doesn't stop at position with value of 1. It starts somewhere at -1 and ends somewhere at 2, or maybe it has no start and end points. We can see only 0 to 1 range, and I can't understand why it is like this. Whence did we take the idea of continuous gradient? I thought that we have only gradient from 0 to 1 for every strip and that's all, don't we?
When I asked the author about all this he answered like this is something obvious
The gradient to the right is a visual reference. It’s the gradient for
the next higher integer. You’re right that it goes negative to the
left. They all do.
So t0 is the gradient that’s zero at the lattice point on the left
side of the region between two integers. And t1 is the gradient that’s
zero at the lattice point on the right side of the same region.
Gradient noise is obtained by interpolating between these two
gradients in between lattice points. And yes, that can produce
negative results, which end up black. That’s why the next step is to
scale and offset the result.
Now I feel like this is impossible for me to understand how this works, so I have just to believe and repeat after smarter guys. But hope dies last, so I beg you to explain it to me somehow.
Second case
The second tutorial is located here eastfarthing.com/blog/2015-04-21-noise/ and it's much less sophisticated than the previous one.
The only problem I had encountered is that I can't understand next paragraph and what's going on after this
So given this, we can just focus on the direction of G and always use
unit length vectors. If we clamp the product of the falloff kernel and
the gradient to 0 at all points beyond the 2×2 square, this gives us
the surflet mentioned in that cryptic sentence.
I'm not sure whether the problem is in my poor math or English knowledge, so I ask you to explain what does this actually mean in simple words.
Here is some code I have written so far, it relates to the second case
import sys
import random
import math
from PyQt4.QtGui import *
from PyQt4.QtCore import pyqtSlot
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
self.gx=1
self.gy=0
self.lbl=QLabel()
self.tlb = None
self.image = QImage(512, 512, QImage.Format_RGB32)
self.hbox = QHBoxLayout()
self.pixmap = QPixmap()
self.length = 1
self.initUI()
def mousePressEvent(self, QMouseEvent):
px = QMouseEvent.pos().x()
py = QMouseEvent.pos().y()
size = self.frameSize()
self.gx = px-size.width()/2
self.gy = py-size.height()/2
h = (self.gx**2+self.gy**2)**0.5
self.gx/=h
self.gy/=h
self.fillImage()
def wheelEvent(self,event):
self.length+=(event.delta()*0.001)
print(self.length)
def initUI(self):
self.hbox = QHBoxLayout(self)
self.pixmap = QPixmap()
self.move(300, 200)
self.setWindowTitle('Red Rock')
self.addedWidget = None
self.fillImage()
self.setLayout(self.hbox)
self.show()
def fillImage(self):
step = 128
for x in range(0, 512, step):
for y in range(0, 512, step):
rn = random.randrange(0, 360)
self.gx = math.cos(math.radians(rn))
self.gy = math.sin(math.radians(rn))
for x1 in range(0, step):
t = -1+(x1/step)*2
color = (1 - (3 - 2*abs(t))*t**2)
for y1 in range(0, step):
t1 = -1+(y1/step)*2
color1 = (1 - (3 - 2*abs(t1))*t1**2)
result = (255/2)+(color * color1 * (t*self.gx+t1*self.gy) )*(255/2)
self.image.setPixel(x+x1, y+y1, qRgb(result, result, result))
self.pixmap = self.pixmap.fromImage(self.image)
if self.lbl == None:
self.lbl = QLabel(self)
else:
self.lbl.setPixmap(self.pixmap)
if self.addedWidget == None:
self.hbox.addWidget(self.lbl)
self.addedWidget = True
self.repaint()
self.update()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
float Noise::perlin1D(glm::vec3 point, float frequency)
{
// map the point to the frequency space
point *= frequency;
// get the base integer the point exists on
int i0 = static_cast<int>(floorf(point.x));
// distance from the left integer to the point
float t0 = point.x - static_cast<float>(i0);
// distance from the right integer to the point
float t1 = t0 - 1.f;
// make sure the base integer is in the range of the hash function
i0 &= hashMask;
// get the right integer (already in range of the hash function)
int i1 = i0 + 1;
// choose a pseudorandom gradient for the left and the right integers
float g0 = gradients1D[hash[i0] & gradientsMask1D];
float g1 = gradients1D[hash[i1] & gradientsMask1D];
// take the dot product between our gradients and our distances to
// get the influence values. (gradients are more influential the closer they are to the point)
float v0 = g0 * t0;
float v1 = g1 * t1;
// map the point to a smooth curve with first and second derivatives of 0
float t = smooth(t0);
// interpolate our influence values along the smooth curve
return glm::mix(v0, v1, t) * 2.f;
}
here is a commented version of the code in question. But rewritten for c++. Obviously all credit goes to catlikecoding.
We've given the function a point p. Let's assume the point p is fractional so for example if p is .25 then the integer to the left of p is 0 and the integer to the right of p is 1. Let's call these integers l and r respectively.
Then t0 is the distance from l to p and t1 is the distance from r to p. The distance is negative for t1 since you have to move in a negative direction to get from r to p.
If we continue on to the perlin noise part of this implementation g0 and g1 are pseudorandom gradients in 1 dimension. Once again gradient may be confusing here since g0 and g1 are floats, but a gradient is simply a direction and in one dimension you can only go positive or negative, so these gradients are +1 and -1. We take the dot product between the gradients and the distances, but in one dimension this is simply multiplication. The result of the dot product is the two floats v0 and v1. These are the influence values of our perlin noise implementation. Finally we smoothly interpolate between these influence values to produce a smooth noise function. Let me know if this helps! This perlin noise explanation was very helpful in my understanding of this code.

Resources