Diego Aaron
Diego Aaron

Reputation: 386

How to insert a line break in the write () function of the turtle module in Python?

As a practice I am generating bars using the turtle module in python.

Using the following code and achieved a simple bar graph but there is a detail that I would like to improve.

import turtle

def generaVentana():
    w = turtle.Screen()
    w.title("Ejercicio 7, 8")
    w.bgcolor("lightgreen")

    return w

def generaTortuga():
    t = turtle.Turtle()
    t.pensize(2)

    return t

wn = generaVentana()
tess = generaTortuga()

xs = [48, 117, -200, 240, 160, 260, 220]

def draw_bar(t, height):
    if (height < 100):
        t.color("black", "green")
    elif (height >= 100 and height < 200):
        t.color("black", "yellow")
    elif (height >= 200):
        t.color("black", "red")
    t.begin_fill()
    t.left(90)
    t.forward(height)
    t.right(90)
    t.write("   " + str(height))
    t.forward(40)
    t.right(90)
    t.forward(height)
    t.left(90)
    t.end_fill()
    t.penup()
    t.forward(10)
    t.pendown()

for v in xs:
    draw_bar(tess, v)

wn.mainloop()

When defining a bar with negative value it is generated but the size of the bar that is printed with the write () function I see that it is displayed on the inside of the bar.

imagen1

But I want it to be displayed on the outside of the bar.

imagen2

And tried to use in the code the line break tag "\n" concatenated with the value of the height returned string but it does not work.

There is some way to force this behavior, Thank you.

Upvotes: 2

Views: 2234

Answers (2)

cdlane
cdlane

Reputation: 41905

I would take control of your font size so you can move relative to the current font rather than estimating for the default font:

from turtle import Screen, Turtle

xs = [48, 117, -200, 240, 160, 260, 220]

FONT_SIZE = 12
FONT = ('Arial', FONT_SIZE, 'normal')

def generaVentana():
    screen = Screen()
    screen.title("Ejercicio 7, 8")
    screen.bgcolor("lightgreen")

    return screen

def generaTortuga():
    turtle = Turtle()
    turtle.pensize(2)
    turtle.penup()

    return turtle

def draw_bar(t, height):
    if height < 100:
        t.fillcolor("green")
    elif 100 <= height < 200:
        t.fillcolor("yellow")
    else:
        t.fillcolor("red")

    t.left(90)
    t.pendown()

    t.begin_fill()
    t.forward(height)
    t.right(90)
    t.forward(20)

    if height < 0:
        t.penup()
        position = t.position()  # save
        t.sety(t.ycor() - FONT_SIZE - t.pensize())

    t.write(height, align='center', font=FONT)

    if height < 0:
        t.setposition(position)  # restore
        t.pendown()

    t.forward(20)
    t.right(90)
    t.forward(height)
    t.end_fill()

    t.penup()
    t.left(90)
    t.forward(10)

wn = generaVentana()
tess = generaTortuga()

for value in xs:
    draw_bar(tess, value)

wn.mainloop()

enter image description here

Upvotes: 1

trincot
trincot

Reputation: 350841

The logic is that the text is written with the current turtle position as baseline, and so text always appears above that position.

When you are on the negative side, you would need to move some extra distance downward before writing the text. This is a bit cumbersome to do in the middle of a bar drawing operation, so I would separate the label printing from the bar drawing, like this:

def draw_bar(t, height):
    if height < 100:
        t.color("black", "green")
    elif height >= 100 and height < 200:
        t.color("black", "yellow")
    else: # no need to put a condition here
        t.color("black", "red")

    # add this block:
    t.left(90)
    p = t.position()
    t.penup()
    # when height is negative, move 14 more in that downward direction.
    t.forward(height - 14 * int(height < 0)) 
    t.write("   " + str(height))
    t.goto(p) 
    t.pendown()
    # end of added block

    t.begin_fill()
    # removed: t.left(90)
    t.forward(height)
    t.right(90)
    # removed: t.write("   " + str(height))
    t.forward(40)
    t.right(90)
    t.forward(height)
    t.left(90)
    t.end_fill()
    t.penup()
    t.forward(10)
    t.pendown()

BTW: the final elif is not needed, you can just do else. Also, you don't need parentheses around if conditions.

You might also want to consider centering the printed text to the center of the bar. Change this line:

t.write("   " + str(height))

to:

t.right(90)
t.forward(20) # move to (horizontal) center of bar
t.write(str(height), align="center")
t.left(90)

Upvotes: 1

Related Questions