Python skyline program: Write a program that uses turtle graphics to display a r
ID: 3684317 • Letter: P
Question
Python skyline program:
Write a program that uses turtle graphics to display a random skyline on the screen, similar in style to the two examples shown below: Your program should implement the following specifications:
• Exactly 6 buildings are drawn.
• The width of each building is randomly picked by the computer and must fall in the range 30-130 pixels, inclusive.
• The height of each building is randomly picked by the computer and must fall in the range 50-250 pixels, inclusive.
• Each building has a random color, but each color component (R, G, B) must be at least 0.5.
• Each building contains a grid of windows, each of which is 10x10 pixels in size and which is separated from neighboring pixels by 10 pixels.
• The number of rows and columns in the grid of windows must be proportional to the height and width (respectively) of a building.
• Each window is lit (yellow) or unlit (black) with a 50/50 percent chance.
• There is a 25% chance that a building has an antenna on top. The antenna must be centered, as in the examples above. The antenna must have two parts, To implement this program you must write a function named drawBuilding that takes five parameters, in this order:
• the x coordinate of the lower-left corner of the building
• the y coordinate of the lower-left corner of the building
• the width of the building
• the height of the building
• the fill_color of the building
Explanation / Answer
Python skyline program: The below program is simple and easy to understand.
from collections import defaultdict, namedtuple
from heapq import heappop, heappush
class Building:
def __init__(self, height):
self.height = height
self.finished = False
def __lt__(self, other):
# Reverse order by height, so that when we store buildings in
# a heap, the first building is the highest.
return other.height < self.height
# An event represents the buildings that start and end at a particular
# x-coordinate.
Event = namedtuple('Event', 'start end')
def skyline(buildings):
"""Given an iterable of buildings represented as triples (left, height,
right), generate the co-ordinates of the skyline.
>>> list(skyline([(1,9,3), (1,11,5), (2,6,7), (3,13,9), (12,7,16),
... (14,3,25), (19,18,22), (23,13,29), (24,4,28)]))
... # doctest: +NORMALIZE_WHITESPACE
[(1, 11), (3, 13), (9, 0), (12, 7), (16, 3), (19, 18), (22, 3),
(23, 13), (29, 0)]
>>> list(skyline([(1, 3, 2), (1, 3, 2)]))
[(1, 3), (2, 0)]
"""
# Map from x-coordinate to event.
events = defaultdict(lambda:Event(start=[], end=[]))
for left, height, right in buildings:
b = Building(height)
events[left].start.append(b)
events[right].end.append(b)
standing = [] # Heap of buildings currently standing.
last_h = 0 # Last emitted skyline height.
for x, event in sorted(events.items()): # Process events in order by x-coordinate
# Update buildings currently standing.
for b in event.start:
heappush(standing, b)
for b in event.end:
b.finished = True
# Pop any finished buildings from the top of the heap.
while standing and standing[0].finished:
heappop(standing)
# Top of heap (if any) is the highest standing building, so
# its height is the current height of the skyline.
h = standing[0].height if standing else 0
# Yield co-ordinates if the skyline height has changed.
if h != last_h:
yield x, h
last_h = h
Test Case:
>>> from timeit import timeit
>>> import random
>>> R = lambda n:random.randrange(n) + 1
>>> buildings = sorted((x, R(10000), x + R(1000)) for x in (R(10000) for _ in range(50000)))
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.