Python turtle color changing and fill - python

This code draws a shape when the user inputs the number of squares to draw and the size of those squares. I want the color to change for every square that is drawn, and for it to get filled in. But the code gets stuck:
import turtle
t = turtle.Turtle()
size = int(input("How long do you want the side lengths to be?"))
number = int(input("How many squares do you want in the image?"))
red = 40.0
blue = 30.0
green = 10.0
def square (size):
count = 0
while count < 4:
t.forward(size)
t.right(90)
count = count + 1
def drawing(number):
times = 0
while times < number:
t.pencolor(red, blue, green)
t.fillcolor(red, blue, green)
t.begin_fill()
square(size)
t.right(360/number)
if t.filling():
t.pensize(5)
else:
t.pensize(3)
t.color()
(red + 1, blue + 1, green + 1)
times = times + 1
drawing(number)

There are several problems with your code -- the primary one is you're using the wrong color model. By default, turtle colors are specified as floating point values between 0.0 and 1.0. However, you want to use values like those in your code, we can switch this via colormode(255) which allows values from 0 to 255.
Next, a begin_fill() has to have a matching end_fill() which you are missing. Colors are specified in the order (red, green, blue), not (red, blue, green). Also, if you set both pencolor() and fillcolor() to the same color, you can simply use the one call color().
Finally, these two statements don't do anything:
t.color()
(red + 1, blue + 1, green + 1)
as far as your code is concerned. You need to rethink them. Below is my rework of your code which addresses the above issues and some other details:
from turtle import Screen, Turtle
def square(size):
count = 0
if turtle.filling():
turtle.pensize(5)
else:
turtle.pensize(3)
while count < 4:
turtle.forward(size)
turtle.right(90)
count += 1
def drawing(number):
red = 30
green = 10
blue = 20
times = 0
while times < number:
turtle.color(red % 255, green % 255, blue % 255)
turtle.begin_fill()
square(size)
turtle.end_fill()
turtle.right(360 / number)
red, green, blue = red + 20, green + 30, blue + 10
times += 1
size = int(input("How long do you want the side lengths to be? "))
number = int(input("How many squares do you want in the image? "))
screen = Screen()
screen.colormode(255)
turtle = Turtle()
turtle.speed('fastest') # because I have no patience
drawing(number)
screen.exitonclick()

Related

How to show shields level by changing color of the progress bar

I have a progress bar in the code which only shows a GREEN color but i want to modify it with the percentage of a player, if player is between 50 to 100% then its color is GREEN, if it is less than 50 and equal to 25 its color is ORANGE and under 25% is RED color.
I have attached a python code
I would be very thankful if anybody help
def draw_shield_bar(surf, x, y, pct):
I have a progress bar in the code which only shows a GREEN color but i want to modify it with the percentage of a player, if player is between 50 to 100% then its color is GREEN, if it is less than 50 and equal to 25 its color is ORANGE and under 25% is RED color. I have attached a python code
I would be very thankful if anybody help
def draw_shield_bar(surf, x, y, pct):
if pct < 0:
pct = 0
BAR_LENGTH = 100
BAR_HEIGHT = 10
fill = (pct / 100) * BAR_LENGTH
outline_rect = pygame.Rect(x, y, BAR_LENGTH, BAR_HEIGHT)
fill_rect = pygame.Rect(x, y, fill, BAR_HEIGHT)
pygame.draw.rect(surf, GREEN, fill_rect)
pygame.draw.rect(surf, WHITE, outline_rect, 2)
Just set the color dependent on the percentage:
color = GREEN if pct >= 50 else ORANGE if pct >= 25 else RED
pygame.draw.rect(surf, color, fill_rect)
By the way, the parameters to pygame.Rect() have to be integral, so when you calculate fill, then you've to use the integral division operator (//), rathet then the floating point division (/):
fill = BAR_LENGTH * pct // 100

Filling rectangles with colors in python using turtle

