cs110_p1
1## DON"T OPEN THIS FILE! USE THE PURPLE BUTTON ON THE ASSIGNMENT 2## to see what functions are available and what their inputs are! 3 4################################################################### 5 6## PROCEED AT YOUR OWN RISK! THERE BE DRAGONS! 7 8_VERSION = "2025.1.1" 9 10## 2025.1.1 11# Feature: adds ability to fill the screen with the window 12# Feature: grid - add show_label param 13 14################################################################### 15### IGNORE EVERYTHING THAT STARTS WITH A _ 16from random import randint 17from math import sqrt, pi, radians, sin, cos, floor 18from time import sleep 19from tkinter import Tk, Canvas 20 21 22__docformat__ = "google" 23 24_a_canvas = None 25_resize_enabled = False 26 27 28Shape_Drawing_Functions = "" 29 30 31def arc(points=[], width=5, color="hot pink", line_steps=15, tag="", ): 32 """ 33 A reporter function that draws an arc ("curve") given a list of points. 34 Args: 35 points (`list`): The points outlining the curve; this should be a list of tuples (coordinates). 36 Make sure to give it at least 3 (x,y) coordinates that aren"t a straight line! 37 color (`str`): What color to make the shape. 38 tag (`str`): The tag to assign to the shape. 39 40 Returns: 41 `Shape`: The arc that was created. 42 """ 43 return _a_canvas.create_line( 44 points, 45 width=width, 46 fill=color, 47 splinesteps=line_steps, 48 smooth=True, 49 tags=tag, 50 , 51 ) 52 53 54def car(top_left=(0, 0), size=100, body_color="#3D9970", wheel_color="black", tag=""): 55 """ 56 Draws a cool car. 57 58 Args: 59 top_left (`tuple`): A coordinate at which to draw the car. 60 body_color (`str`): Color to make the body of the car. 61 wheel_color (`str`): Color to make the wheel of the car. 62 tag (`str`): The tag to assign to the shape. 63 """ 64 x, y = top_left 65 rectangle((x + 5 * size / 10, y), size, size / 10 * 4, color=body_color, tag=tag) 66 rectangle( 67 (x, y + size - 7 * size / 10), 68 size * 2, 69 size / 10 * 4.5, 70 color=body_color, 71 tag=tag, 72 ) 73 circle( 74 (x + 5 * size / 10, y + size - size / 5), size / 5, color=wheel_color, tag=tag 75 ) 76 circle( 77 (x + 15 * size / 10, y + size - size / 5), size / 5, color=wheel_color, tag=tag 78 ) 79 80 81def circle(center=(0, 0), radius=25, color="hot pink", outline="", tag="", ): 82 """ 83 A reporter function that draws a circle. 84 Args: 85 center (`tuple`): A coordinate representing the center of the shape. 86 radius (`int`): Specifies the circle"s radius. 87 color (`str`): What color to draw the shape. 88 outline (`str`): What color should the border of the shape be. 89 tag (`str`): The tag to assign to the shape. 90 91 Returns: 92 `Shape`: The circle that was created. 93 """ 94 return oval( 95 center=center, radius_x=radius, radius_y=radius, color=color, tag=tag, 96 ) 97 98 99def cloud(center=(0, 0), size=30, color="white", tag=""): 100 """ 101 Reporter function that draws a cloud to the screen. 102 Args: 103 center (`tuple`): the point on which to center the cloud 104 size (`int`): how big (roughly) the cloud is drawn 105 color (`str`): which determines the color of the cloud 106 tag (`str`): to give the cloud a name 107 108 Returns: 109 `Shape`: The cloud that was created. 110 """ 111 for i in range(10): 112 x_offset = randint((-1 * size * 1.333), (size * 1.333)) 113 y_offset = randint(0, (size * 0.667)) 114 circle( 115 center=(center[0] + x_offset, center[1] + y_offset), 116 radius=randint((size * 0.667), (size * 1.667)), 117 color=color, 118 tag=tag, 119 ) 120 return tag 121 122 123def diamond( 124 center=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 125): 126 """ 127 A reporter function that draws a rectangle. 128 Args: 129 center (`tuple`): A coordinate representing the center of the shape. 130 width (`int`): How wide to draw the shape. 131 height (`int`): How tall to draw the shape. 132 color (`str`): What color to draw the shape. 133 outline (`str`): What color should the border of the shape be. 134 tag (`str`): The tag to assign to the shape. 135 136 Returns: 137 `Shape`: The shape that was created. 138 """ 139 point_0 = (center[0] - width / 2, center[1]) 140 point_1 = (center[0], center[1] - height / 2) 141 point_2 = (center[0] + width / 2, center[1]) 142 point_3 = (center[0], center[1] + height / 2) 143 return _a_canvas.create_polygon( 144 point_0, 145 point_1, 146 point_2, 147 point_3, 148 fill=_safe_color(color), 149 tags=tag, 150 outline=outline, 151 , 152 ) 153 154 155def grid(width=None, height=None, interval=100, show_labels=True): 156 """ 157 Draws a grid on a screen with intervals of 100. 158 159 Args: 160 width (`int`): The width of the grid to draw (defaults to the whole window) 161 height (`int`): The height of the grid to draw (defaults to the whole window) 162 interval (`int`): The interval to draw the grid on. 163 show_labels (`bool`): Whether or not to show coordinate labels. 164 165 """ 166 167 if width is None 168 width = get_window_width() 169 170 if height is None 171 height = get_window_height() 172 173 # Creates all vertical lines at intervals of 100 174 for i in range(0, width, interval): 175 _a_canvas.create_line(i, 0, i, height, tag="grid", fill="black") 176 # Creates all horizontal lines at intervals of 100 177 for i in range(0, height, interval): 178 _a_canvas.create_line(0, i, width, i, tag="grid", fill="black") 179 180 if show_labels 181 # Creates axis labels 182 offset = 2 183 for y in range(0, height, interval): 184 for x in range(0, width, interval): 185 _a_canvas.create_oval( 186 x - offset, 187 y - offset, 188 x + offset, 189 y + offset, 190 fill="black", 191 tag="grid", 192 ) 193 _a_canvas.create_text( 194 x + offset, 195 y + offset, 196 text="({0}, {1})".format(x, y), 197 anchor="nw", 198 font=("Purisa", 8), 199 fill="black", 200 tag="grid", 201 ) 202 203 204_cache = [] 205 206 207def image(image_path, position=(200, 200), rotation=None, scale=None, tag="", ): 208 """ 209 Draws a given image on the screen. NOTE: Requires the `pillow` package to be installed - contact 210 Prof. Bain or post on edSTEM if you"d like more details! 211 212 Args: 213 image_path (`str`): Location of the image file on your computer. 214 position (`tuple`): A coordinate at which to render the image. 215 rotation (`int`): A number of degrees to rotate the given image. 216 scale (`int`): A scaling factor to multiply the image size by. 217 tag (`str`): A string representing the "name" fo this shape. 218 """ 219 # import PIL libraries 220 from PIL import Image, ImageTk 221 222 anchor = "nw" 223 224 import os 225 226 # 1. create PIL image and apply any image transformations: 227 dir_path = os.path.dirname(os.path.realpath(__file__)) 228 image_path = os.path.join(dir_path, image_path) 229 pil_image = Image.open(image_path) 230 if scale 231 size = (round(pil_image.size[0] * scale), round(pil_image.size[1] * scale)) 232 pil_image = pil_image.resize(size) 233 if rotation 234 pil_image = pil_image.rotate(rotation) # note: returns a copy 235 236 # 2. convert to tkinter-compatible image format: 237 tkinter_image = ImageTk.PhotoImage(pil_image) 238 _cache.append( 239 tkinter_image 240 ) # workaround for known tkinter bug: http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm 241 242 # 3. draw image on canvas: 243 _a_canvas.create_image( 244 *position, image=tkinter_image, anchor=anchor, tags=tag, 245 ) 246 247 248def line(points=[], curvy=False, color="hot pink", tag="", ): 249 """ 250 A reporter function that draws a line given a list of points. 251 Args: 252 points (`list`): The points that define the line; this should be a list of tuples (coordinates). 253 curvy (`bool`): Makes a curvy line instead. 254 color (`str`): What color to make the shape. 255 tag (`str`): The tag to assign to the shape. 256 257 Returns: 258 `Shape`: The line that was created. 259 """ 260 return _a_canvas.create_line(points, fill=color, smooth=curvy, tags=tag, ) 261 262 263def oval( 264 center=(0, 0), 265 radius_x=25, 266 radius_y=50, 267 color="hot pink", 268 outline="", 269 tag="", 270 , 271): 272 """ 273 A reporter function that draws an oval. 274 Args: 275 center (`tuple`): A coordinate representing the center of the shape. 276 radius_x (`int`): Specifies the oval"s radius on the x-axis. 277 radius_y (`int`): Specifies the oval"s radius on the y-axis. 278 color (`str`): What color to draw the shape. 279 outline (`str`): What color should the border of the shape be. 280 tag (`str`): The tag to assign to the shape. 281 282 Returns: 283 `Shape`: The oval that was created. 284 """ 285 x = center[0] 286 y = center[1] 287 x0, y0, x1, y1 = (x - radius_x, y - radius_y, x + radius_x, y + radius_y) 288 steps = 100 289 # major and minor axes 290 a = (x1 - x0) / 2.0 291 b = (y1 - y0) / 2.0 292 # center 293 xc = x0 + a 294 yc = y0 + b 295 point_list = [] 296 # create the oval as a list of points 297 for i in range(steps): 298 # Calculate the angle for this step 299 theta = (pi * 2) * (float(i) / steps) 300 x = a * cos(theta) 301 y = b * sin(theta) 302 point_list.append(round(x + xc)) 303 point_list.append(round(y + yc)) 304 305 return _a_canvas.create_polygon( 306 point_list, fill=_safe_color(color), tags=tag, 307 ) 308 309 310def pixel_art(top_left, artwork, palette, pixel=10, tag=""): 311 """ 312 Draws a pixel art design! 313 314 Args: 315 top_left (`tuple`): the top left coordinate of the pixel art 316 artwork (sequence of sequences): the art to draw 317 palette (sequence): the palette of colors to use for each different square 318 pixel (`int`, optional): how big each individual pixel should be 319 tag (`str`, optional): the tag to assign to every square in the row 320 321 Note: this doesn"t return anything so make sure to use a tag if you want to animate / modify. 322 """ 323 x = top_left[0] 324 y = top_left[1] 325 for row in artwork 326 # draw each row at the specified (x, y) position: 327 _draw_row(row, (x, y), colors=palette, pixel=pixel, tag=tag) 328 # ...and don"t forget to shift the y-value down by the proper 329 # amount so that the next row won"t draw on top of the first one: 330 y += pixel 331 332 333def polygon(points=[], color="hot pink", outline="", tag="", ): 334 """ 335 A reporter function that draws a polygon given a list of points. 336 Args: 337 points (`list`): The points outlining the polygon; this should be a list of tuples (coordinates). 338 defaults to an empty list. 339 outline (`str`): What color should the border of the shape be. 340 color (`str`): What color to make the shape. 341 342 Returns: 343 `Shape`: The polygon that was created. 344 """ 345 return _a_canvas.create_polygon(points, fill=_safe_color(color), tags=tag, ) 346 347 348def rectangle( 349 top_left=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 350): 351 """ 352 A reporter function that draws a rectangle. 353 Args: 354 top_left (`tuple`): A coordinate representing the top left-hand corner of the shape. 355 width (`int`): How wide to draw the shape. 356 height (`int`): How tall to draw the shape. 357 color (`str`): What color to draw the shape. 358 outline (`str`): What color should the border of the shape be. 359 tag (`str`): The tag to assign to the shape. 360 361 Returns: 362 `Shape`: The rectangle that was created. 363 """ 364 point_0 = top_left 365 point_1 = (top_left[0] + width, top_left[1]) 366 point_2 = (top_left[0] + width, top_left[1] + height) 367 point_3 = (top_left[0], top_left[1] + height) 368 return _a_canvas.create_polygon( 369 point_0, point_1, point_2, point_3, fill=_safe_color(color), tags=tag, 370 ) 371 372 373def spiral( 374 center=(0, 0), width=100, roughness=0.01, start=0, spirals=5, line_width=1, 375): 376 """ 377 A reporter function that draws a spiral. 378 Args: 379 center (`tuple`): A coordinate representing the center of the shape. 380 width (`int`): Specifies the total width of the spiral. 381 roughness (`float`): Controls how spiral-y the shape is (lower is less spiral-y) 382 start (`int`): Where on the spiral to start drawing. 383 spirals (`int`): How many loops to draw. 384 line_width (`int`): How wide for the line to be drawn. 385 tag (`str`): The tag to assign to the shape. 386 387 Returns: 388 `Shape`: The spiral that was created. 389 """ 390 theta = 0.0 391 r = start 392 all_points = [] 393 prev_pos = _polar_to_cartesian(r, theta) 394 distance = width / 4 / pi / spirals 395 all_points.append((prev_pos[0] + center[0], prev_pos[1] + center[1])) 396 while theta < 2 * spirals * pi 397 theta += roughness 398 r = start + distance * theta 399 pos = _polar_to_cartesian(r, theta) 400 all_points.append((pos[0] + center[0], pos[1] + center[1])) 401 402 return arc(points=all_points, width=line_width, ) 403 404 405def square(top_left=(0, 0), size=25, color="hot pink", outline="", tag="", ): 406 """ 407 A reporter function that draws a square. 408 Args: 409 top_left (`tuple`): A coordinate representing the top left-hand corner of the shape. 410 size (`int`): How big to draw the shape. 411 color (`str`): What color to draw the shape. 412 outline (`str`): What color should the border of the shape be. 413 tag (`str`): The tag to assign to the shape. 414 415 Returns: 416 `Shape`: The square that was created. 417 """ 418 return rectangle( 419 top_left=top_left, width=size, height=size, color=color, tag=tag, 420 ) 421 422 423def star( 424 center=(0, 0), 425 radius=50, 426 color="hot pink", 427 outer_radius=75, 428 points=5, 429 outline="", 430 tag="", 431 , 432): 433 """ 434 A reporter function that draws a star. 435 Args: 436 center (`tuple`): A coordinate representing the center of the shape. 437 radius (`int`): Specifies the radius of the inside part of the star. 438 color (`str`): Specifies the color of the star. 439 outer_radius (`int`): Specifies the radius of the outside part of the star. 440 points (`int`): Specifies the number of points for the star. 441 outline (`str`): What color should the border of the shape be. 442 tag (`str`): The tag to assign to the shape. 443 444 Returns: 445 `Shape`: The star that was created. 446 """ 447 arc_segment = 360 / points 448 vertices = [] 449 for i in range(points): 450 inner_point = ( 451 radius * cos(radians(arc_segment * i)) + center[0], 452 -1 * radius * sin(radians(arc_segment * i)) + center[1], 453 ) 454 vertices.append(inner_point) 455 outer_point = ( 456 outer_radius * cos(radians(arc_segment * i + arc_segment / 2)) + center[0], 457 -1 * outer_radius * sin(radians(arc_segment * i + arc_segment / 2)) 458 + center[1], 459 ) 460 vertices.append(outer_point) 461 return polygon(vertices, color=color, tag=tag, ) 462 463 464def text( 465 top_left=(0, 0), text="", font=("Purisa", 32), color="black", tag="", 466): 467 """ 468 A reporter function that draws text to the screen 469 Args: 470 top_left (`tuple`): coordinate pair to specify the location. 471 text (`str`): What text to draw. 472 font (`tuple`): A tuple where the first element is a string for the font name and the second is an 473 int with the font size. 474 color (`str`): What color should the text be. 475 tag (`str`): The name to tag this thing with. 476 477 Returns: 478 `Shape`: The text that was created. 479 """ 480 return _a_canvas.create_text( 481 top_left, text=text, font=font, fill=color, tags=tag, 482 ) 483 484 485def triangle( 486 bottom_center=(0, 0), 487 width=25, 488 top_shift=0, 489 height=0, 490 color="hot pink", 491 outline="", 492 tag="", 493 , 494): 495 """ 496 A reporter function that draws a triangle. 497 Args: 498 bottom_center (`tuple`): A coordinate representing the bottom center of the shape. 499 width (`int`): Specifies the width of the base of the triangle. 500 top_shift (`int`): Specifies the how far to the left or right to shift the top of 501 the triangle from the bottom center. 502 height (`int`): Specifies the triangle"s height. 503 color (`str`): What color to draw the shape. 504 outline (`str`): What color should the border of the shape be. 505 tag (`str`): The tag to assign to the shape. 506 507 Returns: 508 `Shape`: The triangle that was created. 509 """ 510 if height == 0 511 height = width * sqrt(3) / 2 512 point_0 = (bottom_center[0] - width / 2, bottom_center[1]) 513 point_1 = (bottom_center[0] + width / 2, bottom_center[1]) 514 point_2 = (bottom_center[0] + top_shift, bottom_center[1] - height) 515 516 return _a_canvas.create_polygon( 517 point_0, point_1, point_2, fill=_safe_color(color), tags=tag, 518 ) 519 520 521def wedge( 522 center=(0, 0), radius=25, angle=180, color="hot pink", outline="", tag="", 523): 524 """ 525 A reporter function that draws a circle. 526 Args: 527 center (`tuple`): A coordinate representing the center of the shape. 528 radius (`int`): Specifies the circle"s radius. 529 angle (`int`): A number between 0 and 360 that specifies how much of the circle to draw. 530 color (`str`): What color to draw the shape. 531 outline (`str`): What color should the border of the shape be. 532 tag (`str`): The tag to assign to the shape. 533 534 Returns: 535 `Shape`: The wedge that was created. 536 """ 537 point_list = [center[0], center[1]] 538 for i in range(0, 0 + angle): 539 x1 = center[0] + radius * cos(radians(i)) 540 point_list.append(x1) 541 y1 = center[1] + radius * sin(radians(i)) 542 point_list.append(y1) 543 544 point_list.append(center[0]) 545 point_list.append(center[1]) 546 547 return _a_canvas.create_polygon( 548 point_list, fill=_safe_color(color), outline=outline, tags=tag, 549 ) 550 551 552Shape_Modifier_Functions = "" 553 554 555def above(shape1, shape2, offset_x=0, offset_y=0): 556 """ 557 A reporter function that places shape1 above shape2 (vertically). It does this by moving shape 1"s center 558 to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any 559 specified offset. 560 561 Args: 562 shape1 (`Shape` or Tag): The first shape to use. 563 shape2 (`Shape` or Tag): The second shape to use. 564 offset_x (`int`): How much to shift shape 2 in the x-direction after moving it. 565 offset_y (`int`): How much to shift shape 2 in the x-direction after moving it. 566 567 Returns: 568 `Shape`: The modified shape1. 569 """ 570 overlay(shape1, shape2) 571 _a_canvas.move( 572 shape1, 573 0 + offset_x, 574 -1 * (get_height(shape2) + get_height(shape1)) / 2 + offset_y, 575 ) 576 return shape1 577 578 579def align(shape1, shape2, via="middle", offset_x=0, offset_y=0): 580 """ 581 A reporter function that aligns `shape1` with `shape2`. It does this by moving `shape1` to align with 582 whatever property of `shape2` is selected with the `via` input. 583 584 Args: 585 shape1 (`Shape` or Tag): The first shape to use. 586 shape2 (`Shape` or Tag): The second shape to use. 587 via (`str`): Has to be one of, the following options: `"center"` (horizontal center), 588 `"middle"` (vertical center), `"top"`, `"bottom"`, `"left"`, or `"right"` 589 offset_x (`int`): How much to shift in the x-axis after alignment 590 offset_y (`int`): How much to shift in the y-axis after alignment 591 592 Returns: 593 `Shape`: The modified shape1. 594 """ 595 via_options = ["center", "middle", "top", "bottom", "left", "right"] 596 if via not in via_options 597 raise ValueError( 598 "The via input must be one of " 599 + (via_options) 600 + " but instead we found " 601 + (via) 602 ) 603 604 outline1 = _get_outline(shape1) 605 outline2 = _get_outline(shape2) 606 607 if via == "center" 608 _a_canvas.move( 609 shape1, (outline2["center"][0] - outline1["center"][0]) + offset_x, offset_y 610 ) 611 612 elif via == "middle" 613 _a_canvas.move( 614 shape1, offset_x, (outline2["center"][1] - outline1["center"][1]) + offset_y 615 ) 616 617 elif via == "top" 618 _a_canvas.move(shape1, offset_x, (outline2["top"] - outline1["top"]) + offset_y) 619 620 elif via == "bottom" 621 _a_canvas.move( 622 shape1, offset_x, (outline2["bottom"] - outline1["bottom"]) + offset_y 623 ) 624 625 elif via == "left" 626 _a_canvas.move( 627 shape1, (outline2["left"] - outline1["left"]) + offset_x, offset_y 628 ) 629 630 elif via == "right" 631 _a_canvas.move( 632 shape1, (outline2["right"] - outline1["right"]) + offset_x, offset_y 633 ) 634 635 return shape1 636 637 638def beside(shape1, shape2, offset_x=0, offset_y=0): 639 """ 640 A reporter function that places shape1 beside shape2 (horizontally). It does this by moving shape 1"s center 641 to shape 2"s center, moving shape 1 in the x-direction the exact width of shape 2, and then applying any 642 specified offset. 643 644 Args: 645 shape1 (`Shape` or Tag): The first shape to use. 646 shape2 (`Shape` or Tag): The second shape to use. 647 offset_x (`int`): How much to shift shape 2 in the x-direction after moving it. 648 offset_y (`int`): How much to shift shape 2 in the x-direction after moving it. 649 650 Returns: 651 `Shape`: The modified shape1. 652 """ 653 overlay(shape1, shape2) 654 _a_canvas.move( 655 shape1, 656 (get_width(shape2) + get_width(shape1)) / 2 + offset_x, 657 0 + offset_y, 658 ) 659 return shape1 660 661 662def below(shape1, shape2, offset_x=0, offset_y=0): 663 """ 664 A reporter function that places shape1 below shape2 (vertically). It does this by moving shape 1"s center 665 to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any 666 specified offset. 667 668 Args: 669 shape1 (`Shape` or Tag): The first shape to use. 670 shape2 (`Shape` or Tag): The second shape to use. 671 offset_x (`int`): How much to shift shape 2 in the x-direction after moving it. 672 offset_y (`int`): How much to shift shape 2 in the x-direction after moving it. 673 674 Returns: 675 `Shape`: The modified shape1. 676 """ 677 overlay(shape1, shape2) 678 _a_canvas.move( 679 shape1, 680 0 + offset_x, 681 (get_height(shape2) + get_height(shape1)) / 2 + offset_y, 682 ) 683 return shape1 684 685 686def change_color(shape, color): 687 """ 688 Change the fill color of a tagged object. 689 690 Args: 691 shape (`Shape` or Tag): The shape or tag to re-fill. 692 color (`str`): A color name or hex code to re-fill with. 693 """ 694 ids = _a_canvas.find_withtag(shape) 695 for id in ids 696 _a_canvas.itemconfig(id, fill=color) 697 698 699def delete(shape): 700 """ 701 A function that deletes a shape from our screen. 702 703 Args: 704 shape (`Shape` or Tag): The shape to delete. 705 """ 706 _a_canvas.delete(shape) 707 708 709def duplicate(shape, color=None): 710 """ 711 A reporter function that perfectly copies a shape and returns that copy. 712 713 Args: 714 shape (`Shape` or Tag): The shape to duplicate. 715 color (`str`): A new color to use with the duplicated shape. 716 717 Returns: 718 `Shape`: The new duplicated shape. 719 """ 720 shape_type = _a_canvas.type(shape) 721 shape_config = _a_canvas.itemconfig(shape) 722 shape_coords = _a_canvas.coords(shape) 723 the_copy = None 724 if shape_type == "polygon" 725 new_config = {key shape_config[key][-1] for key in shape_config.keys()} 726 if color != None 727 new_config["fill"] = color 728 the_copy = _a_canvas.create_polygon(shape_coords, new_config) 729 return the_copy 730 731 732def mirror(shape): 733 """ 734 A function that takes a shape and flips it across its vertical 735 axis, returning the modified shape. 736 737 Args: 738 shape (`Shape` or Tag): The shape in question. 739 740 """ 741 center = get_center(shape)[0] 742 shape_ids = _a_canvas.find_withtag(shape) 743 for shape_id in shape_ids 744 flipped_coordinates = [] 745 shape_coords = _a_canvas.coords(shape_id) 746 counter = 0 747 for num in shape_coords 748 if counter % 2 == 0 749 if num < center 750 flipped_coordinates.append(num + 2 * (center - num)) 751 elif num > center 752 flipped_coordinates.append(num - 2 * (num - center)) 753 else 754 flipped_coordinates.append(num) 755 else 756 flipped_coordinates.append(num) 757 counter += 1 758 _a_canvas.coords(shape_id, flipped_coordinates) 759 760 761def move(shape, x_shift=0, y_shift=0): 762 """ 763 Purpose: Move the x and y position of all shapes that have been tagged 764 with the tag argument 765 766 Args: 767 shape (`Shape` or Tag): The shape in question. 768 x_shift (`int`; optional): amount to move in the x direction 769 y_shift (`int`; optional): amount to move in the y direction 770 """ 771 shape_ids = _a_canvas.find_withtag(shape) 772 for id in shape_ids 773 _a_canvas.move(id, x_shift, y_shift) 774 775 776def move_to(tag, to, anchor="center"): 777 """ 778 Move the given tagged item to a particular `point` maintaining some `anchor`. 779 Note: this is NOT the same as the `move` function which moves an object by a specific amount. 780 781 Args: 782 tag (Shape or `str`): the shape (or shapes) to move 783 to (`tuple`): the `(x, y)` coordinate to which you wish to move the tagged object 784 anchor (`str`): which point on the shape do you want to move toward the given tuple. You can 785 use either `"center"` (default), `"top_left"`, `"top_right"`, `"bottom_left"`, or `"bottom_right"`. 786 """ 787 anchor_options = ["center", "top_left", "top_right", "bottom_left", "bottom_right"] 788 if anchor not in anchor_options 789 raise ValueError( 790 "The anchor input must be one of " 791 + (anchor_options) 792 + " but instead we found " 793 + (anchor) 794 ) 795 796 outline = _get_outline(tag) 797 delta_x = 0 798 delta_y = 0 799 800 if anchor == "top_left" 801 delta_x = to[0] - outline["left"] 802 delta_y = to[1] - outline["top"] 803 elif anchor == "top_right" 804 delta_x = to[0] - outline["right"] 805 delta_y = to[1] - outline["top"] 806 elif anchor == "bottom_right" 807 delta_x = to[0] - outline["right"] 808 delta_y = to[1] - outline["bottom"] 809 elif anchor == "bottom_left" 810 delta_x = to[0] - outline["left"] 811 delta_y = to[1] - outline["bottom"] 812 elif anchor == "center" 813 delta_x = to[0] - outline["center"][0] 814 delta_y = to[1] - outline["center"][1] 815 816 _a_canvas.move(tag, delta_x, delta_y) 817 818 819def overlay(shape1, shape2, offset_x=0, offset_y=0): 820 """ 821 A reporter function that overlays shape1 onto shape2. It does this by moving shape 1"s center 822 to shape 2"s center, and then applying any specified offset. 823 Args: 824 shape1 (`Shape` or Tag): The first shape to use. 825 shape2 (`Shape` or Tag): The second shape to use. 826 offset_x (`int`): How much to shift shape 2 in the x-direction after centering it. 827 offset_y (`int`): How much to shift shape 2 in the x-direction after centering it. 828 829 Returns: 830 `Shape`: The modified shape1. 831 """ 832 center1 = get_center(shape1) 833 center2 = get_center(shape2) 834 _a_canvas.move( 835 shape1, 836 (center2[0] - center1[0]) + offset_x, 837 (center2[1] - center1[1]) + offset_y, 838 ) 839 _a_canvas.tag_raise(shape1, shape2) 840 return shape1 841 842 843def portion(shape, start=0, end=0.5): 844 """ 845 Purpose: Take a slice or portion of some already created shape. 846 847 Args: 848 shape (`Shape` or Tag): The shape to take a portion of 849 start (`float`): A number between 0 and 1 representing where to start the slice. 850 end (`float`): A number between 0 and 1 representing where to end the slice. 851 852 For example, taking a portion from 0 to 0.5 of a circle would result in a semi-circle. 853 854 Note: this function is experimental. It might produce unexpected results! 855 """ 856 all_shapes = _a_canvas.find_withtag(shape) 857 858 for a_shape in all_shapes 859 coords = _a_canvas.coords(a_shape) 860 861 start_coord = floor(start * len(coords)) 862 if start_coord % 2 == 1 863 start_coord = start_coord - 1 # need to start with an x,y pair 864 end_coord = floor(end * len(coords)) 865 if end_coord % 2 == 1 866 end_coord = end_coord - 1 # need to end with an x,y pair 867 868 # slice is up to not including so get the last x,y pair 869 new_coords = coords[start_coord end_coord + 2] 870 871 # loop shape back in on itself 872 new_coords.append(new_coords[0]) 873 new_coords.append(new_coords[1]) 874 875 # set the coordinates: 876 _a_canvas.coords(a_shape, new_coords) 877 878 879def put_in_back(shape): 880 """ 881 A function that "lowers" a shape to the "bottom" of the screen." 882 883 Args: 884 shape (`Shape` or Tag): The shape in question. 885 """ 886 _a_canvas.tag_lower(shape) 887 888 889def put_in_front(shape): 890 """ 891 A function that "raises" a shape to the "top" of the screen." 892 893 Args: 894 shape (`Shape` or Tag): The shape in question. 895 """ 896 _a_canvas.tag_raise(shape) 897 898 899def rotate(shape, degrees=5, origin=None): 900 """ 901 A reporter function that takes a shape and rotates it by a specified amount around a specified point. 902 It does this by interpolating a polygon around the shape and calculating the shifts of individual 903 points on the edge of the polygon. 904 905 Args: 906 shape (`Shape` or Tag): The shape to rotate. 907 degrees (`int`): The number of degrees to rotate the shape. 908 origin (`tuple`): An `(x,y)` coordinate about which to perform the rotation. Defaults to the center 909 of the given shape. 910 911 Returns: 912 `Shape`: The modified shape. 913 """ 914 if origin is None 915 origin = get_center(shape) 916 917 theta = radians(degrees) 918 ox, oy = origin 919 920 all_shapes = _a_canvas.find_withtag(shape) 921 922 for a_shape in all_shapes 923 coords = _a_canvas.coords(a_shape) 924 # update coordinates: 925 for i in range(0, len(coords), 2): 926 px, py = coords[i], coords[i + 1] 927 qx = cos(theta) * (px - ox) - sin(theta) * (py - oy) + ox 928 qy = sin(theta) * (px - ox) + cos(theta) * (py - oy) + oy 929 coords[i] = qx 930 coords[i + 1] = qy 931 # set the coordinates: 932 _a_canvas.coords(a_shape, coords) 933 934 return shape 935 936 937def scale(shape, x_scale=1.0, y_scale=1.0): 938 """ 939 A function that takes a given `Shape` or tag and scales it on either/both the x and y-axis. 940 941 The two optional inputs accept floats between 0.0 and 1.0. Values greater than 1 will cause 942 the shape to grow along that access. Values less than 1.0 will cause the shape to shrink. 943 944 Args: 945 shape (`Shape` or Tag): The shape or tag to re-fill. 946 x_scale (`float`): How much to scale in the x-axis. 947 y_scale (`float`): How much to scale in the y-axis. 948 """ 949 ids = _a_canvas.find_withtag(shape) 950 951 coord = get_center(shape) 952 953 for i in ids 954 _a_canvas.scale(i, coord[0], coord[1], x_scale, y_scale) 955 956 957def underlay(shape1, shape2, offset_x=0, offset_y=0): 958 """ 959 A reporter function that underlays shape1 beneath shape2. It does this by moving shape 1"s center 960 to shape 2"s center, and then applying any specified offset. 961 Args: 962 shape1 (`Shape` or Tag): The first shape to use. 963 shape2 (`Shape` or Tag): The second shape to use. 964 offset_x (`int`): How much to shift shape 2 in the x-direction after centering it. 965 offset_y (`int`): How much to shift shape 2 in the x-direction after centering it. 966 967 Returns: 968 `Shape`: The modified shape1. 969 """ 970 center1 = get_center(shape1) 971 center2 = get_center(shape2) 972 _a_canvas.move( 973 shape1, 974 (center2[0] - center1[0]) + offset_x, 975 (center2[1] - center1[1]) + offset_y, 976 ) 977 _a_canvas.tag_lower(shape1, shape2) 978 return shape1 979 980 981Utility_Functions = "" 982 983 984def clear_window(keep_grid=True): 985 """ 986 A function that deletes everything from the window. 987 988 Args: 989 keep_grid (`bool`): Whether or not to keep the grid. 990 """ 991 all_shapes = _a_canvas.find_all() 992 993 for shape in all_shapes 994 tags = _a_canvas.gettags(shape) 995 if "grid" in tags and keep_grid 996 continue 997 _a_canvas.delete(shape) 998 999 global _resize_enabled 1000 _resize_enabled = True 1001 1002 1003def distance(point1, point2): 1004 """ 1005 A reporter function calculates the distance between two `(x, y)` coordinates. 1006 1007 Args: 1008 point1 (`tuple`): The first `(x, y)` coordinate. 1009 point2 (`tuple`): The second `(x, y)` coordinate. 1010 1011 Returns: 1012 A `float` representing the distance between the two points. 1013 """ 1014 return sqrt(((point1[0] - point2[0]) 2) + ((point1[1] - point2[1]) 2)) 1015 1016 1017def does_tag_exist(tag): 1018 """ 1019 Returns `True` if a given tag exists otherwise returns `False`. 1020 1021 Args: 1022 `tag` (`str`): [Required] The tag of the object to lookup. 1023 1024 """ 1025 result = _a_canvas.find_withtag(tag) 1026 1027 if result 1028 return True 1029 else 1030 return False 1031 1032 1033def get_bottom(shape): 1034 """ 1035 A reporter function calculates the maximum y-value of a given shape (since the y-axis is flipped). 1036 1037 Args: 1038 shape (`Shape` or Tag): The shape in question. 1039 1040 Returns: 1041 A `int` representing the maximum y-coordinate of the shape. 1042 """ 1043 bbox = _safe_bbox(shape) 1044 return bbox[3] 1045 1046 1047def get_center(shape): 1048 """ 1049 A reporter function calculates the a coordinate at the center of some shape. 1050 1051 Args: 1052 shape (`Shape` or Tag): The shape in question. 1053 1054 Returns: 1055 A `tuple` representing center of the given shape. 1056 """ 1057 bbox = _safe_bbox(shape) 1058 1059 if bbox is None 1060 raise Exception( 1061 f"We couldn"t find the shape with id/tag {shape}. Make sure it exists!" 1062 ) 1063 1064 return (((bbox[2] + bbox[0]) / 2), ((bbox[1] + bbox[3]) / 2)) 1065 1066 1067def get_colors(shape_or_shapes): 1068 """ 1069 A reporter function that returns all the colors associated with a tag or list of tags. 1070 1071 Args: 1072 shape_or_shapes (`str`/`Shape` or `List`): the shape/tag or list of shapes/tags you"d like to find the colors of 1073 1074 Returns: 1075 A `List` containing all unique colors associated with that tag(s) 1076 """ 1077 all_shapes = [] 1078 if not isinstance(shape_or_shapes, ): 1079 shape_or_shapes = [shape_or_shapes] 1080 for shape in shape_or_shapes 1081 all_shapes += _a_canvas.find_withtag(shape) 1082 1083 all_colors = [] 1084 for shape in all_shapes 1085 color = _a_canvas.itemcget(shape, "fill") 1086 if color not in all_colors 1087 all_colors.append(color) 1088 1089 return all_colors 1090 1091 1092def get_height(shape): 1093 """ 1094 A reporter function calculates the height of some given shape. 1095 1096 Args: 1097 shape (`Shape` or Tag): The shape in question. 1098 1099 Returns: 1100 A `int` representing the height of the shape. 1101 """ 1102 bbox = _safe_bbox(shape) 1103 return bbox[3] - bbox[1] - 1 1104 1105 1106def get_left(shape): 1107 """ 1108 A reporter function calculates the minimum x-value of a given shape. 1109 1110 Args: 1111 shape (`Shape` or Tag): The shape in question. 1112 1113 Returns: 1114 A `int` representing the minimum x-coordinate of the shape. 1115 """ 1116 bbox = _safe_bbox(shape) 1117 return bbox[0] 1118 1119 1120def get_right(shape): 1121 """ 1122 A reporter function calculates the maximum x-value of a given shape. 1123 1124 Args: 1125 shape (`Shape` or Tag): The shape in question. 1126 1127 Returns: 1128 A `int` representing the maximum x-coordinate of the shape. 1129 """ 1130 bbox = _safe_bbox(shape) 1131 return bbox[2] 1132 1133 1134def get_tag_from_event(event, precision=25): 1135 """ 1136 Tries to return a tag of an object at a given mouse-event. 1137 1138 Args: 1139 event (`Event`): Must be a mouse event otherwise we"ll give back an error. 1140 precision (`int`): How precise in number of pixels does a user have be in order to "select" an object 1141 1142 Returns a blank string `""` if no shapes are found closer than `precision`. 1143 """ 1144 1145 if (event.type) not in [4, 6]: 1146 raise Exception(f"Received an event that isn"t a mouse event: {event}") 1147 1148 try 1149 x = event.x 1150 y = event.y 1151 shape_id = _a_canvas.find_closest(x, y) # get the top shape 1152 if shape_id and distance(get_center(shape_id), (x, y)) < precision 1153 tags = _a_canvas.gettags(shape_id) 1154 if len(tags) > 0 1155 return tags[0] 1156 return "" 1157 1158 except 1159 raise Exception( 1160 "No tag found! Maybe you passed us an event that isn"t a mouse event?" 1161 ) 1162 1163 1164def get_top(shape): 1165 """ 1166 A reporter function calculates the minimum y-value of a given shape (since the y-axis is flipped). 1167 1168 Args: 1169 shape (`Shape` or Tag): The shape in question. 1170 1171 Returns: 1172 A `int` representing the minimum y-coordinate of the shape. 1173 """ 1174 bbox = _safe_bbox(shape) 1175 return bbox[1] 1176 1177 1178def get_width(shape): 1179 """ 1180 A reporter function calculates the width of some given shape. 1181 1182 Args: 1183 shape (`Shape` or Tag): The shape in question. 1184 1185 Returns: 1186 An `int` representing width of the shape. 1187 """ 1188 bbox = _safe_bbox(shape) 1189 return bbox[2] - bbox[0] - 1 1190 1191 1192def get_window_height(): 1193 """ 1194 A reporter function that returns the current height of the window. 1195 1196 Returns: 1197 An `int` representing height of the window. 1198 """ 1199 return _a_canvas.winfo_height() 1200 1201 1202def get_window_width(): 1203 """ 1204 A reporter function that returns the current width of the window. 1205 1206 Returns: 1207 An `int` representing width of the window. 1208 """ 1209 return _a_canvas.winfo_width() 1210 1211 1212def interpolate_colors(color1, color2, frac): 1213 """ 1214 A reporter function that generates a new color between two given colors. 1215 Args: 1216 color1 (`str`): The path of the file to wrap 1217 color2 (`str`): The path of the file to wrap 1218 frac (`float`): What fraction of each color to take. An input of 0 returns 1219 color1, an input of 1 returns color2, an input of 0.5 returns a color 1220 perfectly between the two. 1221 1222 Returns: 1223 A color (as a hex `str`) to be used elsewhere 1224 """ 1225 if "#" not in color1 1226 color1 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color1))) 1227 else 1228 color1 = _tupelize_color(color1) 1229 if "#" not in color2 1230 color2 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color2))) 1231 else 1232 color2 = _tupelize_color(color2) 1233 return _interpolate_tuple(color1, color2, frac) 1234 1235 1236def random_color(): 1237 """ 1238 Returns a random color as a `string` to be used. 1239 It does not accept any inputs. 1240 """ 1241 r = lambda randint(0, 255) 1242 return "#%02X%02X%02X" % (r(), r(), r()) 1243 1244 1245def setup_listener(event_str, handler_function, override=False): 1246 """ 1247 Sets up a listener for a given event on our window. 1248 1249 Args: 1250 event_str (`str`): The magic string that represents this event in the window 1251 handler_function (`func`): The name (not a string though) of the function you want called when the event his heard 1252 override (`bool`): Only use this if you speak to Prof. Bain and he recommends it. 1253 1254 The supported events are: 1255 * `"LEFT-CLICK"`: Left mouse click 1256 * `"RIGHT-CLICK"`: Right mouse click 1257 * `"ALT-CLICK"`: If you"re using a PC, this event might instead work for Right Click 1258 * `"LEFT-DRAG"`: Left mouse clicked and dragged on the screen 1259 * `"RIGHT-DRAG"`: Right mouse clicked and dragged on the screen 1260 * `"ALT-DRAG"`: For PCs, this event might instead work for RIGHT-DRAG 1261 * `"DOUBLE-LEFT"`: Left mouse double click 1262 * `"DOUBLE-RIGHT"`: Right mouse double click 1263 * `"DOUBLE-ALT"`: For PCs, this event might instead work for DOUBLE-RIGHT 1264 * `"KEY"`: The catch-all event for Keyboard presses 1265 """ 1266 1267 event_translator = { 1268 "LEFT-CLICK" "<Button-1>", 1269 "RIGHT-CLICK" "<Button-2>", 1270 "ALT-CLICK" "<Button-3>", 1271 "LEFT-DRAG" "<B1-Motion>", 1272 "RIGHT-DRAG" "<B2-Motion>", 1273 "ALT-DRAG" "<B3-Motion>", 1274 "DOUBLE-LEFT" "<Double-Button-1>", 1275 "DOUBLE-RIGHT" "<Double-Button-2>", 1276 "DOUBLE-ALT" "<Double-Button-3>", 1277 "KEY" "<Key>", 1278 } 1279 1280 if event_str not in event_translator and not override 1281 raise ( 1282 TypeError( 1283 f"The event you entered, {event_str}, isn"t supported. Here are the supported events: {[i for i in event_translator]}" 1284 ) 1285 ) 1286 1287 event = event_translator[event_str] 1288 1289 setup_listener.tracker.add(event_str) 1290 1291 _a_canvas.bind(event, handler_function) 1292 1293setup_listener.tracker = set() 1294 1295def setup_shapes(title, background="white", include_grid=True, width=600, height=600): 1296 """ 1297 A static function that sets up the pop-up window. You can specify the size of the window here. 1298 1299 However, you should NOT add any calls to this function unless Prof. Bain specifically tells you to! 1300 1301 Args: 1302 title (`str`): The title of the pop-up window. 1303 background (`str`): A valid color as a string to be used as the background color. 1304 include_grid (`bool`): Whether or not to draw the grid. 1305 width (`int` or `str`): How wide the window should appear (advanced: use the string "FULLWIDTH" to maximize the width) 1306 height (`int` or `str`): How wide the window should appear (advanced: use the string "FULLHEIGHT" to maximize the width) 1307 """ 1308 1309 global _a_canvas 1310 gui = Tk() 1311 gui.title(title) 1312 1313 if width == "FULLWIDTH" 1314 width = gui.winfo_screenwidth() 1315 1316 if height == "FULLHEIGHT" 1317 height = gui.winfo_screenheight() 1318 1319 _a_canvas = Canvas(gui, background=background, width=width, height=height) 1320 _a_canvas.pack() 1321 if include_grid 1322 grid(width, height) 1323 1324 _a_canvas.focus_set() 1325 return _a_canvas 1326 1327 1328def update(): 1329 """ 1330 A static function that sets up the pop-up window. DO NOT USE THIS FUNCTION unless Prof. Bain explictly says to use it. 1331 """ 1332 _a_canvas.update() 1333 1334 1335def _safe_color(color ): 1336 color = color.strip() 1337 # Could also do some other verifications here... 1338 return color 1339 1340 1341def _tupelize_color(color): 1342 R = (color[13], 16) 1343 G = (color[35], 16) 1344 B = (color[57], 16) 1345 return R, G, B 1346 1347 1348def _interpolate_tuple(startcolor, goalcolor, frac): 1349 R = startcolor[0] 1350 G = startcolor[1] 1351 B = startcolor[2] 1352 1353 targetR = goalcolor[0] 1354 targetG = goalcolor[1] 1355 targetB = goalcolor[2] 1356 1357 DiffR = targetR - R 1358 DiffG = targetG - G 1359 DiffB = targetB - B 1360 1361 iR = (R + (DiffR * frac)) 1362 iG = (G + (DiffG * frac)) 1363 iB = (B + (DiffB * frac)) 1364 1365 hR = hex(iR).replace("0x", "") 1366 hG = hex(iG).replace("0x", "") 1367 hB = hex(iB).replace("0x", "") 1368 1369 if len(hR) == 1 1370 hR = "0" + hR 1371 if len(hB) == 1 1372 hB = "0" + hB 1373 if len(hG) == 1 1374 hG = "0" + hG 1375 1376 color = ("#" + hR + hG + hB).upper() 1377 1378 return color 1379 1380 1381def _polar_to_cartesian(r, theta): 1382 return (r * cos(theta)), (r * sin(theta)) 1383 1384 1385def _get_outline(shape): 1386 """ 1387 A reporter function that takes in a shape and calls the various helper functions to generate 1388 a sort of "summary" of that particular shape and returns it in the form of a dictionary. 1389 1390 Args: 1391 shape (`Shape` or Tag): The shape in question. 1392 1393 Returns: 1394 a `Dictionary` with the various properties of the shape 1395 """ 1396 1397 return { 1398 "center" get_center(shape), 1399 "left" get_left(shape), 1400 "right" get_right(shape), 1401 "top" get_top(shape), 1402 "bottom" get_bottom(shape), 1403 } 1404 1405 1406def _draw_row(row, top_left, colors, pixel=25, tag=""): 1407 """ 1408 Draws a single row of some pixel art. 1409 1410 Args: 1411 row (sequence): the row of artwork to draw 1412 top_left (`tuple`): the top left coordinate of the pixel art 1413 color (sequence): the colors to use for each square 1414 pixel (`int`, optional): how big each individual pixel should be 1415 tag (`str`, optional): the tag to assign to every square in the row 1416 """ 1417 x = top_left[0] 1418 y = top_left[1] 1419 for cell in row 1420 if cell != 0 1421 square((x, y), pixel, color=colors[cell], tag=tag) 1422 x += pixel 1423 1424 1425def _safe_bbox(shape): 1426 try 1427 bbox = _a_canvas.bbox(shape) 1428 if bbox is None 1429 Exception( 1430 f"We couldn"t find the shape with tag/id: {shape}. Make sure this shape exists!" 1431 ) 1432 return bbox 1433 except 1434 raise Exception( 1435 f"We couldn"t find the shape with tag/id: {shape}. Make sure this shape exists!" 1436 )
32def arc(points=[], width=5, color="hot pink", line_steps=15, tag="", ): 33 """ 34 A reporter function that draws an arc ("curve") given a list of points. 35 Args: 36 points (`list`): The points outlining the curve; this should be a list of tuples (coordinates). 37 Make sure to give it at least 3 (x,y) coordinates that aren"t a straight line! 38 color (`str`): What color to make the shape. 39 tag (`str`): The tag to assign to the shape. 40 41 Returns: 42 `Shape`: The arc that was created. 43 """ 44 return _a_canvas.create_line( 45 points, 46 width=width, 47 fill=color, 48 splinesteps=line_steps, 49 smooth=True, 50 tags=tag, 51 , 52 )
A reporter function that draws an arc ("curve") given a list of points.
Arguments:
- points (
list): The points outlining the curve; this should be a list of tuples (coordinates). Make sure to give it at least 3 (x,y) coordinates that aren't a straight line! - color (
str): What color to make the shape. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The arc that was created.
55def car(top_left=(0, 0), size=100, body_color="#3D9970", wheel_color="black", tag=""): 56 """ 57 Draws a cool car. 58 59 Args: 60 top_left (`tuple`): A coordinate at which to draw the car. 61 body_color (`str`): Color to make the body of the car. 62 wheel_color (`str`): Color to make the wheel of the car. 63 tag (`str`): The tag to assign to the shape. 64 """ 65 x, y = top_left 66 rectangle((x + 5 * size / 10, y), size, size / 10 * 4, color=body_color, tag=tag) 67 rectangle( 68 (x, y + size - 7 * size / 10), 69 size * 2, 70 size / 10 * 4.5, 71 color=body_color, 72 tag=tag, 73 ) 74 circle( 75 (x + 5 * size / 10, y + size - size / 5), size / 5, color=wheel_color, tag=tag 76 ) 77 circle( 78 (x + 15 * size / 10, y + size - size / 5), size / 5, color=wheel_color, tag=tag 79 )
Draws a cool car.
Arguments:
- top_left (
tuple): A coordinate at which to draw the car. - body_color (
str): Color to make the body of the car. - wheel_color (
str): Color to make the wheel of the car. - tag (
str): The tag to assign to the shape.
82def circle(center=(0, 0), radius=25, color="hot pink", outline="", tag="", ): 83 """ 84 A reporter function that draws a circle. 85 Args: 86 center (`tuple`): A coordinate representing the center of the shape. 87 radius (`int`): Specifies the circle"s radius. 88 color (`str`): What color to draw the shape. 89 outline (`str`): What color should the border of the shape be. 90 tag (`str`): The tag to assign to the shape. 91 92 Returns: 93 `Shape`: The circle that was created. 94 """ 95 return oval( 96 center=center, radius_x=radius, radius_y=radius, color=color, tag=tag, 97 )
A reporter function that draws a circle.
Arguments:
- center (
tuple): A coordinate representing the center of the shape. - radius (
int): Specifies the circle's radius. - color (
str): What color to draw the shape. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The circle that was created.
100def cloud(center=(0, 0), size=30, color="white", tag=""): 101 """ 102 Reporter function that draws a cloud to the screen. 103 Args: 104 center (`tuple`): the point on which to center the cloud 105 size (`int`): how big (roughly) the cloud is drawn 106 color (`str`): which determines the color of the cloud 107 tag (`str`): to give the cloud a name 108 109 Returns: 110 `Shape`: The cloud that was created. 111 """ 112 for i in range(10): 113 x_offset = randint((-1 * size * 1.333), (size * 1.333)) 114 y_offset = randint(0, (size * 0.667)) 115 circle( 116 center=(center[0] + x_offset, center[1] + y_offset), 117 radius=randint((size * 0.667), (size * 1.667)), 118 color=color, 119 tag=tag, 120 ) 121 return tag
Reporter function that draws a cloud to the screen.
Arguments:
- center (
tuple): the point on which to center the cloud - size (
int): how big (roughly) the cloud is drawn - color (
str): which determines the color of the cloud - tag (
str): to give the cloud a name
Returns:
Shape: The cloud that was created.
124def diamond( 125 center=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 126): 127 """ 128 A reporter function that draws a rectangle. 129 Args: 130 center (`tuple`): A coordinate representing the center of the shape. 131 width (`int`): How wide to draw the shape. 132 height (`int`): How tall to draw the shape. 133 color (`str`): What color to draw the shape. 134 outline (`str`): What color should the border of the shape be. 135 tag (`str`): The tag to assign to the shape. 136 137 Returns: 138 `Shape`: The shape that was created. 139 """ 140 point_0 = (center[0] - width / 2, center[1]) 141 point_1 = (center[0], center[1] - height / 2) 142 point_2 = (center[0] + width / 2, center[1]) 143 point_3 = (center[0], center[1] + height / 2) 144 return _a_canvas.create_polygon( 145 point_0, 146 point_1, 147 point_2, 148 point_3, 149 fill=_safe_color(color), 150 tags=tag, 151 outline=outline, 152 , 153 )
A reporter function that draws a rectangle.
Arguments:
- center (
tuple): A coordinate representing the center of the shape. - width (
int): How wide to draw the shape. - height (
int): How tall to draw the shape. - color (
str): What color to draw the shape. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The shape that was created.
156def grid(width=None, height=None, interval=100, show_labels=True): 157 """ 158 Draws a grid on a screen with intervals of 100. 159 160 Args: 161 width (`int`): The width of the grid to draw (defaults to the whole window) 162 height (`int`): The height of the grid to draw (defaults to the whole window) 163 interval (`int`): The interval to draw the grid on. 164 show_labels (`bool`): Whether or not to show coordinate labels. 165 166 """ 167 168 if width is None 169 width = get_window_width() 170 171 if height is None 172 height = get_window_height() 173 174 # Creates all vertical lines at intervals of 100 175 for i in range(0, width, interval): 176 _a_canvas.create_line(i, 0, i, height, tag="grid", fill="black") 177 # Creates all horizontal lines at intervals of 100 178 for i in range(0, height, interval): 179 _a_canvas.create_line(0, i, width, i, tag="grid", fill="black") 180 181 if show_labels 182 # Creates axis labels 183 offset = 2 184 for y in range(0, height, interval): 185 for x in range(0, width, interval): 186 _a_canvas.create_oval( 187 x - offset, 188 y - offset, 189 x + offset, 190 y + offset, 191 fill="black", 192 tag="grid", 193 ) 194 _a_canvas.create_text( 195 x + offset, 196 y + offset, 197 text="({0}, {1})".format(x, y), 198 anchor="nw", 199 font=("Purisa", 8), 200 fill="black", 201 tag="grid", 202 )
Draws a grid on a screen with intervals of 100.
Arguments:
- width (
int): The width of the grid to draw (defaults to the whole window) - height (
int): The height of the grid to draw (defaults to the whole window) - interval (
int): The interval to draw the grid on. - show_labels (
bool): Whether or not to show coordinate labels.
208def image(image_path, position=(200, 200), rotation=None, scale=None, tag="", ): 209 """ 210 Draws a given image on the screen. NOTE: Requires the `pillow` package to be installed - contact 211 Prof. Bain or post on edSTEM if you"d like more details! 212 213 Args: 214 image_path (`str`): Location of the image file on your computer. 215 position (`tuple`): A coordinate at which to render the image. 216 rotation (`int`): A number of degrees to rotate the given image. 217 scale (`int`): A scaling factor to multiply the image size by. 218 tag (`str`): A string representing the "name" fo this shape. 219 """ 220 # import PIL libraries 221 from PIL import Image, ImageTk 222 223 anchor = "nw" 224 225 import os 226 227 # 1. create PIL image and apply any image transformations: 228 dir_path = os.path.dirname(os.path.realpath(__file__)) 229 image_path = os.path.join(dir_path, image_path) 230 pil_image = Image.open(image_path) 231 if scale 232 size = (round(pil_image.size[0] * scale), round(pil_image.size[1] * scale)) 233 pil_image = pil_image.resize(size) 234 if rotation 235 pil_image = pil_image.rotate(rotation) # note: returns a copy 236 237 # 2. convert to tkinter-compatible image format: 238 tkinter_image = ImageTk.PhotoImage(pil_image) 239 _cache.append( 240 tkinter_image 241 ) # workaround for known tkinter bug: http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm 242 243 # 3. draw image on canvas: 244 _a_canvas.create_image( 245 *position, image=tkinter_image, anchor=anchor, tags=tag, 246 )
Draws a given image on the screen. NOTE: Requires the pillow package to be installed - contact
Prof. Bain or post on edSTEM if you'd like more details!
Arguments:
- image_path (
str): Location of the image file on your computer. - position (
tuple): A coordinate at which to render the image. - rotation (
int): A number of degrees to rotate the given image. - scale (
int): A scaling factor to multiply the image size by. - tag (
str): A string representing the "name" fo this shape.
249def line(points=[], curvy=False, color="hot pink", tag="", ): 250 """ 251 A reporter function that draws a line given a list of points. 252 Args: 253 points (`list`): The points that define the line; this should be a list of tuples (coordinates). 254 curvy (`bool`): Makes a curvy line instead. 255 color (`str`): What color to make the shape. 256 tag (`str`): The tag to assign to the shape. 257 258 Returns: 259 `Shape`: The line that was created. 260 """ 261 return _a_canvas.create_line(points, fill=color, smooth=curvy, tags=tag, )
A reporter function that draws a line given a list of points.
Arguments:
- points (
list): The points that define the line; this should be a list of tuples (coordinates). - curvy (
bool): Makes a curvy line instead. - color (
str): What color to make the shape. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The line that was created.
264def oval( 265 center=(0, 0), 266 radius_x=25, 267 radius_y=50, 268 color="hot pink", 269 outline="", 270 tag="", 271 , 272): 273 """ 274 A reporter function that draws an oval. 275 Args: 276 center (`tuple`): A coordinate representing the center of the shape. 277 radius_x (`int`): Specifies the oval"s radius on the x-axis. 278 radius_y (`int`): Specifies the oval"s radius on the y-axis. 279 color (`str`): What color to draw the shape. 280 outline (`str`): What color should the border of the shape be. 281 tag (`str`): The tag to assign to the shape. 282 283 Returns: 284 `Shape`: The oval that was created. 285 """ 286 x = center[0] 287 y = center[1] 288 x0, y0, x1, y1 = (x - radius_x, y - radius_y, x + radius_x, y + radius_y) 289 steps = 100 290 # major and minor axes 291 a = (x1 - x0) / 2.0 292 b = (y1 - y0) / 2.0 293 # center 294 xc = x0 + a 295 yc = y0 + b 296 point_list = [] 297 # create the oval as a list of points 298 for i in range(steps): 299 # Calculate the angle for this step 300 theta = (pi * 2) * (float(i) / steps) 301 x = a * cos(theta) 302 y = b * sin(theta) 303 point_list.append(round(x + xc)) 304 point_list.append(round(y + yc)) 305 306 return _a_canvas.create_polygon( 307 point_list, fill=_safe_color(color), tags=tag, 308 )
A reporter function that draws an oval.
Arguments:
- center (
tuple): A coordinate representing the center of the shape. - radius_x (
int): Specifies the oval's radius on the x-axis. - radius_y (
int): Specifies the oval's radius on the y-axis. - color (
str): What color to draw the shape. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The oval that was created.
311def pixel_art(top_left, artwork, palette, pixel=10, tag=""): 312 """ 313 Draws a pixel art design! 314 315 Args: 316 top_left (`tuple`): the top left coordinate of the pixel art 317 artwork (sequence of sequences): the art to draw 318 palette (sequence): the palette of colors to use for each different square 319 pixel (`int`, optional): how big each individual pixel should be 320 tag (`str`, optional): the tag to assign to every square in the row 321 322 Note: this doesn"t return anything so make sure to use a tag if you want to animate / modify. 323 """ 324 x = top_left[0] 325 y = top_left[1] 326 for row in artwork 327 # draw each row at the specified (x, y) position: 328 _draw_row(row, (x, y), colors=palette, pixel=pixel, tag=tag) 329 # ...and don"t forget to shift the y-value down by the proper 330 # amount so that the next row won"t draw on top of the first one: 331 y += pixel
Draws a pixel art design!
Arguments:
- top_left (
tuple): the top left coordinate of the pixel art - artwork (sequence of sequences): the art to draw
- palette (sequence): the palette of colors to use for each different square
- pixel (
int, optional): how big each individual pixel should be - tag (
str, optional): the tag to assign to every square in the row
Note: this doesn't return anything so make sure to use a tag if you want to animate / modify.
334def polygon(points=[], color="hot pink", outline="", tag="", ): 335 """ 336 A reporter function that draws a polygon given a list of points. 337 Args: 338 points (`list`): The points outlining the polygon; this should be a list of tuples (coordinates). 339 defaults to an empty list. 340 outline (`str`): What color should the border of the shape be. 341 color (`str`): What color to make the shape. 342 343 Returns: 344 `Shape`: The polygon that was created. 345 """ 346 return _a_canvas.create_polygon(points, fill=_safe_color(color), tags=tag, )
A reporter function that draws a polygon given a list of points.
Arguments:
- points (
list): The points outlining the polygon; this should be a list of tuples (coordinates). defaults to an empty list. - outline (
str): What color should the border of the shape be. - color (
str): What color to make the shape.
Returns:
Shape: The polygon that was created.
349def rectangle( 350 top_left=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 351): 352 """ 353 A reporter function that draws a rectangle. 354 Args: 355 top_left (`tuple`): A coordinate representing the top left-hand corner of the shape. 356 width (`int`): How wide to draw the shape. 357 height (`int`): How tall to draw the shape. 358 color (`str`): What color to draw the shape. 359 outline (`str`): What color should the border of the shape be. 360 tag (`str`): The tag to assign to the shape. 361 362 Returns: 363 `Shape`: The rectangle that was created. 364 """ 365 point_0 = top_left 366 point_1 = (top_left[0] + width, top_left[1]) 367 point_2 = (top_left[0] + width, top_left[1] + height) 368 point_3 = (top_left[0], top_left[1] + height) 369 return _a_canvas.create_polygon( 370 point_0, point_1, point_2, point_3, fill=_safe_color(color), tags=tag, 371 )
A reporter function that draws a rectangle.
Arguments:
- top_left (
tuple): A coordinate representing the top left-hand corner of the shape. - width (
int): How wide to draw the shape. - height (
int): How tall to draw the shape. - color (
str): What color to draw the shape. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The rectangle that was created.
374def spiral( 375 center=(0, 0), width=100, roughness=0.01, start=0, spirals=5, line_width=1, 376): 377 """ 378 A reporter function that draws a spiral. 379 Args: 380 center (`tuple`): A coordinate representing the center of the shape. 381 width (`int`): Specifies the total width of the spiral. 382 roughness (`float`): Controls how spiral-y the shape is (lower is less spiral-y) 383 start (`int`): Where on the spiral to start drawing. 384 spirals (`int`): How many loops to draw. 385 line_width (`int`): How wide for the line to be drawn. 386 tag (`str`): The tag to assign to the shape. 387 388 Returns: 389 `Shape`: The spiral that was created. 390 """ 391 theta = 0.0 392 r = start 393 all_points = [] 394 prev_pos = _polar_to_cartesian(r, theta) 395 distance = width / 4 / pi / spirals 396 all_points.append((prev_pos[0] + center[0], prev_pos[1] + center[1])) 397 while theta < 2 * spirals * pi 398 theta += roughness 399 r = start + distance * theta 400 pos = _polar_to_cartesian(r, theta) 401 all_points.append((pos[0] + center[0], pos[1] + center[1])) 402 403 return arc(points=all_points, width=line_width, )
A reporter function that draws a spiral.
Arguments:
- center (
tuple): A coordinate representing the center of the shape. - width (
int): Specifies the total width of the spiral. - roughness (
float): Controls how spiral-y the shape is (lower is less spiral-y) - start (
int): Where on the spiral to start drawing. - spirals (
int): How many loops to draw. - line_width (
int): How wide for the line to be drawn. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The spiral that was created.
406def square(top_left=(0, 0), size=25, color="hot pink", outline="", tag="", ): 407 """ 408 A reporter function that draws a square. 409 Args: 410 top_left (`tuple`): A coordinate representing the top left-hand corner of the shape. 411 size (`int`): How big to draw the shape. 412 color (`str`): What color to draw the shape. 413 outline (`str`): What color should the border of the shape be. 414 tag (`str`): The tag to assign to the shape. 415 416 Returns: 417 `Shape`: The square that was created. 418 """ 419 return rectangle( 420 top_left=top_left, width=size, height=size, color=color, tag=tag, 421 )
A reporter function that draws a square.
Arguments:
- top_left (
tuple): A coordinate representing the top left-hand corner of the shape. - size (
int): How big to draw the shape. - color (
str): What color to draw the shape. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The square that was created.
424def star( 425 center=(0, 0), 426 radius=50, 427 color="hot pink", 428 outer_radius=75, 429 points=5, 430 outline="", 431 tag="", 432 , 433): 434 """ 435 A reporter function that draws a star. 436 Args: 437 center (`tuple`): A coordinate representing the center of the shape. 438 radius (`int`): Specifies the radius of the inside part of the star. 439 color (`str`): Specifies the color of the star. 440 outer_radius (`int`): Specifies the radius of the outside part of the star. 441 points (`int`): Specifies the number of points for the star. 442 outline (`str`): What color should the border of the shape be. 443 tag (`str`): The tag to assign to the shape. 444 445 Returns: 446 `Shape`: The star that was created. 447 """ 448 arc_segment = 360 / points 449 vertices = [] 450 for i in range(points): 451 inner_point = ( 452 radius * cos(radians(arc_segment * i)) + center[0], 453 -1 * radius * sin(radians(arc_segment * i)) + center[1], 454 ) 455 vertices.append(inner_point) 456 outer_point = ( 457 outer_radius * cos(radians(arc_segment * i + arc_segment / 2)) + center[0], 458 -1 * outer_radius * sin(radians(arc_segment * i + arc_segment / 2)) 459 + center[1], 460 ) 461 vertices.append(outer_point) 462 return polygon(vertices, color=color, tag=tag, )
A reporter function that draws a star.
Arguments:
- center (
tuple): A coordinate representing the center of the shape. - radius (
int): Specifies the radius of the inside part of the star. - color (
str): Specifies the color of the star. - outer_radius (
int): Specifies the radius of the outside part of the star. - points (
int): Specifies the number of points for the star. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The star that was created.
465def text( 466 top_left=(0, 0), text="", font=("Purisa", 32), color="black", tag="", 467): 468 """ 469 A reporter function that draws text to the screen 470 Args: 471 top_left (`tuple`): coordinate pair to specify the location. 472 text (`str`): What text to draw. 473 font (`tuple`): A tuple where the first element is a string for the font name and the second is an 474 int with the font size. 475 color (`str`): What color should the text be. 476 tag (`str`): The name to tag this thing with. 477 478 Returns: 479 `Shape`: The text that was created. 480 """ 481 return _a_canvas.create_text( 482 top_left, text=text, font=font, fill=color, tags=tag, 483 )
A reporter function that draws text to the screen
Arguments:
- top_left (
tuple): coordinate pair to specify the location. - text (
str): What text to draw. - font (
tuple): A tuple where the first element is a string for the font name and the second is an int with the font size. - color (
str): What color should the text be. - tag (
str): The name to tag this thing with.
Returns:
Shape: The text that was created.
486def triangle( 487 bottom_center=(0, 0), 488 width=25, 489 top_shift=0, 490 height=0, 491 color="hot pink", 492 outline="", 493 tag="", 494 , 495): 496 """ 497 A reporter function that draws a triangle. 498 Args: 499 bottom_center (`tuple`): A coordinate representing the bottom center of the shape. 500 width (`int`): Specifies the width of the base of the triangle. 501 top_shift (`int`): Specifies the how far to the left or right to shift the top of 502 the triangle from the bottom center. 503 height (`int`): Specifies the triangle"s height. 504 color (`str`): What color to draw the shape. 505 outline (`str`): What color should the border of the shape be. 506 tag (`str`): The tag to assign to the shape. 507 508 Returns: 509 `Shape`: The triangle that was created. 510 """ 511 if height == 0 512 height = width * sqrt(3) / 2 513 point_0 = (bottom_center[0] - width / 2, bottom_center[1]) 514 point_1 = (bottom_center[0] + width / 2, bottom_center[1]) 515 point_2 = (bottom_center[0] + top_shift, bottom_center[1] - height) 516 517 return _a_canvas.create_polygon( 518 point_0, point_1, point_2, fill=_safe_color(color), tags=tag, 519 )
A reporter function that draws a triangle.
Arguments:
- bottom_center (
tuple): A coordinate representing the bottom center of the shape. - width (
int): Specifies the width of the base of the triangle. - top_shift (
int): Specifies the how far to the left or right to shift the top of the triangle from the bottom center. - height (
int): Specifies the triangle's height. - color (
str): What color to draw the shape. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The triangle that was created.
522def wedge( 523 center=(0, 0), radius=25, angle=180, color="hot pink", outline="", tag="", 524): 525 """ 526 A reporter function that draws a circle. 527 Args: 528 center (`tuple`): A coordinate representing the center of the shape. 529 radius (`int`): Specifies the circle"s radius. 530 angle (`int`): A number between 0 and 360 that specifies how much of the circle to draw. 531 color (`str`): What color to draw the shape. 532 outline (`str`): What color should the border of the shape be. 533 tag (`str`): The tag to assign to the shape. 534 535 Returns: 536 `Shape`: The wedge that was created. 537 """ 538 point_list = [center[0], center[1]] 539 for i in range(0, 0 + angle): 540 x1 = center[0] + radius * cos(radians(i)) 541 point_list.append(x1) 542 y1 = center[1] + radius * sin(radians(i)) 543 point_list.append(y1) 544 545 point_list.append(center[0]) 546 point_list.append(center[1]) 547 548 return _a_canvas.create_polygon( 549 point_list, fill=_safe_color(color), outline=outline, tags=tag, 550 )
A reporter function that draws a circle.
Arguments:
- center (
tuple): A coordinate representing the center of the shape. - radius (
int): Specifies the circle's radius. - angle (
int): A number between 0 and 360 that specifies how much of the circle to draw. - color (
str): What color to draw the shape. - outline (
str): What color should the border of the shape be. - tag (
str): The tag to assign to the shape.
Returns:
Shape: The wedge that was created.
556def above(shape1, shape2, offset_x=0, offset_y=0): 557 """ 558 A reporter function that places shape1 above shape2 (vertically). It does this by moving shape 1"s center 559 to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any 560 specified offset. 561 562 Args: 563 shape1 (`Shape` or Tag): The first shape to use. 564 shape2 (`Shape` or Tag): The second shape to use. 565 offset_x (`int`): How much to shift shape 2 in the x-direction after moving it. 566 offset_y (`int`): How much to shift shape 2 in the x-direction after moving it. 567 568 Returns: 569 `Shape`: The modified shape1. 570 """ 571 overlay(shape1, shape2) 572 _a_canvas.move( 573 shape1, 574 0 + offset_x, 575 -1 * (get_height(shape2) + get_height(shape1)) / 2 + offset_y, 576 ) 577 return shape1
A reporter function that places shape1 above shape2 (vertically). It does this by moving shape 1's center to shape 2's center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any specified offset.
Arguments:
- shape1 (
Shapeor Tag): The first shape to use. - shape2 (
Shapeor Tag): The second shape to use. - offset_x (
int): How much to shift shape 2 in the x-direction after moving it. - offset_y (
int): How much to shift shape 2 in the x-direction after moving it.
Returns:
Shape: The modified shape1.
580def align(shape1, shape2, via="middle", offset_x=0, offset_y=0): 581 """ 582 A reporter function that aligns `shape1` with `shape2`. It does this by moving `shape1` to align with 583 whatever property of `shape2` is selected with the `via` input. 584 585 Args: 586 shape1 (`Shape` or Tag): The first shape to use. 587 shape2 (`Shape` or Tag): The second shape to use. 588 via (`str`): Has to be one of, the following options: `"center"` (horizontal center), 589 `"middle"` (vertical center), `"top"`, `"bottom"`, `"left"`, or `"right"` 590 offset_x (`int`): How much to shift in the x-axis after alignment 591 offset_y (`int`): How much to shift in the y-axis after alignment 592 593 Returns: 594 `Shape`: The modified shape1. 595 """ 596 via_options = ["center", "middle", "top", "bottom", "left", "right"] 597 if via not in via_options 598 raise ValueError( 599 "The via input must be one of " 600 + (via_options) 601 + " but instead we found " 602 + (via) 603 ) 604 605 outline1 = _get_outline(shape1) 606 outline2 = _get_outline(shape2) 607 608 if via == "center" 609 _a_canvas.move( 610 shape1, (outline2["center"][0] - outline1["center"][0]) + offset_x, offset_y 611 ) 612 613 elif via == "middle" 614 _a_canvas.move( 615 shape1, offset_x, (outline2["center"][1] - outline1["center"][1]) + offset_y 616 ) 617 618 elif via == "top" 619 _a_canvas.move(shape1, offset_x, (outline2["top"] - outline1["top"]) + offset_y) 620 621 elif via == "bottom" 622 _a_canvas.move( 623 shape1, offset_x, (outline2["bottom"] - outline1["bottom"]) + offset_y 624 ) 625 626 elif via == "left" 627 _a_canvas.move( 628 shape1, (outline2["left"] - outline1["left"]) + offset_x, offset_y 629 ) 630 631 elif via == "right" 632 _a_canvas.move( 633 shape1, (outline2["right"] - outline1["right"]) + offset_x, offset_y 634 ) 635 636 return shape1
A reporter function that aligns shape1 with shape2. It does this by moving shape1 to align with
whatever property of shape2 is selected with the via input.
Arguments:
- shape1 (
Shapeor Tag): The first shape to use. - shape2 (
Shapeor Tag): The second shape to use. - via (
str): Has to be one of, the following options:"center"(horizontal center),"middle"(vertical center),"top","bottom","left", or"right" - offset_x (
int): How much to shift in the x-axis after alignment - offset_y (
int): How much to shift in the y-axis after alignment
Returns:
Shape: The modified shape1.
639def beside(shape1, shape2, offset_x=0, offset_y=0): 640 """ 641 A reporter function that places shape1 beside shape2 (horizontally). It does this by moving shape 1"s center 642 to shape 2"s center, moving shape 1 in the x-direction the exact width of shape 2, and then applying any 643 specified offset. 644 645 Args: 646 shape1 (`Shape` or Tag): The first shape to use. 647 shape2 (`Shape` or Tag): The second shape to use. 648 offset_x (`int`): How much to shift shape 2 in the x-direction after moving it. 649 offset_y (`int`): How much to shift shape 2 in the x-direction after moving it. 650 651 Returns: 652 `Shape`: The modified shape1. 653 """ 654 overlay(shape1, shape2) 655 _a_canvas.move( 656 shape1, 657 (get_width(shape2) + get_width(shape1)) / 2 + offset_x, 658 0 + offset_y, 659 ) 660 return shape1
A reporter function that places shape1 beside shape2 (horizontally). It does this by moving shape 1's center to shape 2's center, moving shape 1 in the x-direction the exact width of shape 2, and then applying any specified offset.
Arguments:
- shape1 (
Shapeor Tag): The first shape to use. - shape2 (
Shapeor Tag): The second shape to use. - offset_x (
int): How much to shift shape 2 in the x-direction after moving it. - offset_y (
int): How much to shift shape 2 in the x-direction after moving it.
Returns:
Shape: The modified shape1.
663def below(shape1, shape2, offset_x=0, offset_y=0): 664 """ 665 A reporter function that places shape1 below shape2 (vertically). It does this by moving shape 1"s center 666 to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any 667 specified offset. 668 669 Args: 670 shape1 (`Shape` or Tag): The first shape to use. 671 shape2 (`Shape` or Tag): The second shape to use. 672 offset_x (`int`): How much to shift shape 2 in the x-direction after moving it. 673 offset_y (`int`): How much to shift shape 2 in the x-direction after moving it. 674 675 Returns: 676 `Shape`: The modified shape1. 677 """ 678 overlay(shape1, shape2) 679 _a_canvas.move( 680 shape1, 681 0 + offset_x, 682 (get_height(shape2) + get_height(shape1)) / 2 + offset_y, 683 ) 684 return shape1
A reporter function that places shape1 below shape2 (vertically). It does this by moving shape 1's center to shape 2's center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any specified offset.
Arguments:
- shape1 (
Shapeor Tag): The first shape to use. - shape2 (
Shapeor Tag): The second shape to use. - offset_x (
int): How much to shift shape 2 in the x-direction after moving it. - offset_y (
int): How much to shift shape 2 in the x-direction after moving it.
Returns:
Shape: The modified shape1.
687def change_color(shape, color): 688 """ 689 Change the fill color of a tagged object. 690 691 Args: 692 shape (`Shape` or Tag): The shape or tag to re-fill. 693 color (`str`): A color name or hex code to re-fill with. 694 """ 695 ids = _a_canvas.find_withtag(shape) 696 for id in ids 697 _a_canvas.itemconfig(id, fill=color)
Change the fill color of a tagged object.
Arguments:
- shape (
Shapeor Tag): The shape or tag to re-fill. - color (
str): A color name or hex code to re-fill with.
700def delete(shape): 701 """ 702 A function that deletes a shape from our screen. 703 704 Args: 705 shape (`Shape` or Tag): The shape to delete. 706 """ 707 _a_canvas.delete(shape)
A function that deletes a shape from our screen.
Arguments:
- shape (
Shapeor Tag): The shape to delete.
710def duplicate(shape, color=None): 711 """ 712 A reporter function that perfectly copies a shape and returns that copy. 713 714 Args: 715 shape (`Shape` or Tag): The shape to duplicate. 716 color (`str`): A new color to use with the duplicated shape. 717 718 Returns: 719 `Shape`: The new duplicated shape. 720 """ 721 shape_type = _a_canvas.type(shape) 722 shape_config = _a_canvas.itemconfig(shape) 723 shape_coords = _a_canvas.coords(shape) 724 the_copy = None 725 if shape_type == "polygon" 726 new_config = {key shape_config[key][-1] for key in shape_config.keys()} 727 if color != None 728 new_config["fill"] = color 729 the_copy = _a_canvas.create_polygon(shape_coords, new_config) 730 return the_copy
A reporter function that perfectly copies a shape and returns that copy.
Arguments:
- shape (
Shapeor Tag): The shape to duplicate. - color (
str): A new color to use with the duplicated shape.
Returns:
Shape: The new duplicated shape.
733def mirror(shape): 734 """ 735 A function that takes a shape and flips it across its vertical 736 axis, returning the modified shape. 737 738 Args: 739 shape (`Shape` or Tag): The shape in question. 740 741 """ 742 center = get_center(shape)[0] 743 shape_ids = _a_canvas.find_withtag(shape) 744 for shape_id in shape_ids 745 flipped_coordinates = [] 746 shape_coords = _a_canvas.coords(shape_id) 747 counter = 0 748 for num in shape_coords 749 if counter % 2 == 0 750 if num < center 751 flipped_coordinates.append(num + 2 * (center - num)) 752 elif num > center 753 flipped_coordinates.append(num - 2 * (num - center)) 754 else 755 flipped_coordinates.append(num) 756 else 757 flipped_coordinates.append(num) 758 counter += 1 759 _a_canvas.coords(shape_id, flipped_coordinates)
A function that takes a shape and flips it across its vertical axis, returning the modified shape.
Arguments:
- shape (
Shapeor Tag): The shape in question.
762def move(shape, x_shift=0, y_shift=0): 763 """ 764 Purpose: Move the x and y position of all shapes that have been tagged 765 with the tag argument 766 767 Args: 768 shape (`Shape` or Tag): The shape in question. 769 x_shift (`int`; optional): amount to move in the x direction 770 y_shift (`int`; optional): amount to move in the y direction 771 """ 772 shape_ids = _a_canvas.find_withtag(shape) 773 for id in shape_ids 774 _a_canvas.move(id, x_shift, y_shift)
Purpose: Move the x and y position of all shapes that have been tagged with the tag argument
Arguments:
- shape (
Shapeor Tag): The shape in question. - x_shift (
int; optional): amount to move in the x direction - y_shift (
int; optional): amount to move in the y direction
777def move_to(tag, to, anchor="center"): 778 """ 779 Move the given tagged item to a particular `point` maintaining some `anchor`. 780 Note: this is NOT the same as the `move` function which moves an object by a specific amount. 781 782 Args: 783 tag (Shape or `str`): the shape (or shapes) to move 784 to (`tuple`): the `(x, y)` coordinate to which you wish to move the tagged object 785 anchor (`str`): which point on the shape do you want to move toward the given tuple. You can 786 use either `"center"` (default), `"top_left"`, `"top_right"`, `"bottom_left"`, or `"bottom_right"`. 787 """ 788 anchor_options = ["center", "top_left", "top_right", "bottom_left", "bottom_right"] 789 if anchor not in anchor_options 790 raise ValueError( 791 "The anchor input must be one of " 792 + (anchor_options) 793 + " but instead we found " 794 + (anchor) 795 ) 796 797 outline = _get_outline(tag) 798 delta_x = 0 799 delta_y = 0 800 801 if anchor == "top_left" 802 delta_x = to[0] - outline["left"] 803 delta_y = to[1] - outline["top"] 804 elif anchor == "top_right" 805 delta_x = to[0] - outline["right"] 806 delta_y = to[1] - outline["top"] 807 elif anchor == "bottom_right" 808 delta_x = to[0] - outline["right"] 809 delta_y = to[1] - outline["bottom"] 810 elif anchor == "bottom_left" 811 delta_x = to[0] - outline["left"] 812 delta_y = to[1] - outline["bottom"] 813 elif anchor == "center" 814 delta_x = to[0] - outline["center"][0] 815 delta_y = to[1] - outline["center"][1] 816 817 _a_canvas.move(tag, delta_x, delta_y)
Move the given tagged item to a particular point maintaining some anchor.
Note: this is NOT the same as the move function which moves an object by a specific amount.
Arguments:
- tag (Shape or
str): the shape (or shapes) to move - to (
tuple): the(x, y)coordinate to which you wish to move the tagged object - anchor (
str): which point on the shape do you want to move toward the given tuple. You can use either"center"(default),"top_left","top_right","bottom_left", or"bottom_right".
820def overlay(shape1, shape2, offset_x=0, offset_y=0): 821 """ 822 A reporter function that overlays shape1 onto shape2. It does this by moving shape 1"s center 823 to shape 2"s center, and then applying any specified offset. 824 Args: 825 shape1 (`Shape` or Tag): The first shape to use. 826 shape2 (`Shape` or Tag): The second shape to use. 827 offset_x (`int`): How much to shift shape 2 in the x-direction after centering it. 828 offset_y (`int`): How much to shift shape 2 in the x-direction after centering it. 829 830 Returns: 831 `Shape`: The modified shape1. 832 """ 833 center1 = get_center(shape1) 834 center2 = get_center(shape2) 835 _a_canvas.move( 836 shape1, 837 (center2[0] - center1[0]) + offset_x, 838 (center2[1] - center1[1]) + offset_y, 839 ) 840 _a_canvas.tag_raise(shape1, shape2) 841 return shape1
A reporter function that overlays shape1 onto shape2. It does this by moving shape 1's center to shape 2's center, and then applying any specified offset.
Arguments:
- shape1 (
Shapeor Tag): The first shape to use. - shape2 (
Shapeor Tag): The second shape to use. - offset_x (
int): How much to shift shape 2 in the x-direction after centering it. - offset_y (
int): How much to shift shape 2 in the x-direction after centering it.
Returns:
Shape: The modified shape1.
844def portion(shape, start=0, end=0.5): 845 """ 846 Purpose: Take a slice or portion of some already created shape. 847 848 Args: 849 shape (`Shape` or Tag): The shape to take a portion of 850 start (`float`): A number between 0 and 1 representing where to start the slice. 851 end (`float`): A number between 0 and 1 representing where to end the slice. 852 853 For example, taking a portion from 0 to 0.5 of a circle would result in a semi-circle. 854 855 Note: this function is experimental. It might produce unexpected results! 856 """ 857 all_shapes = _a_canvas.find_withtag(shape) 858 859 for a_shape in all_shapes 860 coords = _a_canvas.coords(a_shape) 861 862 start_coord = floor(start * len(coords)) 863 if start_coord % 2 == 1 864 start_coord = start_coord - 1 # need to start with an x,y pair 865 end_coord = floor(end * len(coords)) 866 if end_coord % 2 == 1 867 end_coord = end_coord - 1 # need to end with an x,y pair 868 869 # slice is up to not including so get the last x,y pair 870 new_coords = coords[start_coord end_coord + 2] 871 872 # loop shape back in on itself 873 new_coords.append(new_coords[0]) 874 new_coords.append(new_coords[1]) 875 876 # set the coordinates: 877 _a_canvas.coords(a_shape, new_coords)
Purpose: Take a slice or portion of some already created shape.
Arguments:
- shape (
Shapeor Tag): The shape to take a portion of - start (
float): A number between 0 and 1 representing where to start the slice. - end (
float): A number between 0 and 1 representing where to end the slice.
For example, taking a portion from 0 to 0.5 of a circle would result in a semi-circle.
Note: this function is experimental. It might produce unexpected results!
880def put_in_back(shape): 881 """ 882 A function that "lowers" a shape to the "bottom" of the screen." 883 884 Args: 885 shape (`Shape` or Tag): The shape in question. 886 """ 887 _a_canvas.tag_lower(shape)
A function that "lowers" a shape to the "bottom" of the screen."
Arguments:
- shape (
Shapeor Tag): The shape in question.
890def put_in_front(shape): 891 """ 892 A function that "raises" a shape to the "top" of the screen." 893 894 Args: 895 shape (`Shape` or Tag): The shape in question. 896 """ 897 _a_canvas.tag_raise(shape)
A function that "raises" a shape to the "top" of the screen."
Arguments:
- shape (
Shapeor Tag): The shape in question.
900def rotate(shape, degrees=5, origin=None): 901 """ 902 A reporter function that takes a shape and rotates it by a specified amount around a specified point. 903 It does this by interpolating a polygon around the shape and calculating the shifts of individual 904 points on the edge of the polygon. 905 906 Args: 907 shape (`Shape` or Tag): The shape to rotate. 908 degrees (`int`): The number of degrees to rotate the shape. 909 origin (`tuple`): An `(x,y)` coordinate about which to perform the rotation. Defaults to the center 910 of the given shape. 911 912 Returns: 913 `Shape`: The modified shape. 914 """ 915 if origin is None 916 origin = get_center(shape) 917 918 theta = radians(degrees) 919 ox, oy = origin 920 921 all_shapes = _a_canvas.find_withtag(shape) 922 923 for a_shape in all_shapes 924 coords = _a_canvas.coords(a_shape) 925 # update coordinates: 926 for i in range(0, len(coords), 2): 927 px, py = coords[i], coords[i + 1] 928 qx = cos(theta) * (px - ox) - sin(theta) * (py - oy) + ox 929 qy = sin(theta) * (px - ox) + cos(theta) * (py - oy) + oy 930 coords[i] = qx 931 coords[i + 1] = qy 932 # set the coordinates: 933 _a_canvas.coords(a_shape, coords) 934 935 return shape
A reporter function that takes a shape and rotates it by a specified amount around a specified point. It does this by interpolating a polygon around the shape and calculating the shifts of individual points on the edge of the polygon.
Arguments:
- shape (
Shapeor Tag): The shape to rotate. - degrees (
int): The number of degrees to rotate the shape. - origin (
tuple): An(x,y)coordinate about which to perform the rotation. Defaults to the center of the given shape.
Returns:
Shape: The modified shape.
938def scale(shape, x_scale=1.0, y_scale=1.0): 939 """ 940 A function that takes a given `Shape` or tag and scales it on either/both the x and y-axis. 941 942 The two optional inputs accept floats between 0.0 and 1.0. Values greater than 1 will cause 943 the shape to grow along that access. Values less than 1.0 will cause the shape to shrink. 944 945 Args: 946 shape (`Shape` or Tag): The shape or tag to re-fill. 947 x_scale (`float`): How much to scale in the x-axis. 948 y_scale (`float`): How much to scale in the y-axis. 949 """ 950 ids = _a_canvas.find_withtag(shape) 951 952 coord = get_center(shape) 953 954 for i in ids 955 _a_canvas.scale(i, coord[0], coord[1], x_scale, y_scale)
A function that takes a given Shape or tag and scales it on either/both the x and y-axis.
The two optional inputs accept floats between 0.0 and 1.0. Values greater than 1 will cause the shape to grow along that access. Values less than 1.0 will cause the shape to shrink.
Arguments:
- shape (
Shapeor Tag): The shape or tag to re-fill. - x_scale (
float): How much to scale in the x-axis. - y_scale (
float): How much to scale in the y-axis.
958def underlay(shape1, shape2, offset_x=0, offset_y=0): 959 """ 960 A reporter function that underlays shape1 beneath shape2. It does this by moving shape 1"s center 961 to shape 2"s center, and then applying any specified offset. 962 Args: 963 shape1 (`Shape` or Tag): The first shape to use. 964 shape2 (`Shape` or Tag): The second shape to use. 965 offset_x (`int`): How much to shift shape 2 in the x-direction after centering it. 966 offset_y (`int`): How much to shift shape 2 in the x-direction after centering it. 967 968 Returns: 969 `Shape`: The modified shape1. 970 """ 971 center1 = get_center(shape1) 972 center2 = get_center(shape2) 973 _a_canvas.move( 974 shape1, 975 (center2[0] - center1[0]) + offset_x, 976 (center2[1] - center1[1]) + offset_y, 977 ) 978 _a_canvas.tag_lower(shape1, shape2) 979 return shape1
A reporter function that underlays shape1 beneath shape2. It does this by moving shape 1's center to shape 2's center, and then applying any specified offset.
Arguments:
- shape1 (
Shapeor Tag): The first shape to use. - shape2 (
Shapeor Tag): The second shape to use. - offset_x (
int): How much to shift shape 2 in the x-direction after centering it. - offset_y (
int): How much to shift shape 2 in the x-direction after centering it.
Returns:
Shape: The modified shape1.
985def clear_window(keep_grid=True): 986 """ 987 A function that deletes everything from the window. 988 989 Args: 990 keep_grid (`bool`): Whether or not to keep the grid. 991 """ 992 all_shapes = _a_canvas.find_all() 993 994 for shape in all_shapes 995 tags = _a_canvas.gettags(shape) 996 if "grid" in tags and keep_grid 997 continue 998 _a_canvas.delete(shape) 999 1000 global _resize_enabled 1001 _resize_enabled = True
A function that deletes everything from the window.
Arguments:
- keep_grid (
bool): Whether or not to keep the grid.
1004def distance(point1, point2): 1005 """ 1006 A reporter function calculates the distance between two `(x, y)` coordinates. 1007 1008 Args: 1009 point1 (`tuple`): The first `(x, y)` coordinate. 1010 point2 (`tuple`): The second `(x, y)` coordinate. 1011 1012 Returns: 1013 A `float` representing the distance between the two points. 1014 """ 1015 return sqrt(((point1[0] - point2[0]) 2) + ((point1[1] - point2[1]) 2))
A reporter function calculates the distance between two (x, y) coordinates.
Arguments:
- point1 (
tuple): The first(x, y)coordinate. - point2 (
tuple): The second(x, y)coordinate.
Returns:
A
floatrepresenting the distance between the two points.
1018def does_tag_exist(tag): 1019 """ 1020 Returns `True` if a given tag exists otherwise returns `False`. 1021 1022 Args: 1023 `tag` (`str`): [Required] The tag of the object to lookup. 1024 1025 """ 1026 result = _a_canvas.find_withtag(tag) 1027 1028 if result 1029 return True 1030 else 1031 return False
Returns True if a given tag exists otherwise returns False.
Arguments:
tag(str): [Required] The tag of the object to lookup.
1034def get_bottom(shape): 1035 """ 1036 A reporter function calculates the maximum y-value of a given shape (since the y-axis is flipped). 1037 1038 Args: 1039 shape (`Shape` or Tag): The shape in question. 1040 1041 Returns: 1042 A `int` representing the maximum y-coordinate of the shape. 1043 """ 1044 bbox = _safe_bbox(shape) 1045 return bbox[3]
A reporter function calculates the maximum y-value of a given shape (since the y-axis is flipped).
Arguments:
- shape (
Shapeor Tag): The shape in question.
Returns:
A
intrepresenting the maximum y-coordinate of the shape.
1048def get_center(shape): 1049 """ 1050 A reporter function calculates the a coordinate at the center of some shape. 1051 1052 Args: 1053 shape (`Shape` or Tag): The shape in question. 1054 1055 Returns: 1056 A `tuple` representing center of the given shape. 1057 """ 1058 bbox = _safe_bbox(shape) 1059 1060 if bbox is None 1061 raise Exception( 1062 f"We couldn"t find the shape with id/tag {shape}. Make sure it exists!" 1063 ) 1064 1065 return (((bbox[2] + bbox[0]) / 2), ((bbox[1] + bbox[3]) / 2))
A reporter function calculates the a coordinate at the center of some shape.
Arguments:
- shape (
Shapeor Tag): The shape in question.
Returns:
A
tuplerepresenting center of the given shape.
1068def get_colors(shape_or_shapes): 1069 """ 1070 A reporter function that returns all the colors associated with a tag or list of tags. 1071 1072 Args: 1073 shape_or_shapes (`str`/`Shape` or `List`): the shape/tag or list of shapes/tags you"d like to find the colors of 1074 1075 Returns: 1076 A `List` containing all unique colors associated with that tag(s) 1077 """ 1078 all_shapes = [] 1079 if not isinstance(shape_or_shapes, ): 1080 shape_or_shapes = [shape_or_shapes] 1081 for shape in shape_or_shapes 1082 all_shapes += _a_canvas.find_withtag(shape) 1083 1084 all_colors = [] 1085 for shape in all_shapes 1086 color = _a_canvas.itemcget(shape, "fill") 1087 if color not in all_colors 1088 all_colors.append(color) 1089 1090 return all_colors
A reporter function that returns all the colors associated with a tag or list of tags.
Arguments:
- shape_or_shapes (
str/ShapeorList): the shape/tag or list of shapes/tags you'd like to find the colors of
Returns:
A
Listcontaining all unique colors associated with that tag(s)
1093def get_height(shape): 1094 """ 1095 A reporter function calculates the height of some given shape. 1096 1097 Args: 1098 shape (`Shape` or Tag): The shape in question. 1099 1100 Returns: 1101 A `int` representing the height of the shape. 1102 """ 1103 bbox = _safe_bbox(shape) 1104 return bbox[3] - bbox[1] - 1
A reporter function calculates the height of some given shape.
Arguments:
- shape (
Shapeor Tag): The shape in question.
Returns:
A
intrepresenting the height of the shape.
1107def get_left(shape): 1108 """ 1109 A reporter function calculates the minimum x-value of a given shape. 1110 1111 Args: 1112 shape (`Shape` or Tag): The shape in question. 1113 1114 Returns: 1115 A `int` representing the minimum x-coordinate of the shape. 1116 """ 1117 bbox = _safe_bbox(shape) 1118 return bbox[0]
A reporter function calculates the minimum x-value of a given shape.
Arguments:
- shape (
Shapeor Tag): The shape in question.
Returns:
A
intrepresenting the minimum x-coordinate of the shape.
1121def get_right(shape): 1122 """ 1123 A reporter function calculates the maximum x-value of a given shape. 1124 1125 Args: 1126 shape (`Shape` or Tag): The shape in question. 1127 1128 Returns: 1129 A `int` representing the maximum x-coordinate of the shape. 1130 """ 1131 bbox = _safe_bbox(shape) 1132 return bbox[2]
A reporter function calculates the maximum x-value of a given shape.
Arguments:
- shape (
Shapeor Tag): The shape in question.
Returns:
A
intrepresenting the maximum x-coordinate of the shape.
1135def get_tag_from_event(event, precision=25): 1136 """ 1137 Tries to return a tag of an object at a given mouse-event. 1138 1139 Args: 1140 event (`Event`): Must be a mouse event otherwise we"ll give back an error. 1141 precision (`int`): How precise in number of pixels does a user have be in order to "select" an object 1142 1143 Returns a blank string `""` if no shapes are found closer than `precision`. 1144 """ 1145 1146 if (event.type) not in [4, 6]: 1147 raise Exception(f"Received an event that isn"t a mouse event: {event}") 1148 1149 try 1150 x = event.x 1151 y = event.y 1152 shape_id = _a_canvas.find_closest(x, y) # get the top shape 1153 if shape_id and distance(get_center(shape_id), (x, y)) < precision 1154 tags = _a_canvas.gettags(shape_id) 1155 if len(tags) > 0 1156 return tags[0] 1157 return "" 1158 1159 except 1160 raise Exception( 1161 "No tag found! Maybe you passed us an event that isn"t a mouse event?" 1162 )
Tries to return a tag of an object at a given mouse-event.
Arguments:
- event (
Event): Must be a mouse event otherwise we'll give back an error. - precision (
int): How precise in number of pixels does a user have be in order to "select" an object
Returns a blank string "" if no shapes are found closer than precision.
1165def get_top(shape): 1166 """ 1167 A reporter function calculates the minimum y-value of a given shape (since the y-axis is flipped). 1168 1169 Args: 1170 shape (`Shape` or Tag): The shape in question. 1171 1172 Returns: 1173 A `int` representing the minimum y-coordinate of the shape. 1174 """ 1175 bbox = _safe_bbox(shape) 1176 return bbox[1]
A reporter function calculates the minimum y-value of a given shape (since the y-axis is flipped).
Arguments:
- shape (
Shapeor Tag): The shape in question.
Returns:
A
intrepresenting the minimum y-coordinate of the shape.
1179def get_width(shape): 1180 """ 1181 A reporter function calculates the width of some given shape. 1182 1183 Args: 1184 shape (`Shape` or Tag): The shape in question. 1185 1186 Returns: 1187 An `int` representing width of the shape. 1188 """ 1189 bbox = _safe_bbox(shape) 1190 return bbox[2] - bbox[0] - 1
A reporter function calculates the width of some given shape.
Arguments:
- shape (
Shapeor Tag): The shape in question.
Returns:
An
intrepresenting width of the shape.
1193def get_window_height(): 1194 """ 1195 A reporter function that returns the current height of the window. 1196 1197 Returns: 1198 An `int` representing height of the window. 1199 """ 1200 return _a_canvas.winfo_height()
A reporter function that returns the current height of the window.
Returns:
An
intrepresenting height of the window.
1203def get_window_width(): 1204 """ 1205 A reporter function that returns the current width of the window. 1206 1207 Returns: 1208 An `int` representing width of the window. 1209 """ 1210 return _a_canvas.winfo_width()
A reporter function that returns the current width of the window.
Returns:
An
intrepresenting width of the window.
1213def interpolate_colors(color1, color2, frac): 1214 """ 1215 A reporter function that generates a new color between two given colors. 1216 Args: 1217 color1 (`str`): The path of the file to wrap 1218 color2 (`str`): The path of the file to wrap 1219 frac (`float`): What fraction of each color to take. An input of 0 returns 1220 color1, an input of 1 returns color2, an input of 0.5 returns a color 1221 perfectly between the two. 1222 1223 Returns: 1224 A color (as a hex `str`) to be used elsewhere 1225 """ 1226 if "#" not in color1 1227 color1 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color1))) 1228 else 1229 color1 = _tupelize_color(color1) 1230 if "#" not in color2 1231 color2 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color2))) 1232 else 1233 color2 = _tupelize_color(color2) 1234 return _interpolate_tuple(color1, color2, frac)
A reporter function that generates a new color between two given colors.
Arguments:
- color1 (
str): The path of the file to wrap - color2 (
str): The path of the file to wrap - frac (
float): What fraction of each color to take. An input of 0 returns color1, an input of 1 returns color2, an input of 0.5 returns a color perfectly between the two.
Returns:
A color (as a hex
str) to be used elsewhere
1237def random_color(): 1238 """ 1239 Returns a random color as a `string` to be used. 1240 It does not accept any inputs. 1241 """ 1242 r = lambda randint(0, 255) 1243 return "#%02X%02X%02X" % (r(), r(), r())
Returns a random color as a string to be used.
It does not accept any inputs.
1246def setup_listener(event_str, handler_function, override=False): 1247 """ 1248 Sets up a listener for a given event on our window. 1249 1250 Args: 1251 event_str (`str`): The magic string that represents this event in the window 1252 handler_function (`func`): The name (not a string though) of the function you want called when the event his heard 1253 override (`bool`): Only use this if you speak to Prof. Bain and he recommends it. 1254 1255 The supported events are: 1256 * `"LEFT-CLICK"`: Left mouse click 1257 * `"RIGHT-CLICK"`: Right mouse click 1258 * `"ALT-CLICK"`: If you"re using a PC, this event might instead work for Right Click 1259 * `"LEFT-DRAG"`: Left mouse clicked and dragged on the screen 1260 * `"RIGHT-DRAG"`: Right mouse clicked and dragged on the screen 1261 * `"ALT-DRAG"`: For PCs, this event might instead work for RIGHT-DRAG 1262 * `"DOUBLE-LEFT"`: Left mouse double click 1263 * `"DOUBLE-RIGHT"`: Right mouse double click 1264 * `"DOUBLE-ALT"`: For PCs, this event might instead work for DOUBLE-RIGHT 1265 * `"KEY"`: The catch-all event for Keyboard presses 1266 """ 1267 1268 event_translator = { 1269 "LEFT-CLICK" "<Button-1>", 1270 "RIGHT-CLICK" "<Button-2>", 1271 "ALT-CLICK" "<Button-3>", 1272 "LEFT-DRAG" "<B1-Motion>", 1273 "RIGHT-DRAG" "<B2-Motion>", 1274 "ALT-DRAG" "<B3-Motion>", 1275 "DOUBLE-LEFT" "<Double-Button-1>", 1276 "DOUBLE-RIGHT" "<Double-Button-2>", 1277 "DOUBLE-ALT" "<Double-Button-3>", 1278 "KEY" "<Key>", 1279 } 1280 1281 if event_str not in event_translator and not override 1282 raise ( 1283 TypeError( 1284 f"The event you entered, {event_str}, isn"t supported. Here are the supported events: {[i for i in event_translator]}" 1285 ) 1286 ) 1287 1288 event = event_translator[event_str] 1289 1290 setup_listener.tracker.add(event_str) 1291 1292 _a_canvas.bind(event, handler_function)
Sets up a listener for a given event on our window.
Arguments:
- event_str (
str): The magic string that represents this event in the window - handler_function (
func): The name (not a string though) of the function you want called when the event his heard - override (
bool): Only use this if you speak to Prof. Bain and he recommends it.
The supported events are:
"LEFT-CLICK": Left mouse click"RIGHT-CLICK": Right mouse click"ALT-CLICK": If you're using a PC, this event might instead work for Right Click"LEFT-DRAG": Left mouse clicked and dragged on the screen"RIGHT-DRAG": Right mouse clicked and dragged on the screen"ALT-DRAG": For PCs, this event might instead work for RIGHT-DRAG"DOUBLE-LEFT": Left mouse double click"DOUBLE-RIGHT": Right mouse double click"DOUBLE-ALT": For PCs, this event might instead work for DOUBLE-RIGHT"KEY": The catch-all event for Keyboard presses
1296def setup_shapes(title, background="white", include_grid=True, width=600, height=600): 1297 """ 1298 A static function that sets up the pop-up window. You can specify the size of the window here. 1299 1300 However, you should NOT add any calls to this function unless Prof. Bain specifically tells you to! 1301 1302 Args: 1303 title (`str`): The title of the pop-up window. 1304 background (`str`): A valid color as a string to be used as the background color. 1305 include_grid (`bool`): Whether or not to draw the grid. 1306 width (`int` or `str`): How wide the window should appear (advanced: use the string "FULLWIDTH" to maximize the width) 1307 height (`int` or `str`): How wide the window should appear (advanced: use the string "FULLHEIGHT" to maximize the width) 1308 """ 1309 1310 global _a_canvas 1311 gui = Tk() 1312 gui.title(title) 1313 1314 if width == "FULLWIDTH" 1315 width = gui.winfo_screenwidth() 1316 1317 if height == "FULLHEIGHT" 1318 height = gui.winfo_screenheight() 1319 1320 _a_canvas = Canvas(gui, background=background, width=width, height=height) 1321 _a_canvas.pack() 1322 if include_grid 1323 grid(width, height) 1324 1325 _a_canvas.focus_set() 1326 return _a_canvas
A static function that sets up the pop-up window. You can specify the size of the window here.
However, you should NOT add any calls to this function unless Prof. Bain specifically tells you to!
Arguments:
- title (
str): The title of the pop-up window. - background (
str): A valid color as a string to be used as the background color. - include_grid (
bool): Whether or not to draw the grid. - width (
intorstr): How wide the window should appear (advanced: use the string "FULLWIDTH" to maximize the width) - height (
intorstr): How wide the window should appear (advanced: use the string "FULLHEIGHT" to maximize the width)
1329def update(): 1330 """ 1331 A static function that sets up the pop-up window. DO NOT USE THIS FUNCTION unless Prof. Bain explictly says to use it. 1332 """ 1333 _a_canvas.update()
A static function that sets up the pop-up window. DO NOT USE THIS FUNCTION unless Prof. Bain explictly says to use it.