Project 1 for CS151 introduced me to the basics of constructing and manipulating shapes on python, along with ways to break up the code to make it easier to follow, such as by defining functions. I first learned how to use python turtle to draw basic shapes, then how to render shape drawings more flexible by making their sizes adjustable, and finally how to make these adjustable shapes flexible enough to have any number of sides n (with n>3) and dimensions.
Creation of Shape A and B
For shapes A and B, I accessed python turtle by typing "from turtle import *", then indented and used commands forward(distance), left(angle), and right(angle) to draw basic shapes.To finish, I included the command "raw_input('Enter to continue')" to allow myself to view the completed turtle drawings by accessing my saved file via terminal.
To program the steps to draw the shapes, I simply visualized the steps needed to draw a cross (shape A) and an L (shape B), then told simple turtle do execute them. I paid attention to which way the arrow was facing on the simple turtle screen at the completion of a command to draw a straight line, then told it to go left or right a certain number of degrees (in this case, it was always 90 degrees) and draw forward another distance. In both cases, I made sure to adjust the distances forward according to what exact line on the shape I was drawing, since I wanted to make sure my shapes looked how I wanted them to (ex- making the "top" portion of the cross shorter than the "bottom" portion so the cross did not resemble a plus sign or an upside-down cross).
In summary, I visualized drawing the shapes to type in directions for simple turtle, then checked my work by executing my code using terminal and made adjustments as necessary.
Creation of Shape C (comprised of A and B)
To make Shape C, I first defined functions that created Shape A and Shape B. I also inserted a note using a # to keep track of which shape was which.
#makes the cross shape
Then, I created a function to define Shape C, which was comprised of shapes A and B. However, I did not simply write a simple definition including both functions.
Instead, I inserted steps to lift my pen between drawing the two, since I had a specific way I wanted shape B to fit with shape A, much like a Tetris puzzle. To do this, I wrote "up()" to lift the pen, inserted a series of commands to move the pen around the edge of shape A, then wrote "down()" to place the pen back down so I could then tell the program to draw Shape B in my desired location for the shape.
Finally, to execute my function for shapeC, I had to type
raw_input('Enter to continue')
at the end of my code.
Creation of Shape E (calls D multiple times with different parameters)
For the creation of Shape E, I created a function that defined a simple cross that resembled a plus sign, then added a parameter variable "distance" within the function to make the size of the cross adjustable.
After that, I defined a function shapeE(distance) that contained multiple crosses with different sizes, for instance shapeD(20) and shapeD(50). Since I had already defined Shape D, this new function just had to repeat the old function using different sizes.
To create Shape F, I added on a variety of additions to Shape E to create three colored crosses of different sizes layered around one another.
First, I decided to swap the simple cross shape used to create Shape F for the more complex cross shape used to create Shape A. To do so, I added different numbers to keep the cross shape design consistent with that of Shape A and yet still account for changing distances. So, I decided to simply add on numbers to the end of my commands, such as "forward(distance+50)."
Warning: This method works for crosses of small sizes, however, I would need to use a different method for crosses of extremely large sizes, as the distances I added are too small to maintain the proper shape of extremely large crosses. For example, for a cross of size 0 the "top" portion (above the horizontal part of the cross) would be half the size of the bottom portion and for size 50, it would be two thirds the size of the bottom portion.
top is 50, bottom is 100 for distance 0; top is 100, bottom is 150 for distance 50
Next, I defined the function for Shape F using parameters to account for the different sizes of the three crosses. I typed, "def shapeF(distance1,distance2,distance3)." I also widened the line drawn by each command and added colors.
Then, I embedded movements to arrange the crosses in such a way that they appeared to fit inside one another. I did so by drawing the shapes on paper, then trying to figure out what basic mathematical relationship I need to maintain between the shapes to ensure that there was no overlap and that the shapes' distances indicating their sizes could be placed in any order. This is what I came up with for the move between the first cross and the second:
For the move between the second cross and the third, I used to same steps but changed "distance2" and "distance1" to "distance3" and "distance2."
Finally, I put all these components in order, added some notes to organize my code, ended the program with shapeF(distance1,distance2,distance3), and inserted my own desired distances to run the program.
Shape F- one of the many possibilities
To make a polygon that could have any number of sides and any size, I looked through the python 2.7 standard library to find a function I could use. I found the function, "for i in range()," then decided to try to find a way to alter it to apply to my project.
I figured out that I could define my n-gon as:
for side in range(x):
The x represents the number of sides desired, and y represents the desired length of each side. The use of 360/x as my number of degrees accounts for the changing angles depending on how many sides the shape has.
After defining an ngon, I decided to make a function made up of repeated n-gons with decreasing numbers of sides because I though it would make for a good design.
N-gon Design using ngonrepeat(8,50)
After creating this design, I decided to modify my n-gon function further, so that the shapes could be layered with one another rather than simple stacked. I accomplished this by creating and inserting a move function into my definition of ngonrepeat. I also had to make sure to add the "distance" parameter to my newly altered function.
N-gon Design Using ngonrepeat(10,50,15)
At the end, I also added notes in the program pointing out that my program does not work for numbers less than 8, since it counts down by 5 sides and no shapes can be drawn with only one or two sides.
What I learned
Through this project, I learned some basic techniques to draw shapes using python's turtle application, including how to lift and put down the "pen" to draw, how to define simple functions and then compile them to make more complex functions, and how to create polygons of varying size and shape by using parameters. In addition to making concretely observable gains, I also made some internal gains in learning to think logically and make use of trial and error techniques to solve problems that arose during my project, such as when trying to consistently and symmetrically place one shape inside the lines of another to make Shape F.
Who I worked with
In class- Professor Dale Skrien
In lab- Professor Ying Li
Python 2.7 Standard Library
Link to colors found on Professor Skrien's moodle page: http://www.tcl.tk/man/tcl8.4/TkCmd/colors.htm