How can I draw a rectangle where: the smallest is 5 in height and each consecutive rectangle adds the first rectangles height, i.e. 5, 10, 15, …. The width of each rectangle is 200. The color of the lines are blue and the fill color, from top to bottom is grey0, grey14, grey28, ….
How can I do this and make sure the picture fits onto the screen?
(Each new rectangle goes below the previous one)
This is what I have so far, but I don't know how I can fill it:
import turtle
def rectangle(t, l, w):
for i in range(2):
t.right(90)
t.forward(l)
t.right(90)
t.forward(w)
me = turtle.Turtle()
me.color('blue')
me.pensize(2)
me.penup()
l = 2.5
w = 250
x = 50
y = 150
for i in range(9):
rectangle(me, l, w)
l = l*2
w = w
x = x
y = y
me.setposition(x,y)
me.pendown()
def filled_rectangle(t, l, w):
t.begin_fill()
for i in range(2):
t.right(90)
t.forward(l)
t.right(90)
t.forward(w)
t.end_fill()
Filling the rectangles is simple as #JoranBeasley has addressed. However, your specification of "smallest is 5" and "make sure the picture fits onto the screen" are in conflict. We need to fit the rectangles to the screen and take whatever starting size we get. Since each rectangle is twice the height of the next, then the starting rectangle is the available height divided by 2 (since we're doubling) raised to the power of the number of grey shades you want to represent:
from turtle import Turtle, Screen
def rectangle(t, l, w):
t.begin_fill()
for _ in range(2):
t.right(90)
t.forward(l)
t.right(90)
t.forward(w)
t.end_fill()
screen = Screen()
me = Turtle(visible=False)
me.penup()
GREYS = [ # adjust to taste
('grey0' , '#000000'),
('grey14', '#242424'),
('grey28', '#474747'),
('grey42', '#6B6B6B'),
('grey56', '#8F8F8F'),
('grey70', '#B3B3B3'),
('grey84', '#D6D6D6'),
('grey98', '#FAFAFA'),
]
WIDTH = 2 ** (len(GREYS) + 1) # depends on font and keep below screen.window_width()
x = WIDTH / 2 # rectangle() draws right to left -- move x right to center drawing
canvas_height = screen.window_height() * 0.90 # use most of the space available
length = canvas_height / 2 ** len(GREYS) # determine starting length to fill canvas
y = canvas_height / 2 # begin at the top of canvas
fontsize = 1
for name, color in GREYS:
me.fillcolor(color)
me.setposition(x, y)
me.pendown()
rectangle(me, length, WIDTH)
me.penup()
if 4 <= fontsize <= length:
font = ("Arial", fontsize, "bold")
me.setposition(0, y - length / 2 - fontsize / 2)
me.write(name, align="center", font=font)
fontsize *= 2
y -= length
length *= 2
screen.exitonclick()
The width is more arbitrary than the height but I made it a function of the fontsize and the doubling so I could write the shade names in the rectangles:
I reverted the outline color to black instead of blue so there'd be pure black nearby to compare the grey shades against.

Turtle begin_fill and end_fill with multiple shapes and loops

