简体   繁体   中英

How to simplify my codes?

I wrote a program for a class using recursion to mimic certain kinds of simple branching structures like trees. I thought my code was great until I showed my professor. He told my code was too complicated and said I would need to simplify it. Besides spacing them out, I'm not sure what else I could do. Any tips? (I'm a beginner so go easy on me.) This program creates multiple trees with varying thickness, number of branch and at different coordinates.

import random 
import turtle
##I'm using a python module called turtle to visualize results
p1 = turtle.Pen()
##Creates a pen
p1.tracer(True)
## Shows pen drawing
p1.up()
p1.left(90)

d=random.randint(0,2)
## Varying thickness of branch
length=150
##Length of branches
contract=random.uniform(.5,1)
## Varying degree of contraction
branch=random.randint(5,8)
## Varying amount of branches
first=random.randint(30,70)
## Varying first degree of branch
next=random.randint(1,30)
## Varying degree between each branches
number1=random.randint(10,20)
number2=random.randint(-100,100)
number3=random.randint(-100,100)
# Range of numbers used for coordinates 
def drawFern1(pen, depth, length, contractBy, branches, firstBranchAngle, nextBranchAngle):
    if depth > 0:
       #Pen's Position and heading
       heading = pen.heading()
       position = pen.position()
       pen.width(depth)
       pen.forward(length)
       pen.left(firstBranchAngle)
       for i in range(branches):
        drawFern1(pen, depth-1, contractBy*length, contractBy,branches,firstBranchAngle,nextBranchAngle)
        pen.right(nextBranchAngle)
      pen.setheading(heading)
      pen.setposition(position)
# Ensures that multiple trees are created each at different coordinates. 
for i in range(number1):
   p1.sety(number2)
   p1.setx(number3)
   p1.down()
   drawFern1(p1,d,length,contract,branch,first,next)
   number2 = random.randint(-100,100)
   number3 = random.randint(-100,100)
   p1.up()

This code looks pretty solid to me, especially for a Python beginner. I've seen much worse.

If I were writing it, I think I'd calculate number2 and number3 only inside the main for loop - a priming definition as you have here is often convenient for a while loop, but not necessary in this case. I would also try to use more explanatory variable names, and depending on the problem statement I might require the randomly generated depth value to be at least 1 - if depth is generated as 0, nothing will be drawn.

My version of this would look like this:

import random 
import turtle

def drawFern(pen, depth, length, contraction, branches, firstBranchAngle, nextBranchAngle):
    if depth > 0:
        # Pen's Position and heading
        heading = pen.heading()
        position = pen.position()
        pen.width(depth)
        pen.forward(length)
        pen.left(firstBranchAngle)
        for i in xrange(branches):
            drawFern(pen, depth-1, contraction*length, contraction, branches, firstBranchAngle, nextBranchAngle)
            pen.right(nextBranchAngle)
        pen.setheading(heading)
        pen.setposition(position)

# I'm using a python module called turtle to visualize results
# Creates a pen
pen = turtle.Pen()
#  Shows pen drawing
pen.tracer(True)
pen.up()
pen.left(90)

# Configure initial state
# Varying depth of recursive fern
depth = random.randint(1,2)
# Length of branches
length = 150
# Varying degree of contraction
contraction = random.uniform(.5,1)
# Varying number of branches
branches = random.randint(5,8)
# Varying first degree of branch
first_angle = random.randint(30,70)
#  Varying degree between each branches
next_angle = random.randint(1,30)

number_of_trees =random.randint(10,20)

for i in xrange(number_of_trees):
    new_x = random.randint(-100, 100)
    new_y = random.randint(-100, 100)
    pen.setx(new_x)
    pen.sety(new_y)   
    pen.down()
    drawFern(pen, depth, length, contraction, branches, first_angle, next_angle)
    pen.up()

In addition to moving the x and y coordinate randomization into the main loop, moving the recursive function definition earlier in the file, and using some more explicit variable names, I've used xrange calls instead of range calls - a trivial optimization if you're on Python 2.x. If you're on Python 3, range is correct. But these are minor changes.

You could also throw in an if clause before the range(branches) loop to not even try if depth equals 1 - that's another minor optimization, although not one that will make a big difference.

I thought my code was great until I showed my professor. He told my code was too complicated and said I would need to simplify it.

This is rather complicated code given the quality of trees that it draws:

在此处输入图片说明

Drawing just vertical lines and blank screens are within the random parameters of the program as written! Let's rework the program to move some of the randomness from the static configuration code into the recursive routine itself. We'll also fine tune the random ranges a bit and clean up the code, primarily by eliminating variables that are only set and used once:

from random import randint, uniform
from turtle import Screen, Pen  # Using python turtle module to visualize results

# Configure initial state

DEPTH = randint(3, 4)  # Varying thickness and splitting of branches
LENGTH = randint(125, 150)  # Length of branches
CONTRACT_BY = uniform(0.4, 0.8)  # Varying degree of contraction

def drawFern(pen, depth, length, contractBy):
    if depth < 1:
        return

    # Save pen's position and heading
    heading = pen.heading()
    position = pen.position()

    pen.width(depth * 1.5)  # pen thickness depends on branching
    pen.forward(length)
    pen.left(randint(30, 70)) # Varying first degree of branch)

    for _ in range(randint(5, 8)):  # Varying amount of branches
        drawFern(pen, depth - 1, contractBy * length, contractBy)
        pen.right(randint(5, 30))  # Varying degree between each branches

    # Restore pen's Position and heading
    pen.setheading(heading)
    pen.setposition(position)

screen = Screen()

pen = Pen(visible=False)
pen.left(90)

screen.tracer(False)
# Ensure that multiple trees are created each at different coordinates.
for i in range(randint(10, 20)):
    pen.penup()
    pen.setposition(randint(-200, 200), randint(-300, 0))
    pen.pendown()
    drawFern(pen, DEPTH, LENGTH, CONTRACT_BY)
screen.tracer(True)

screen.mainloop()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM