4

My professor has asked our class to write a Python function that does as following:

Draw a regular n-pointed star with side d - in a function named star(turtle, n, d)

Here's the code that I have so far:

def star(turtle, n, d):
    angle = (180-((180*(n-2))/n))*2
    for i in range(n):
        t.forward(d)
        t.left(angle)
    return angle

The problem that I am experiencing is that my function is only able to draw stars with odd numbers of corners (5, 7, 9-sided stars). When I ask it to draw a star with an even number of sides, it outputs polygon with sides n/2. So asking to draw an 8-sided star outputs a square, 6-sided gives a triangle, and so forth.

I've tried altering the angle formula many times, but it never works with any given n.

Thanks for helping!

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
BryanLavinParmenter
  • 416
  • 1
  • 8
  • 20
  • I don't think there are any [regular star polygons](http://en.wikipedia.org/wiki/Star_polygon#Examples) with less than 5 sides. – martineau Oct 19 '14 at 21:12
  • I'm aware that there are not, but numbers like 6, 8, 10, and so forth do not work with the above formula. – BryanLavinParmenter Oct 19 '14 at 21:23
  • 1
    If there are an even number of sides, don't you need two disconnected lines? (Think the six-pointed star as two triangles) – mdurant Oct 19 '14 at 21:41

3 Answers3

3

You can draw most of the odd and even pointed stars with the same code by using a GCD routine to look for coprimes and treating failures as exceptions:

import sys
import turtle
from time import sleep

def gcd(a, b):
    while b != 0:
        a, b = b, a % b
    return a

def normal_star(size, color, points):
    if points <= 4:
        raise ValueError('Not enough points')

    turtle.color(color)

    for coprime in range(points // 2, 1, -1):
        if gcd(points, coprime) == 1:

            print("({},{})".format(points, coprime), file=sys.stderr)

            start = turtle.position()

            for _ in range(points):
                turtle.forward(size)
                turtle.left(360.0 / points * coprime)

            turtle.setposition(start)

            return

    abnormal_star(size, color, points)

def abnormal_star(size, color, points):
    # deal with special cases here
    print("Exception:", points, file=sys.stderr)

for points in range(5, 20):
    turtle.reset()
    normal_star(200, 'red', points)
    sleep(5)

turtle.exitonclick()

For points from 5 to 20, this only fails to find a solution for 6 which you'll need to treat as an exception, i.e. specialized code or just letting the user know it's an exception you can't handle:

> python3 test.py
(5,2)
Exception: 6
(7,3)
(8,3)
(9,4)
(10,3)
(11,5)
(12,5)
(13,6)
(14,5)
(15,7)
(16,7)
(17,8)
(18,7)
(19,9)
(20,9)
>

Output example for arguments 200,'red',10

enter image description here

cdlane
  • 40,441
  • 5
  • 32
  • 81
1

This code will draw a star with any number of points greater than 5. It takes two arguments: n is the number of vertices and size controls the size of the turtle's steps.

import turtle
turtle.showturtle()
turtle.shape("classic")

def turtle_star(n, size = 100):
    extent = 360 / n
    if n % 2 == 0:
        coords = []
        for a in range(0, n):
            turtle.penup()
            coords.append(turtle.pos())
            turtle.circle(size, extent)
        for b in range(0, len(coords)):
            if b % 2 == 0:
                turtle.pendown()
                turtle.goto(coords[b][0], coords[b][1])
            else:
                continue
        turtle.goto(coords[0][0], coords[0][1])
        turtle.penup()
        for c in range(0, (len(coords) + 1)):
            if c % 2 != 0:
                turtle.goto(coords[c][0], coords[c][1])
                turtle.pendown()
            else:
                continue
        turtle.goto(coords[1][0], coords[1][1])
    else:
        angle = 180 - (180 / n)
        for a in range(n):
            turtle.forward(size)
            turtle.right(angle)

turtle_star(11) (odd) and turtle(6) (even) shown below:

enter image description here

enter image description here

PatrickT
  • 10,037
  • 9
  • 76
  • 111
  • 1
    "any number of points greater than 5" seems to exclude odd numbers. For 7 and up, odd-wise, it just draws a line. It looks like it's missing a loop in the `else` clause. – cdlane Jun 09 '19 at 04:26
-1

Your formula is wrong a little:

def star(turtle, n, d):
    for i in range(n):
        angle = 180.0 - 180.0 / n
        turtle.forward(d)
        turtle.right(angle)
        turtle.forward(d)`
Huey
  • 5,110
  • 6
  • 32
  • 44
chabislav
  • 939
  • 1
  • 8
  • 27
  • This answer fails to address the OP's primary concern, "draw a star with an even number of sides". – cdlane Dec 26 '16 at 19:19