I need help capping off my for loops. (They can go on forever, yet I need them to be in range of 12 and 10.) My thinking is instead of this
for i in range(sides):
to do:
for sides in range(12):
#and for repeat do
for repeat in range(10):
This, in theory, should stop the possibly infinite process of looping, right? The second problem is my end_fill() doesn't fill in each shape with a different color. The outline and inside should be the same, and on a new shape, should be a random color (using randint function).
from turtle import *
import math
import random
#Continue being lazy and not creating turtles, also using a .cfg file to make the window.
colormode(255)
sides = int(input("Enter a number of sides (1-12): "))
repeat = int(input("How many times to repeat? (1-10): "))
#Turtle stuff.
penup()
goto(0,0)
size = 100
angle1 = 360 / sides
angle2 = 360 / repeat
#Here is where I am having issues, I am not sure how much to turn the turtle by do to the needed input
#Also I need to cap this off to only 12 sides and 10 repeats
#As it stands it can go for infinitum.
begin_fill()
for count in range(repeat):
for i in range(sides):
pendown() #Puts the pen down.
pensize(5) #Sets the pen to something more visible
colors1 = random.randint(0, 255) #Random red
colors2 = random.randint(0, 255) #Random blue
colors3 = random.randint(0, 255) #Random green
forward(size) #Goes forward 10 pixels
left(angle1)
penup()
#Goes left 360 / sides degrees. So 360 / 10 = 36 degrees.
pencolor(colors1, colors2, colors3) #Sets pencolor to a random RGB code
fillcolor(colors1, colors2, colors3) #Sets fillcolor to a random RGB code.
left(angle2) #Move left 90 degrees afterwards.
forward(5) #Moves forward 5 times.
end_fill() #Fills in the shape.
Code also available here: https://gist.github.com/anonymous/3984f7a1a04e9957ea55
Your first problem can be solved using Python 3 turtle's graphic numinput() instead of console input():
numinput(title, prompt, default=None, minval=None, maxval=None)
This will limit the range of the user's input. Your second issue is due to having begin_fill and end_fill at two different indentation levels. Usually, they should be at the same level. Here's a rework of your code with the above changes:
from turtle import Screen, Turtle
import random
screen = Screen()
screen.colormode(255)
sides = screen.numinput("Color Polygons", "Enter a number of sides (1-12)", default=6, minval=1, maxval=12)
if sides is None: # user cancelled operation
sides = 6
repeat = screen.numinput("Color Polygons", "How many times to repeat? (1-10)", default=5, minval=1, maxval=10)
if repeat is None:
repeat = 5
turtle = Turtle()
turtle.speed('fastest')
turtle.pensize(5)
turtle.penup()
size = 100
angle1 = 360 / sides
angle2 = 360 / repeat
for count in range(int(repeat)):
red = random.randint(0, 255)
green = random.randint(0, 255)
blue = random.randint(0, 255)
turtle.color(red, green, blue)
turtle.begin_fill()
for i in range(int(sides)):
turtle.pendown()
turtle.forward(size)
turtle.left(angle1)
turtle.penup()
turtle.end_fill()
turtle.left(angle2)
turtle.forward(5)
turtle.hideturtle()
screen.exitonclick()

Colors not varying - python graphics

I'm trying to reproduce something to this effect.
import graphics
from graphics import color_rgb
import random
window= graphics.GraphWin("x", 600, 400)
stripes = input("How many stripes should be on the flag")
stripes = int(stripes)
count = 0
count = int(count)
P1=graphics.Point(0,0) #left corner - anchor point
for x in range(stripes): #loop for number of stripes
col= random.randint(1,255)
stepdim = 400/stripes #size of divisions
stepdim = int(stepdim)
shrink = count*stepdim
shrink = int(shrink)
stepdim = stepdim*10 #enlarge to an increment below the last
stepdim = stepdim-shrink
stepdim = int(stepdim)
P2=graphics.Point(600,stepdim) #bottom right corner - ever shrinking
outsiderec=graphics.Rectangle(P1,P2) #
outsiderec.setFill(color_rgb(100, col, 0))
outsiderec.draw(window)
count= count + 1
count= int(count)
window.getMouse()
window.close()
I'm instead receiving one flat color.
I assume the problem is in my rand(int). I don't really know the ins and outs of it. Is it not running more than once?
Using your code as base I have tried to reproduce the expected result.
import graphics
from graphics import color_rgb
import random
window= graphics.GraphWin("x", 600, 400)
stripes = input("How many stripes should be on the flag")
stripes = int(stripes)
#count = 0
#count = int(count)
#P1=graphics.Point(0,0) #left corner - anchor point
stepdim = 400/stripes #size of divisions
for x in range(stripes): #loop for number of stripes
#col= random.randint(1,255)
#stepdim = int(stepdim)
#shrink = count*stepdim
#shrink = int(shrink)
#stepdim = stepdim*10 #enlarge to an increment below the last
#stepdim = stepdim-shrink
#stepdim = int(stepdim)
#P2=graphics.Point(600,stepdim) #bottom right corner - ever shrinking
P1=graphics.Point(0, stepdim * x) #left corner - anchor point
P2=graphics.Point(600,stepdim * (x + 1)) #bottom right corner - ever shrinking
outsiderec=graphics.Rectangle(P1,P2)
#outsiderec.setFill(color_rgb(100, col, 0))
red = random.randint(1, 255)
green = random.randint(1, 255)
blue = random.randint(1, 255)
outsiderec.setFill(color_rgb(red, green, blue))
outsiderec.draw(window)
#count= count + 1
#count= int(count)
window.getMouse()
window.close()
I have:
commented out all those statement that aren't needed
moved stepdim = 400/stripes from inside the loop to outside because you don't need to compute the same value for every loop
moved the P1=graphics.Point(0,0) inside the loop with a slight modification just to point to the top left corner of the stripe
modified the P2=graphics.Point(600,stepdim) to point to the bottom right corner of the stripe
added a random calculation for the three color components red = random.randint(1, 255), green = random.randint(1, 255), and blue = random.randint(1, 255)
Observations:
I have changed a little bit the way the stripes are drawn. Instead of drawing a shrunk version for every loop, the modified version just draws a fixed size stripe in consecutive positions.

