Why won't python update function value? - python

I am trying to make a table in python that asks a user for a side length of a polygon and then gives the area of that polygon when it's number of sides is between 3-9. My problem is that, in the report function, I have to give a different area for each polygon with a different number of sides but when i run it, the area is always the same even when the number of sides of the polygon has changed.
import math
def main():
side_length = get_side_length()
report(side_length)
def get_side_length():
length = int(input('Enter a side length: '))
return length
def report(a):
num_sides = 2
each_area = polygon_area(a)
print('side length\t'+ 'number of sides\t'+ 'area')
while num_sides < 9:
num_sides += 1
print(a, num_sides, each_area, sep='\t\t', end='\n')
def polygon_area(sl):
for num_sides in range(3, 10):
area = (num_sides * sl * sl) / (4 * math.tan(math.pi / num_sides))
return area
main()

Related

Can't run turtle program on macOS: "turtle.TurtleGraphicsError: bad color string: blue"

The program for drawing the Fibonacci spiral works on a virtual machine on Windows, but does not work on macOS and gives errors.
Here's my code:
import turtle
Import math
def fiboPlot(n):
a = 0
b = 1
square_a = a
square_b = b
#Setting the colour of the plotting pen to blue
x.pencolor("blue")
# Drawing the first square
x.forward(b * factor)
x.left(90)
x.forward(b * factor)
x.left(90)
x.forward(b * factor)
x.left(90)
x.forward(b * factor)
# Proceeding in the Fibonacci Series
temp = square_b
square_b = square_b + square_a
square_a = temp
# Drawing the rest of the squares
for i in range(1, n):
x.backward(square_a * factor)
x.right(90)
x.forward(square_b * factor)
x.left(90)
x.forward(square_b * factor)
x.left(90)
x.forward(square_b * factor)
# Proceeding in the Fibonacci Series
temp = square_b
square_b = square_b + square_a
square_a = temp
# Bringing the pen to starting point of the spiral plot
x.penup()
x.setposition(factor, 0)
x.seth(0)
x.pendown()
# Setting the colour of the plotting pen to red
x.pencolor("red")
# Fibonacci Spiral Plot
x.left(90)
for i in range(n):
print(b)
fdwd = math.pi * b * factor / 2
fdwd /= 90
for j in range(90):
x.forward(fdwd)
x.left(1)
temp = a
a = b
b = temp + b
# Here 'factor' signifies the multiplicative
# factor which expands or shrinks the scale
# of the plot by a certain factor.
factor = 1
# Taking Input for the number of
# Iterations our Algorithm will run
n = int(input('Enter the number of iterations (must be > 1): '))
# Plotting the Fibonacci Spiral Fractal
# and printing the corresponding Fibonacci Number
if n > 0:
print("Fibonacci series for", n, "elements :")
x = turtle.Turtle()
x.speed(100)
fiboPlot(n)
turtle.done()
else:
print("Numb
Here are the errors:
kEventMenuPopulate to menu ''
kEventMenuPopulate to menu '<Apple>'
kEventMenuPopulate to menu 'python'
kEventMenuPopulate to menu 'File'
kEventMenuPopulate to menu 'Edit'
kEventMenuPopulate to menu 'Window'
kEventMenuPopulate to menu 'Help'
kEventMenuPopulate to menu 'Help'
kEventMenuPopulate to menu 'Help'
kEventMenuPopulate to menu 'Help'
kEventMenuPopulate to menu ''
and this
File "/Users/als/PycharmProjects/spiral_of_fibonacci/main.py", line 81, in <module>
fiboPlot(n)
File "/Users/als/PycharmProjects/spiral_of_fibonacci/main.py", line 12, in fiboPlot
x.pencolor("blue")
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/turtle.py", line 2253, in pencolor
color = self._colorstr(args)
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/turtle.py", line 2697, in _colorstr
return self.screen._colorstr(args)
File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/turtle.py", line 1159, in _colorstr
raise TurtleGraphicsError("bad color string: %s" % str(color))
turtle.TurtleGraphicsError: bad color string: blue
In macOS
In Windows
I can't see problems with the code, because it runs on Windows.
After fixing the incomplete line:
print("Numb
and changing the case on the incorrect line:
Import math
this code runs fine on my Mac OS (Unix) system. Below is my rework of your code to simplify it so I could see everything that was going on. See if it works any better for you:
from turtle import Screen, Turtle
from math import pi
# 'FACTOR' signifies the multiplicative factor
# which expands or shrinks the scale of the plot:
FACTOR = 2
def fiboPlot(n):
a, b = 0, 1
# Setting the colour of the plotting pen to blue
turtle.pencolor('blue')
# Drawing the first square
for _ in range(4):
turtle.forward(b * FACTOR)
turtle.left(90)
turtle.right(90)
# Drawing the rest of the squares
for _ in range(n - 1):
# Proceeding in the Fibonacci Series
a, b = b, b + a
turtle.backward(a * FACTOR)
turtle.right(90)
turtle.forward(b * FACTOR)
turtle.left(90)
turtle.forward(b * FACTOR)
turtle.left(90)
turtle.forward(b * FACTOR)
# Bringing the pen to starting point of the spiral plot
turtle.penup()
turtle.setposition(FACTOR, 0)
turtle.setheading(90)
turtle.pendown()
# Setting the colour of the plotting pen to red
turtle.pencolor('red')
a, b = 0, 1
# Fibonacci Spiral Plot
for _ in range(n):
print(b)
distance = pi * b * FACTOR / 180
for _ in range(90):
turtle.forward(distance)
turtle.left(1)
a, b = b, b + a
# Input the number of iterations our algorithm will run:
n = int(input('Enter the number of iterations (must be > 1): '))
# Plot the fibonacci spiral fractal and
# print the corresponding fibonacci number:
if n > 0:
print("Fibonacci series for", n, "elements:")
screen = Screen()
turtle = Turtle()
turtle.speed('fastest')
fiboPlot(n)
screen.mainloop()
else:
print("Number something or other")

Python turtle assignment pleasehelp

I need to create a function called SpinPolygon that will do what the instruction says. I am a noob coder.
SpinPolygon(Turtle, sides, angle, length, repeat): Draws the polygon number of times while turn polygon by the angle on the left each time. Your program needs to ask number of sides, length of the side and number of rotations from the user) Below is a sample image for rotating 5 times.
I have this so far for the rest of my program:`
import turtle
stage = turtle.Screen() # set stage
stage.title("Shapes") # name stage
sides = int(input("Please enter number of sides:"))
length = int(input("Please enter length of side:"))
sfactor = float(input("Please enter the scale factor:"))
copies = int(input("Please enter number of copies:"))
repeat = int(input("Please enter number of times to repeat the shape:"))
def angle(sides):
sum_of_angles = (sides - 2) * 180
exterior_angle = sum_of_angles / sides
angle = 180 - exterior_angle
return angle
def drawShape(turtle, sides, length):
for i in range(sides):
turtle.forward(length)
turtle.left(angle(sides))
def SpinPolygon(Turtle, sides, angle, length, repeat):
print("idk")
def ScalePolygon(turtle, sides, length, sfactor, number):
for i in range(number):
drawShape(turtle, sides, length)
length *= sfactor
turtle.done()
ScalePolygon(turtle, sides, length, sfactor, copies)
Description doesn't mention to ask for sfactor, copies and even for angle.
You ask for too many elements.
Function angle can be reduced to angle = 360 / sides
You should start with SpinPolygon, not ScalePolygon.
And you don't even need ScalePolygon because description doesn't mention sfactor.
import turtle
# --- functions ---
def drawShape(turtle, sides, length):
shape_angle = 360 / sides
for i in range(sides):
turtle.forward(length)
turtle.left(shape_angle)
def SpinPolygon(turtle, sides, angle, length, repeat):
for i in range(repeat):
drawShape(turtle, sides, length)
turtle.left(angle)
# --- main ---
stage = turtle.Screen()
stage.title("Shapes")
sides = 5 #int(input("number of sides: "))
length = 100 #int(input("length of side: "))
repeat = 5 #int(input("number of rotations: "))
angle = 360/repeat
SpinPolygon(turtle, sides, angle, length, repeat)
turtle.done()
Result for sides = 5:
Result for sides = 4:
Result for sides = 8, length = 50, repeat = 15:
EDIT:
Code with extra sfactor
import turtle
# --- functions ---
def drawShape(turtle, sides, length):
shape_angle = 360 / sides
for i in range(sides):
turtle.forward(length)
turtle.left(shape_angle)
def SpinPolygon(Turtle, sides, angle, length, repeat, sfactor):
for i in range(repeat):
drawShape(turtle, sides, length)
turtle.left(angle)
length *= sfactor
# --- main ---
stage = turtle.Screen()
stage.title("Shapes")
sides = 8 #int(input("number of sides: "))
length = 50 #int(input("length of side: "))
repeat = 15 #int(input("number of rotations: "))
sfactor = 0.9 #float(input("sfactor: "))
angle = 360/repeat
SpinPolygon(turtle, sides, angle, length, repeat, sfactor)
turtle.done()
Result for sides = 8, length = 50, repeat = 15 and sfactor = 0.9:

Confused about Functions

So I'm currently doing an assignment for my python coding class and I have to get the area of a cylinder and I'm supposed to be using functions so it looks cleaner, but I'm not so sure how to exactly do my assignment from scratch, I've watched a lot of videos but can't really seem to understand functions, my code looks like this currently, but whenever I run my code I can't get the "def calc():" part to run, could I get some pointers please?
def info():
r = float(input("What is the radius of the cylinder? "))
h = float(input("What is the height of the cylinder? "))
print("The cylinders area is", area)
def calc():
pi = 22/7
area = ((2*pi*r) * h) + ((pi*r**2)*2)
return pi, area
info()
Don't need so many funcatin .
def info():
r = float(input("What is the radius of the cylinder? "))
h = float(input("What is the height of the cylinder? "))
calc(r,h)
def calc(r,h):
pi = 22/7
area = ((2*pi*r) * h) + ((pi*r**2)*2)
print("The cylinders area is", area)
info()
in this case I put the radius as 3 and height as 6. You need to define you variables.
Then it should work. in this case I used numpy to import an exact pi variable.
You have to put the calc() function above the info() function. You have to actually call the calc() function which will return the area of cylinder. I have provided the code below which should solve your problem. Hope you understand the code!
def calc(r, h): # Calculates the area of cylinder
pi = 22/7
area = ((2*pi*r) * h) + ((pi*r**2)*2)
return area
def info(): # Takes the radius and height from user.
r = float(input("What is the radius of the cylinder? "))
h = float(input("What is the height of the cylinder? "))
return f"The area is {calc(r, h)}"
# r = 5
# h = 10
print(info())
# using parameters in functions instead of inputs:
def info2(r, h):
return f"The area is {calc(r, h)}"
r = 5
h = 10
print(info2(r, h))
# Comparing areas of cylinders
area1 = calc(5, 10)
area2 = calc(10, 15)
if area1>area2: #Area1 is greater than Area2
print("Area1 is greater than Area2")
elif area2>area1: #Area2 is greater than Area1
print("Area2 is greater than Area1")
else: #Both are equal
print("Both are equal")
You mentioned in a comment that you wanted to input multiple cylinders and determine which was the larger one -- I think for that you want to have your function that inputs a cylinder return the cylinder itself so that it can be compared using the volume function.
from dataclasses import dataclass
from math import pi
#dataclass
class Cylinder:
radius: float
height: float
name: str
def volume(c: Cylinder) -> float:
return (2*pi*c.radius) * c.height + (pi*c.radius**2)*2
def input_cylinder(name: str) -> Cylinder:
r = float(input(f"What is the radius of the {name} cylinder? "))
h = float(input(f"What is the height of the {name} cylinder? "))
return Cylinder(r, h, name)
if __name__ == '__main__':
cylinders = [input_cylinder(name) for name in ('first', 'second')]
for c in cylinders:
print(f"The {c.name} cylinder's volume is {volume(c)}")
print(f"The bigger cylinder is the {max(cylinders, key=volume).name} one.")

Click-Circle game - clicking outside and inside the circle

I am trying to code a game that has a red circle in which the user is supposed to click up to 7 times in the window. If the user clicks outside the circle, the circle will change its position to where the user clicked. And the game should end when the user has clicked 3 times inside the circle (does not have to be in a row) or when the user has clicked 7 times in total.
I have coded and done quite most of it I think, its just I cant seem to make it work as I want to.
from graphics import *
def draw_circle(win, c=None):
x = random.randint(0,500)
y = random.randint(0,500)
if var is None:
centa = Point(x,y)
var = Circle(centa,50)
var.setFill(color_rgb(200,0,0))
var.draw(win)
else:
p1 = c.p1
x_dif = (p1.x - x) * -1
y_dif = (p1.y - y) * -1
var.move(x_dif, y_dif)
return (var, x, y)
def main():
win= GraphWin("game",800,800)
score = 0
var,x,y = draw_circle(win)
while score <= 7:
mouseClick2=win.getMouse()
if mouseClick2.y >= y-50 and mouseClick2.y <= y +50 and
mouseClick2.x >= x-50 and mouseClick2.x <= x+50:
score=score + random.randint(0,5)
var,x,y = draw_circle(win, c)
print ("Success!")
print (("the score is, {0}").format(score))
thanks for the help in advance!
I see a couple problems.
your if mouseClick2.y >= y-50... conditional is spread out on two lines, but you don't have a line continuation character.
You never call main().
You don't import random.
You call draw_circle in the while loop with an argument of c, but there is no variable by that name in the global scope. You probably meant to pass in var.
c in draw_circle ostensibly refers to the circle object you want to manipulate, but half the time you manipulate var instead of c.
you assign a value to cvar in the loop, but never use it.
Your else block in draw_circle calculates the movement delta by subtracting the cursor coordinates from c.p1. But c.p1 is the upper-left corner of the circle, not the center of the circle. So your hit detection is off by fifty pixels.
import random
from graphics import *
def draw_circle(win, c=None):
x = random.randint(0,500)
y = random.randint(0,500)
if c is None:
centa = Point(x,y)
c = Circle(centa,50)
c.setFill(color_rgb(200,0,0))
c.draw(win)
else:
center_x = c.p1.x + 50
center_y = c.p1.y + 50
x_dif = (center_x - x) * -1
y_dif = (center_y - y) * -1
c.move(x_dif, y_dif)
return (c, x, y)
def main():
win= GraphWin("game",800,800)
score = 0
var,x,y = draw_circle(win)
while score <= 7:
mouseClick2=win.getMouse()
if mouseClick2.y >= y-50 and mouseClick2.y <= y +50 and \
mouseClick2.x >= x-50 and mouseClick2.x <= x+50:
score=score + random.randint(0,5)
var,x,y = draw_circle(win, var)
print ("Success!")
print (("the score is, {0}").format(score))
main()
Additional possible improvements:
Your hit detection checks whether the cursor is in a 50x50 rectangle centered on the circle. You could instead check whether the cursor is inside the circle if you measured the distance between the cursor and the center, and checked whether it was less than the radius.
var and c could stand to have more descriptive names.
mouseClick2 doesn't make much sense as a name, considering there's no mouseClick1.
The movement delta arithmetic could be simplified: (a-b) * -1 is the same as (b-a).
If you only use a variable's value once, you can sometimes avoid creating the variable at all if you nest expressions.
it might be nice to define constants, such as for the circle's radius, instead of having magic numbers in your code.
You can save five characters by using += to increment the score.
import math
import random
from graphics import *
RADIUS = 50
def draw_circle(win, circle=None):
x = random.randint(0,500)
y = random.randint(0,500)
if circle is None:
circle = Circle(Point(x,y),RADIUS)
circle.setFill(color_rgb(200,0,0))
circle.draw(win)
else:
circle.move(
x - circle.p1.x - RADIUS,
y - circle.p1.y - RADIUS
)
return (circle, x, y)
def main():
win= GraphWin("game",800,800)
score = 0
circle,x,y = draw_circle(win)
while score <= 7:
cursor = win.getMouse()
if math.hypot(cursor.x - x, cursor.y - y) <= RADIUS:
score += random.randint(0,5)
circle,x,y = draw_circle(win, circle)
print ("Success!")
print (("the score is, {0}").format(score))
main()
I'm not really a python guy, but I see that your hitbox is wrong. If there are any other issues then comment it/them to me.
Solving hitbox to be circle:
What you have already written is good to have thing but you should check if click was in circle not square. Pythagoras triangle is solution for this.
Check:
if (math.sqrt(delta_x **2 + delta_y **2) <= circle_radius)
where delta_x and delta_y is center coordinate minus mouse position

Creating an image of a triangle centered at the centroid

Excuse me as I am a little new to programming. Basically, I am assigned to "analyze" and produce an image of a triangle where the user specifies the lengths of two sides and the size of the angle between them, the program runs and finds the length of the third side as well as the two other angles (using Law of Cosines). Then I must have text outputs for all sides lengths, all angle measures (optional), and also print the area in the form of my turtle printing out "Here is your triangle \n It has an area of x square pixels" in the image as well.
Also, the triangle must have its centroid at (0,0). This is what I have so far:
import math
from turtle import*
print("This program will draw a custom triangle.")
firstside=float(input("Enter length of first side (between 10 and 400 pixels): "))
secondside=float(input("Enter length of second side (between 10 and 400 pixels): "))
includedangle=float(input("Enter the measure of the included angle in degrees (between 1 and 179): "))
print("Side lengths and angle measures:\n")
solvedthirdside=float(math.sqrt(firstside**2+secondside**2-(2*firstside*secondside*math.cos(includedangle))))
cage=Screen(); #Create screen object named cage
cage.setup(500,500) #set screen size to 500x500 pixels
Also, I am using the turtle graphics for this too.
I am really struggling with this. Some help would be greatly appreciated!
Please help! Thanks!
This is not finished, but should be a lot easier to work on now.
I have thoroughly factored it into functions and commented heavily; it should be pretty easy to understand. Hope that helps!
import math
import turtle
def get_float(prompt):
"""
Prompt for input and return it as a floating-point number
"""
while True:
try:
return float(input(prompt))
except ValueError:
pass
def third_side(a, b, C):
"""
Given a triangle defined by two sides and
the angle between them (in degrees),
return the length of the third side
"""
return math.sqrt(a**2 + b**2 - 2. * a * b * math.cos(math.radians(C)))
def get_sides():
"""
Prompt for a triangle as two sides and an angle,
calculate the length of the third side,
and return the three side lengths
"""
side1 = get_float("Length of first side (pixels, in 10..400)? ")
side2 = get_float("Length of second side (pixels, in 10..400)? ")
angle = get_float("Included angle (degrees, in 1..179)? ")
return side1, side2, third_side(side1, side2, angle)
def get_angle(opp, left, right):
"""
Given three sides of a triangle,
return the angle opposite the first side (in degrees)
"""
cos_opp = (left**2 + right**2 - opp**2) / (2. * left * right)
return math.degrees(math.acos(cos_opp))
def get_angles(a, b, c):
"""
Given three sides of a triangle,
return the three angles (in degrees)
"""
return get_angle(a, b, c), get_angle(b, c, a), get_angle(c, a, b)
def main():
print("This program will draw a custom triangle.\n")
side1, side2, side3 = get_sides()
angle1, angle2, angle3 = get_angles(side1, side2, side3)
print(
"\n"
"Sides and angles:\n"
"a = {side1:>5.1f} A = {angle1:>5.1f}\n"
"b = {side2:>5.1f} B = {angle2:>5.1f}\n"
"c = {side3:>5.1f} C = {angle3:>5.1f}\n"
.format(
side1=side1, side2=side2, side3=side3,
angle1=angle1, angle2=angle2, angle3=angle3
)
)
# Your code continues here!
if __name__=="__main_":
main()

Categories