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