Edge detection in Python

I am trying to write a program where a user enters a number, and it draws that many rectangles to the screen, however the triangles cannot overlap. I have had a problem with that last part, and I am looking for some help. I borrowed the edge detection methods from an Al Sweigart book, and the full program he wrote can be found here:
http://inventwithpython.com/chapter18.html
Here is the program I am working on:
http://pastebin.com/EQJVH6xr
import pygame, sys, random
from pygame.locals import *
def doRectsOverlap(rect1, rect2):
for a, b in [(rect1, rect2)]:
# Check if a's corners are inside b
if ((isPointInsideRect(a.left, a.top, b)) or
(isPointInsideRect(a.left, a.bottom, b)) or
(isPointInsideRect(a.right, a.top, b)) or
(isPointInsideRect(a.right, a.bottom, b))):
return True
return False
def isPointInsideRect(x, y, rect):
if (x > rect.left) and (x < rect.right) and (y > rect.top) and (y < rect.bottom):
return True
else:
return False
# set up pygame
pygame.init()
# set up the window
WINDOWWIDTH = 600
WINDOWHEIGHT = 600
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Rectangles')
# set up the colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
from random import choice
foo = [BLACK, RED, GREEN, BLUE]
# draw the background
windowSurface.fill(WHITE)
print('Please enter a number:')
number = input()
x = 0
array = []
for i in array:
while int(number) > x:
x = x+1
x1 = random.randint(1, 400)
y1 = random.randint(1, 400)
x2 = random.randint(1, 400)
y2 = random.randint(1, 400)
x3 = random.randint(1, 400)
y3 = random.randint(1, 400)
x4 = random.randint(1, 400)
y4 = random.randint(1, 400)
box = pygame.draw.rect(windowSurface,random.choice(foo), (x1, y1, x2, y2))
if doRectsOverlap(box, box) == False:
box
else:
x = x-1
# draw the window onto the screen
pygame.display.update()
Any help would be greatly appreciated. Thank you!
Well as a general answer, you are going to have to plot four co ordinance for each rectangle.
There are a few ways you can do this:
1) Just have the rectangle randomly placed and test if any of the new rectangle's points are inside of any of the existing rectangles. If they are, just keep generating until they are not. This will be very slow and inefficient though.
2) You can number crunch by restricting all of your possible random's to only available positions. This is can be done a variety of ways, it will be semi slow and probably fairly difficult to implement.
3) You can have the rectangles generate like in option 1, but in the case that the co-ordinance of the 4 points overlap, you can push the points off. To do this you simply have to set the violating co-ordinance to the co-ordinance of one of the corners and then add say, (5,5) or subtract or whatever. If you don't want to skew the rectangles too much you can regenerate the violating rectangle based on the modified point, or push all of the points an equivalent distance as the violating point.
I think option 3 is probably the best unless you are very strict on your random principles.
If you want me to clarify any of the above options let me know specifically what you want me to explain and I will do so. I can not however explain all of the possibilities for each option because it would take to long and way too many lines.
Cheers

Categories

Resources