generated from mwc/lab_functions
252 lines
5.4 KiB
Python
252 lines
5.4 KiB
Python
#inductive vs deductive
|
|
#breaking complicated problem into simple problems
|
|
#when trying to recreate a brick wall, we can start brick by brick.
|
|
|
|
#if students are stuck, we fill in the gaps for them.
|
|
|
|
from turtle import *
|
|
|
|
#let's try making a brick... that shouldn't be too hard. It's a rectangle.
|
|
def brick():
|
|
forward(100)
|
|
right(90)
|
|
forward(20)
|
|
right(90)
|
|
forward(100)
|
|
right(90)
|
|
forward(20)
|
|
|
|
#"Functions" in code are like new words in our vocabulary. When we tell the turtle,
|
|
#"forward(100)", we are using the vocabulary in the "turtle" library.
|
|
#By using the words and definitions in the turtle library, we don't need to retype the long
|
|
#set of instructions behind the word "forward" each time we want to move the turtle.
|
|
#The code above *def*ines a new function, a new word that we can then use later.
|
|
#Notice that it doesn't do anything with the word yet, it just adds it to our vocabulary.
|
|
#To actually use the word (function), we must "call" it, like this:
|
|
|
|
#brick()
|
|
|
|
#You probably noticed that all of the code inside the definition is indented the same amount.
|
|
#This is how python knows which parts of your code are a part of the definition of the new word,
|
|
#and which parts aren't. We call these similarly indented structures, a "code block."
|
|
#Not all languages use indentention in this way, but with only rare exceptions, they all use
|
|
#codeblocks in some form.
|
|
|
|
#If we want to build a brick all, we will need to place bricks next to eachother...
|
|
|
|
def brick_row():
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
|
|
#brick_row()
|
|
|
|
#Q: What went wrong? A: We didn't put the turtle back in the same position as we found it.
|
|
def brick():
|
|
forward(100)
|
|
right(90)
|
|
forward(20)
|
|
right(90)
|
|
forward(100)
|
|
right(90)
|
|
forward(20)
|
|
right(90)
|
|
|
|
#brick_row()
|
|
|
|
#Now we need to stack rows of bricks on top of eachother, so we need to be below the previous row in the starting position
|
|
|
|
def next_row():
|
|
backward(500)
|
|
right(90)
|
|
forward(20)
|
|
left(90)
|
|
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
|
|
#It looks great, but each layer of bricks should be offset from those above and below it for maximum structural integrity.
|
|
|
|
def next_row():
|
|
backward(450)
|
|
right(90)
|
|
forward(20)
|
|
left(90)
|
|
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
#next_row()
|
|
#brick_row()
|
|
|
|
#it's close but the layers aren't quite lining up correctly... looking at a real brick wall, we see that each other layer starts with a half brick...
|
|
#don't forget to get the turtle back into the original orientation at the end!
|
|
|
|
def half_brick():
|
|
forward(50)
|
|
right(90)
|
|
forward(20)
|
|
right(90)
|
|
forward(50)
|
|
right(90)
|
|
forward(20)
|
|
right(90)
|
|
|
|
#We also need to now have different definition for the odd rows and the even rows.
|
|
#For reasons, we will consider the first row to be "row 0" and so it is therefore even.
|
|
#We will also want to change our "next_row" function so we stop slipping backwards
|
|
|
|
def next_row():
|
|
backward(400)
|
|
right(90)
|
|
forward(20)
|
|
left(90)
|
|
|
|
def even_row():
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
|
|
def odd_row():
|
|
half_brick()
|
|
forward(50)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
brick()
|
|
forward(100)
|
|
half_brick()
|
|
|
|
#even_row()
|
|
#next_row()
|
|
#odd_row()
|
|
|
|
#If we want to build a higher wall, we can now nest the previous code in another function,
|
|
#given that we have to make sure to set the turtle to the right position.
|
|
|
|
def two_rows_of_bricks():
|
|
even_row()
|
|
next_row()
|
|
odd_row()
|
|
backward(450)
|
|
right(90)
|
|
forward(20)
|
|
left(90)
|
|
|
|
#two_rows_of_bricks()
|
|
#two_rows_of_bricks()
|
|
|
|
#Notice that after each function, we have been careful to put the turtle back into something like
|
|
#a starting position, facing the same direction. Let's make this practice official, and promise
|
|
#to leave the turtle in the bottom left corner of whatver our functions draw.
|
|
|
|
#It's time to draw something else, perhaps a flower! Turtle has more words in it's vocabulary
|
|
#that you may or may not have seen before, like "circle()" for example. In this case, the number
|
|
#refers to the radius of the circle we want to draw:
|
|
|
|
#circle(30)
|
|
|
|
#We might build a rosette by turning slightly after each circle is drawn:
|
|
|
|
def rosette():
|
|
circle(30)
|
|
right(60)
|
|
circle(30)
|
|
right(60)
|
|
circle(30)
|
|
right(60)
|
|
circle(30)
|
|
right(60)
|
|
circle(30)
|
|
right(60)
|
|
circle(30)
|
|
right(60)
|
|
|
|
#rosette()
|
|
|
|
#Let's add a stem....
|
|
|
|
def stem():
|
|
right(90)
|
|
forward(100)
|
|
left(90)
|
|
|
|
#...and leaves...
|
|
|
|
def right_leaf():
|
|
left(90)
|
|
forward(50)
|
|
left(30)
|
|
forward(30)
|
|
left(150)
|
|
forward(50)
|
|
left(30)
|
|
forward(30)
|
|
left(60)
|
|
|
|
def left_leaf():
|
|
right(90)
|
|
forward(50)
|
|
right(30)
|
|
forward(30)
|
|
right(150)
|
|
forward(50)
|
|
right(30)
|
|
forward(30)
|
|
right(60)
|
|
|
|
#Let's put those leaves on the stem...
|
|
|
|
def stem():
|
|
right(90)
|
|
forward(100)
|
|
left_leaf()
|
|
right_leaf()
|
|
forward(100)
|
|
|
|
rosette()
|
|
stem()
|
|
penup()
|
|
home()
|
|
forward(100)
|
|
pendown()
|
|
two_rows_of_bricks()
|
|
two_rows_of_bricks()
|
|
two_rows_of_bricks()
|
|
two_rows_of_bricks()
|
|
two_rows_of_bricks()
|
|
two_rows_of_bricks()
|
|
|
|
input()
|