cs110_t3_shapes

   1### IGNORE EVERYTHING THAT STARTS WITH A _
   2from random import randint
   3from math import sqrt, pi, radians, sin, cos, floor
   4
   5__docformat__ = "google"
   6
   7_a_canvas = None
   8
   9def _safe_color(color):
  10    color = color.strip()
  11    # Could also do some other verifications here...
  12    return color
  13
  14def rectangle(
  15    top_left=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 
  16):
  17    """
  18    A reporter function that draws a rectangle.
  19    Args:
  20        top_left (`tuple`): A coordinate representing the top left-hand corner of the shape.
  21        width (`int`): How wide to draw the shape.
  22        height (`int`): How tall to draw the shape.
  23        color (`str`): What color to draw the shape.
  24        outline (`str`): What color should the border of the shape be.
  25        tag (`str`): The tag to assign to the shape.
  26
  27    Returns:
  28         `Shape`: The rectangle that was created.
  29    """
  30    point_0 = top_left
  31    point_1 = (top_left[0] + width, top_left[1])
  32    point_2 = (top_left[0] + width, top_left[1] + height)
  33    point_3 = (top_left[0], top_left[1] + height)
  34    return _a_canvas.create_polygon(
  35        point_0, point_1, point_2, point_3, fill=_safe_color(color), tags=tag, 
  36    )
  37
  38
  39def square(top_left=(0, 0), size=25, color="hot pink", outline="", tag="", ):
  40    """
  41    A reporter function that draws a square.
  42    Args:
  43        top_left (`tuple`): A coordinate representing the top left-hand corner of the shape.
  44        size (`int`): How big to draw the shape.
  45        color (`str`): What color to draw the shape.
  46        outline (`str`): What color should the border of the shape be.
  47        tag (`str`): The tag to assign to the shape.
  48
  49    Returns:
  50         `Shape`: The square that was created.
  51    """
  52    return rectangle(
  53        top_left=top_left, width=size, height=size, color=color, tag=tag, 
  54    )
  55
  56
  57def oval(
  58    center=(0, 0),
  59    radius_x=25,
  60    radius_y=50,
  61    color="hot pink",
  62    outline="",
  63    tag="",
  64    ,
  65):
  66    """
  67    A reporter function that draws an oval.
  68    Args:
  69        center (`tuple`): A coordinate representing the center of the shape.
  70        radius_x (`int`): Specifies the oval"s radius on the x-axis.
  71        radius_y (`int`): Specifies the oval"s radius on the y-axis.
  72        color (`str`): What color to draw the shape.
  73        outline (`str`): What color should the border of the shape be.
  74        tag (`str`): The tag to assign to the shape.
  75
  76    Returns:
  77         `Shape`: The oval that was created.
  78    """
  79    x = center[0]
  80    y = center[1]
  81    x0, y0, x1, y1 = (x - radius_x, y - radius_y, x + radius_x, y + radius_y)
  82    steps = 100
  83    # major and minor axes
  84    a = (x1 - x0) / 2.0
  85    b = (y1 - y0) / 2.0
  86    # center
  87    xc = x0 + a
  88    yc = y0 + b
  89    point_list = []
  90    # create the oval as a list of points
  91    for i in range(steps):
  92        # Calculate the angle for this step
  93        theta = (pi * 2) * (float(i) / steps)
  94        x = a * cos(theta)
  95        y = b * sin(theta)
  96        point_list.append(round(x + xc))
  97        point_list.append(round(y + yc))
  98
  99    return _a_canvas.create_polygon(
 100        point_list, fill=_safe_color(color), tags=tag, 
 101    )
 102
 103
 104def circle(center=(0, 0), radius=25, color="hot pink", outline="", tag="", ):
 105    """
 106    A reporter function that draws a circle.
 107    Args:
 108        center (`tuple`): A coordinate representing the center of the shape.
 109        radius (`int`): Specifies the circle"s radius.
 110        color (`str`): What color to draw the shape.
 111        outline (`str`): What color should the border of the shape be.
 112        tag (`str`): The tag to assign to the shape.
 113
 114    Returns:
 115         `Shape`: The circle that was created.
 116    """
 117    return oval(
 118        center=center, radius_x=radius, radius_y=radius, color=color, tag=tag, 
 119    )
 120
 121
 122def wedge(
 123    center=(0, 0), radius=25, angle=180, color="hot pink", outline="", tag="", 
 124):
 125    """
 126    A reporter function that draws a circle.
 127    Args:
 128        center (`tuple`): A coordinate representing the center of the shape.
 129        radius (`int`): Specifies the circle"s radius.
 130        angle (`int`): A number between 0 and 360 that specifies how much of the circle to draw.
 131        color (`str`): What color to draw the shape.
 132        outline (`str`): What color should the border of the shape be.
 133        tag (`str`): The tag to assign to the shape.
 134
 135    Returns:
 136         `Shape`: The wedge that was created.
 137    """
 138    point_list = [center[0], center[1]]
 139    for i in range(0, 0 + angle):
 140        x1 = center[0] + radius * cos(radians(i))
 141        point_list.append(x1)
 142        y1 = center[1] + radius * sin(radians(i))
 143        point_list.append(y1)
 144
 145    point_list.append(center[0])
 146    point_list.append(center[1])
 147
 148    return _a_canvas.create_polygon(
 149        point_list, fill=_safe_color(color), outline=outline, tags=tag, 
 150    )
 151
 152
 153def triangle(
 154    bottom_center=(0, 0),
 155    width=25,
 156    top_shift=0,
 157    height=0,
 158    color="hot pink",
 159    outline="",
 160    tag="",
 161    ,
 162):
 163    """
 164    A reporter function that draws a triangle.
 165    Args:
 166        bottom_center (`tuple`): A coordinate representing the bottom center of the shape.
 167        width (`int`): Specifies the width of the base of the triangle.
 168        top_shift (`int`): Specifies the how far to the left or right to shift the top of
 169            the triangle from the bottom center.
 170        height (`int`): Specifies the triangle"s height.
 171        color (`str`): What color to draw the shape.
 172        outline (`str`): What color should the border of the shape be.
 173        tag (`str`): The tag to assign to the shape.
 174
 175    Returns:
 176         `Shape`: The triangle that was created.
 177    """
 178    if height == 0
 179        height = width * sqrt(3) / 2
 180    point_0 = (bottom_center[0] - width / 2, bottom_center[1])
 181    point_1 = (bottom_center[0] + width / 2, bottom_center[1])
 182    point_2 = (bottom_center[0] + top_shift, bottom_center[1] - height)
 183
 184    return _a_canvas.create_polygon(
 185        point_0, point_1, point_2, fill=_safe_color(color), tags=tag, 
 186    )
 187
 188
 189def line(points=[], curvy=False, color="hot pink", tag="", ):
 190    """
 191    A reporter function that draws a line given a list of points.
 192    Args:
 193        points (`list`): The points that define the line; this should be a list of tuples (coordinates).
 194        curvy (`bool`): Makes a curvy line instead.
 195        color (`str`): What color to make the shape.
 196        tag (`str`): The tag to assign to the shape.
 197
 198    Returns:
 199        `Shape`: The line that was created.
 200    """
 201    return _a_canvas.create_line(points, fill=color, smooth=curvy, tags=tag, )
 202
 203
 204def arc(points=[], width=5, color="hot pink", line_steps=15, tag="", ):
 205    """
 206    A reporter function that draws an arc ("curve") given a list of points.
 207    Args:
 208        points (`list`): The points outlining the curve; this should be a list of tuples (coordinates).
 209            Make sure to give it at least 3 (x,y) coordinates that aren"t a straight line!
 210        color (`str`): What color to make the shape.
 211        tag (`str`): The tag to assign to the shape.
 212
 213    Returns:
 214        `Shape`: The arc that was created.
 215    """
 216    return _a_canvas.create_line(
 217        points,
 218        width=width,
 219        fill=color,
 220        splinesteps=line_steps,
 221        smooth=True,
 222        tags=tag,
 223        ,
 224    )
 225
 226
 227def diamond(
 228    center=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 
 229):
 230    """
 231    A reporter function that draws a rectangle.
 232    Args:
 233        center (`tuple`): A coordinate representing the center of the shape.
 234        width (`int`): How wide to draw the shape.
 235        height (`int`): How tall to draw the shape.
 236        color (`str`): What color to draw the shape.
 237        outline (`str`): What color should the border of the shape be.
 238        tag (`str`): The tag to assign to the shape.
 239
 240    Returns:
 241         `Shape`: The shape that was created.
 242    """
 243    point_0 = (center[0] - width / 2, center[1])
 244    point_1 = (center[0], center[1] - height / 2)
 245    point_2 = (center[0] + width / 2, center[1])
 246    point_3 = (center[0], center[1] + height / 2)
 247    return _a_canvas.create_polygon(
 248        point_0,
 249        point_1,
 250        point_2,
 251        point_3,
 252        fill=_safe_color(color),
 253        tags=tag,
 254        outline=outline,
 255        ,
 256    )
 257
 258
 259def star(
 260    center=(0, 0),
 261    radius=50,
 262    color="hot pink",
 263    outer_radius=75,
 264    points=5,
 265    outline="",
 266    tag="",
 267    ,
 268):
 269    """
 270    A reporter function that draws a star.
 271    Args:
 272        center (`tuple`): A coordinate representing the center of the shape.
 273        radius (`int`): Specifies the radius of the inside part of the star.
 274        color (`str`): Specifies the color of the star.
 275        outer_radius (`int`): Specifies the radius of the outside part of the star.
 276        points (`int`): Specifies the number of points for the star.
 277        outline (`str`): What color should the border of the shape be.
 278        tag (`str`): The tag to assign to the shape.
 279
 280    Returns:
 281         `Shape`: The star that was created.
 282    """
 283    arc_segment = 360 / points
 284    vertices = []
 285    for i in range(points):
 286        inner_point = (
 287            radius * cos(radians(arc_segment * i)) + center[0],
 288            -1 * radius * sin(radians(arc_segment * i)) + center[1],
 289        )
 290        vertices.append(inner_point)
 291        outer_point = (
 292            outer_radius * cos(radians(arc_segment * i + arc_segment / 2)) + center[0],
 293            -1 * outer_radius * sin(radians(arc_segment * i + arc_segment / 2))
 294            + center[1],
 295        )
 296        vertices.append(outer_point)
 297    return polygon(vertices, color=color, tag=tag, )
 298
 299
 300def polygon(points=[], color="hot pink", outline="", tag="", ):
 301    """
 302    A reporter function that draws a polygon given a list of points.
 303    Args:
 304        points (`list`): The points outlining the polygon; this should be a list of tuples (coordinates).
 305            defaults to an empty list.
 306        outline (`str`): What color should the border of the shape be.
 307        color (`str`): What color to make the shape.
 308
 309    Returns:
 310        `Shape`: The polygon that was created.
 311    """
 312    return _a_canvas.create_polygon(points, fill=_safe_color(color), tags=tag, )
 313
 314
 315def _polar_to_cartesian(r, theta):
 316    return (r * cos(theta)), (r * sin(theta))
 317
 318
 319def spiral(
 320    center=(0, 0), width=100, roughness=0.01, start=0, spirals=5, line_width=1, 
 321):
 322    """
 323    A reporter function that draws a spiral.
 324    Args:
 325        center (`tuple`): A coordinate representing the center of the shape.
 326        width (`int`): Specifies the total width of the spiral.
 327        roughness (`float`): Controls how spiral-y the shape is (lower is less spiral-y)
 328        start (`int`): Where on the spiral to start drawing.
 329        spirals (`int`): How many loops to draw.
 330        line_width (`int`): How wide for the line to be drawn.
 331        tag (`str`): The tag to assign to the shape.
 332
 333    Returns:
 334         `Shape`: The spiral that was created.
 335    """
 336    theta = 0.0
 337    r = start
 338    all_points = []
 339    prev_pos = _polar_to_cartesian(r, theta)
 340    distance = width / 4 / pi / spirals
 341    all_points.append((prev_pos[0] + center[0], prev_pos[1] + center[1]))
 342    while theta < 2 * spirals * pi
 343        theta += roughness
 344        r = start + distance * theta
 345        pos = _polar_to_cartesian(r, theta)
 346        all_points.append((pos[0] + center[0], pos[1] + center[1]))
 347
 348    return arc(points=all_points, width=line_width, )
 349
 350
 351def move(shape, x_shift=0, y_shift=0):
 352    """
 353    Purpose: Move the x and y position of all shapes that have been tagged
 354    with the tag argument
 355
 356    Args:
 357        shape (`Shape` or Tag): The shape in question.
 358        x_shift (`int`; optional): amount to move in the x direction
 359        y_shift (`int`; optional): amount to move in the y direction
 360    """
 361    shape_ids = _a_canvas.find_withtag(shape)
 362    for id in shape_ids
 363        _a_canvas.move(id, x_shift, y_shift)
 364
 365
 366def portion(shape, start=0, end=0.5):
 367    """
 368    Purpose: Take a slice or portion of some already created shape.
 369
 370    Args:
 371        shape (`Shape` or Tag): The shape to take a portion of
 372        start (`float`): A number between 0 and 1 representing where to start the slice.
 373        end (`float`): A number between 0 and 1 representing where to end the slice.
 374
 375    For example, taking a portion from 0 to 0.5 of a circle would result in a semi-circle.
 376
 377    Note: this function is experimental. It might produce unexpected results!
 378    """
 379    all_shapes = _a_canvas.find_withtag(shape)
 380
 381    for a_shape in all_shapes
 382        coords = _a_canvas.coords(a_shape)
 383
 384        start_coord = floor(start * len(coords))
 385        if start_coord % 2 == 1
 386            start_coord = start_coord - 1  # need to start with an x,y pair
 387        end_coord = floor(end * len(coords))
 388        if end_coord % 2 == 1
 389            end_coord = end_coord - 1  # need to end with an x,y pair
 390
 391        # slice is up to not including so get the last x,y pair
 392        new_coords = coords[start_coord  end_coord + 2]
 393
 394        # loop shape back in on itself
 395        new_coords.append(new_coords[0])
 396        new_coords.append(new_coords[1])
 397
 398        # set the coordinates:
 399        _a_canvas.coords(a_shape, new_coords)
 400
 401
 402def put_in_front(shape):
 403    """
 404    A function that "raises" a shape to the "top" of the screen."
 405
 406    Args:
 407        shape (`Shape` or Tag): The shape in question.
 408    """
 409    _a_canvas.tag_raise(shape)
 410
 411
 412def put_in_back(shape):
 413    """
 414    A function that "lowers" a shape to the "bottom" of the screen."
 415
 416    Args:
 417        shape (`Shape` or Tag): The shape in question.
 418    """
 419    _a_canvas.tag_lower(shape)
 420
 421
 422def _get_outline(shape):
 423    """
 424    A reporter function that takes in a shape and calls the various helper functions to generate
 425    a sort of "summary" of that particular shape and returns it in the form of a dictionary.
 426
 427    Args:
 428        shape (`Shape` or Tag): The shape in question.
 429
 430    Returns:
 431        a `Dictionary` with the various properties of the shape
 432    """
 433
 434    return {
 435        "center" get_center(shape),
 436        "left" get_left(shape),
 437        "right" get_right(shape),
 438        "top" get_top(shape),
 439        "bottom" get_bottom(shape),
 440    }
 441
 442
 443def align(shape1, shape2, via="middle", offset_x=0, offset_y=0):
 444    """
 445    A reporter function that aligns `shape1` with `shape2`. It does this by moving `shape1` to align with
 446    whatever property of `shape2` is selected with the `via` input.
 447
 448    Args:
 449        shape1 (`Shape` or Tag): The first shape to use.
 450        shape2 (`Shape` or Tag): The second shape to use.
 451        via (`str`): Has to be one of, the following options: `"center"` (horizontal center),
 452            `"middle"` (vertical center), `"top"`, `"bottom"`, `"left"`, or `"right"`
 453        offset_x (`int`): How much to shift in the x-axis after alignment
 454        offset_y (`int`): How much to shift in the y-axis after alignment
 455
 456    Returns:
 457        `Shape`: The modified shape1.
 458    """
 459    via_options = ["center", "middle", "top", "bottom", "left", "right"]
 460    if via not in via_options
 461        raise ValueError(
 462            "The via input must be one of "
 463            + (via_options)
 464            + " but instead we found "
 465            + (via)
 466        )
 467
 468    outline1 = _get_outline(shape1)
 469    outline2 = _get_outline(shape2)
 470
 471    if via == "center"
 472        _a_canvas.move(
 473            shape1, (outline2["center"][0] - outline1["center"][0]) + offset_x, offset_y
 474        )
 475
 476    elif via == "middle"
 477        _a_canvas.move(
 478            shape1, offset_x, (outline2["center"][1] - outline1["center"][1]) + offset_y
 479        )
 480
 481    elif via == "top"
 482        _a_canvas.move(shape1, offset_x, (outline2["top"] - outline1["top"]) + offset_y)
 483
 484    elif via == "bottom"
 485        _a_canvas.move(
 486            shape1, offset_x, (outline2["bottom"] - outline1["bottom"]) + offset_y
 487        )
 488
 489    elif via == "left"
 490        _a_canvas.move(
 491            shape1, (outline2["left"] - outline1["left"]) + offset_x, offset_y
 492        )
 493
 494    elif via == "right"
 495        _a_canvas.move(
 496            shape1, (outline2["right"] - outline1["right"]) + offset_x, offset_y
 497        )
 498
 499    return shape1
 500
 501
 502def overlay(shape1, shape2, offset_x=0, offset_y=0):
 503    """
 504    A reporter function that overlays shape1 onto shape2. It does this by moving shape 1"s center
 505    to shape 2"s center, and then applying any specified offset.
 506    Args:
 507        shape1 (`Shape` or Tag): The first shape to use.
 508        shape2 (`Shape` or Tag): The second shape to use.
 509        offset_x (`int`): How much to shift shape 2 in the x-direction after centering it.
 510        offset_y (`int`): How much to shift shape 2 in the x-direction after centering it.
 511
 512    Returns:
 513        `Shape`: The modified shape1.
 514    """
 515    center1 = get_center(shape1)
 516    center2 = get_center(shape2)
 517    _a_canvas.move(
 518        shape1,
 519        (center2[0] - center1[0]) + offset_x,
 520        (center2[1] - center1[1]) + offset_y,
 521    )
 522    _a_canvas.tag_raise(shape1, shape2)
 523    return shape1
 524
 525
 526def underlay(shape1, shape2, offset_x=0, offset_y=0):
 527    """
 528    A reporter function that underlays shape1 beneath shape2. It does this by moving shape 1"s center
 529    to shape 2"s center, and then applying any specified offset.
 530    Args:
 531        shape1 (`Shape` or Tag): The first shape to use.
 532        shape2 (`Shape` or Tag): The second shape to use.
 533        offset_x (`int`): How much to shift shape 2 in the x-direction after centering it.
 534        offset_y (`int`): How much to shift shape 2 in the x-direction after centering it.
 535
 536    Returns:
 537        `Shape`: The modified shape1.
 538    """
 539    center1 = get_center(shape1)
 540    center2 = get_center(shape2)
 541    _a_canvas.move(
 542        shape1,
 543        (center2[0] - center1[0]) + offset_x,
 544        (center2[1] - center1[1]) + offset_y,
 545    )
 546    _a_canvas.tag_lower(shape1, shape2)
 547    return shape1
 548
 549
 550def above(shape1, shape2, offset_x=0, offset_y=0):
 551    """
 552    A reporter function that places shape1 above shape2 (vertically). It does this by moving shape 1"s center
 553    to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any
 554    specified offset.
 555
 556    Args:
 557        shape1 (`Shape` or Tag): The first shape to use.
 558        shape2 (`Shape` or Tag): The second shape to use.
 559        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
 560        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
 561
 562    Returns:
 563        `Shape`: The modified shape1.
 564    """
 565    overlay(shape1, shape2)
 566    _a_canvas.move(
 567        shape1,
 568        0 + offset_x,
 569        -1 * (get_height(shape2) + get_height(shape1)) / 2 + offset_y,
 570    )
 571    return shape1
 572
 573
 574def beside(shape1, shape2, offset_x=0, offset_y=0):
 575    """
 576    A reporter function that places shape1 beside shape2 (horizontally). It does this by moving shape 1"s center
 577    to shape 2"s center, moving shape 1 in the x-direction the exact width of shape 2, and then applying any
 578    specified offset.
 579
 580    Args:
 581        shape1 (`Shape` or Tag): The first shape to use.
 582        shape2 (`Shape` or Tag): The second shape to use.
 583        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
 584        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
 585
 586    Returns:
 587        `Shape`: The modified shape1.
 588    """
 589    overlay(shape1, shape2)
 590    _a_canvas.move(
 591        shape1,
 592        (get_width(shape2) + get_width(shape1)) / 2 + offset_x,
 593        0 + offset_y,
 594    )
 595    return shape1
 596
 597
 598def below(shape1, shape2, offset_x=0, offset_y=0):
 599    """
 600    A reporter function that places shape1 below shape2 (vertically). It does this by moving shape 1"s center
 601    to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any
 602    specified offset.
 603
 604    Args:
 605        shape1 (`Shape` or Tag): The first shape to use.
 606        shape2 (`Shape` or Tag): The second shape to use.
 607        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
 608        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
 609
 610    Returns:
 611        `Shape`: The modified shape1.
 612    """
 613    overlay(shape1, shape2)
 614    _a_canvas.move(
 615        shape1,
 616        0 + offset_x,
 617        (get_height(shape2) + get_height(shape1)) / 2 + offset_y,
 618    )
 619    return shape1
 620
 621
 622def delete(shape):
 623    """
 624    A function that deletes a shape from our screen.
 625
 626    Args:
 627        shape (`Shape` or Tag): The shape to delete.
 628    """
 629    _a_canvas.delete(shape)
 630
 631
 632def duplicate(shape, color=None):
 633    """
 634    A reporter function that perfectly copies a shape and returns that copy.
 635
 636    Args:
 637        shape (`Shape` or Tag): The shape to duplicate.
 638        color (`str`): A new color to use with the duplicated shape.
 639
 640    Returns:
 641        `Shape`: The new duplicated shape.
 642    """
 643    shape_type = _a_canvas.type(shape)
 644    shape_config = _a_canvas.itemconfig(shape)
 645    shape_coords = _a_canvas.coords(shape)
 646    the_copy = None
 647    if shape_type == "polygon"
 648        new_config = {key shape_config[key][-1] for key in shape_config.keys()}
 649        if color != None
 650            new_config["fill"] = color
 651        the_copy = _a_canvas.create_polygon(shape_coords, new_config)
 652        return the_copy
 653
 654
 655def mirror(shape):
 656    """
 657    A function that takes a shape and flips it across its vertical
 658    axis, returning the modified shape.
 659
 660    Args:
 661        shape (`Shape` or Tag): The shape in question.
 662
 663    """
 664    center = get_center(shape)[0]
 665    shape_ids = _a_canvas.find_withtag(shape)
 666    for shape_id in shape_ids
 667        flipped_coordinates = []
 668        shape_coords = _a_canvas.coords(shape_id)
 669        counter = 0
 670        for num in shape_coords
 671            if counter % 2 == 0
 672                if num < center
 673                    flipped_coordinates.append(num + 2 * (center - num))
 674                elif num > center
 675                    flipped_coordinates.append(num - 2 * (num - center))
 676                else
 677                    flipped_coordinates.append(num)
 678            else
 679                flipped_coordinates.append(num)
 680            counter += 1
 681        _a_canvas.coords(shape_id, flipped_coordinates)
 682
 683
 684def rotate(shape, degrees=5, origin=None):
 685    """
 686    A reporter function that takes a shape and rotates it by a specified amount around a specified point.
 687    It does this by interpolating a polygon around the shape and calculating the shifts of individual
 688    points on the edge of the polygon.
 689
 690    Args:
 691        shape (`Shape` or Tag): The shape to rotate.
 692        degrees (`int`): The number of degrees to rotate the shape.
 693        origin (`tuple`): An `(x,y)` coordinate about which to perform the rotation. Defaults to the center
 694            of the given shape.
 695
 696    Returns:
 697        `Shape`: The modified shape.
 698    """
 699    if origin is None
 700        origin = get_center(shape)
 701
 702    theta = radians(degrees)
 703    ox, oy = origin
 704
 705    all_shapes = _a_canvas.find_withtag(shape)
 706
 707    for a_shape in all_shapes
 708        coords = _a_canvas.coords(a_shape)
 709        # update coordinates:
 710        for i in range(0, len(coords), 2):
 711            px, py = coords[i], coords[i + 1]
 712            qx = cos(theta) * (px - ox) - sin(theta) * (py - oy) + ox
 713            qy = sin(theta) * (px - ox) + cos(theta) * (py - oy) + oy
 714            coords[i] = qx
 715            coords[i + 1] = qy
 716        # set the coordinates:
 717        _a_canvas.coords(a_shape, coords)
 718
 719    return shape
 720
 721
 722def distance(point1, point2):
 723    """
 724    A reporter function calculates the distance between two `(x, y)` coordinates.
 725
 726    Args:
 727        point1 (`tuple`): The first `(x, y)` coordinate.
 728        point2 (`tuple`): The second `(x, y)` coordinate.
 729
 730    Returns:
 731         A `float` representing the distance between the two points.
 732    """
 733    return sqrt(((point1[0] - point2[0])  2) + ((point1[1] - point2[1])  2))
 734
 735
 736def update_color(shape, color):
 737    """
 738    Change the fill color of a tagged object.
 739
 740    Args:
 741        shape (`Shape` or Tag): The shape or tag to re-fill.
 742        color (`str`): A color name or hex code to re-fill with.
 743    """
 744    ids = _a_canvas.find_withtag(shape)
 745    for id in ids
 746        _a_canvas.itemconfig(id, fill=color)
 747
 748
 749def interpolate_colors(color1, color2, frac):
 750    """
 751    A reporter function that generates a new color between two given colors.
 752    Args:
 753        color1 (`str`): The path of the file to wrap
 754        color2 (`str`): The path of the file to wrap
 755        frac (`float`): What fraction of each color to take. An input of 0 returns
 756            color1, an input of 1 returns color2, an input of 0.5 returns a color
 757            perfectly between the two.
 758
 759    Returns:
 760         A color (as a hex `str`) to be used elsewhere
 761    """
 762    if "#" not in color1
 763        color1 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color1)))
 764    else
 765        color1 = _tupelize_color(color1)
 766    if "#" not in color2
 767        color2 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color2)))
 768    else
 769        color2 = _tupelize_color(color2)
 770    return _interpolate_tuple(color1, color2, frac)
 771
 772
 773def get_colors(shape_or_shapes):
 774    """
 775    A reporter function that returns all the colors associated with a tag or list of tags.
 776
 777    Args:
 778        shape_or_shapes (`str`/`Shape` or `List`): the shape/tag or list of shapes/tags you"d like to find the colors of
 779
 780    Returns:
 781        A `List` containing all unique colors associated with that tag(s)
 782    """
 783    all_shapes = []
 784    if not isinstance(shape_or_shapes, ):
 785        shape_or_shapes = [shape_or_shapes]
 786    for shape in shape_or_shapes
 787        all_shapes += _a_canvas.find_withtag(shape)
 788
 789    all_colors = []
 790    for shape in all_shapes
 791        color = _a_canvas.itemcget(shape, "fill")
 792        if color not in all_colors
 793            all_colors.append(color)
 794
 795    return all_colors
 796
 797
 798def get_center(shape):
 799    """
 800    A reporter function calculates the a coordinate at the center of some shape.
 801
 802    Args:
 803        shape (`Shape` or Tag): The shape in question.
 804
 805    Returns:
 806         A `tuple` representing center of the given shape.
 807    """
 808    bbox = _safe_bbox(shape)
 809
 810    if bbox is None
 811        raise Exception(
 812            f"We couldn"t find the shape with id/tag {shape}. Make sure it exists!"
 813        )
 814
 815    return (((bbox[2] + bbox[0]) / 2), ((bbox[1] + bbox[3]) / 2))
 816
 817
 818def get_top(shape):
 819    """
 820    A reporter function calculates the minimum y-value of a given shape (since the y-axis is flipped).
 821
 822    Args:
 823        shape (`Shape` or Tag): The shape in question.
 824
 825    Returns:
 826         A `int` representing the minimum y-coordinate of the shape.
 827    """
 828    bbox = _safe_bbox(shape)
 829    return bbox[1]
 830
 831
 832def get_bottom(shape):
 833    """
 834    A reporter function calculates the maximum y-value of a given shape (since the y-axis is flipped).
 835
 836    Args:
 837        shape (`Shape` or Tag): The shape in question.
 838
 839    Returns:
 840         A `int` representing the maximum y-coordinate of the shape.
 841    """
 842    bbox = _safe_bbox(shape)
 843    return bbox[3]
 844
 845
 846def get_left(shape):
 847    """
 848    A reporter function calculates the minimum x-value of a given shape.
 849
 850    Args:
 851        shape (`Shape` or Tag): The shape in question.
 852
 853    Returns:
 854         A `int` representing the minimum x-coordinate of the shape.
 855    """
 856    bbox = _safe_bbox(shape)
 857    return bbox[0]
 858
 859
 860def get_right(shape):
 861    """
 862    A reporter function calculates the maximum x-value of a given shape.
 863
 864    Args:
 865        shape (`Shape` or Tag): The shape in question.
 866
 867    Returns:
 868         A `int` representing the maximum x-coordinate of the shape.
 869    """
 870    bbox = _safe_bbox(shape)
 871    return bbox[2]
 872
 873
 874def get_height(shape):
 875    """
 876    A reporter function calculates the height of some given shape.
 877
 878    Args:
 879        shape (`Shape` or Tag): The shape in question.
 880
 881    Returns:
 882         A `int` representing the height of the shape.
 883    """
 884    bbox = _safe_bbox(shape)
 885    return bbox[3] - bbox[1] - 1
 886
 887
 888def get_width(shape):
 889    """
 890    A reporter function calculates the width of some given shape.
 891
 892    Args:
 893        shape (`Shape` or Tag): The shape in question.
 894
 895    Returns:
 896         An `int` representing width of the shape.
 897    """
 898    bbox = _safe_bbox(shape)
 899    return bbox[2] - bbox[0] - 1
 900
 901
 902def make_grid(c, w, h):
 903    """
 904    Draws a grid on a screen with intervals of 100.
 905
 906    Args:
 907        w (`int`): The width of the grid to draw
 908        h (`int`): The height of the grid to draw
 909    """
 910    interval = 100
 911    # Creates all vertical lines at intervals of 100
 912    for i in range(0, w, interval):
 913        _a_canvas.create_line(i, 0, i, h, tag="grid_line")
 914    # Creates all horizontal lines at intervals of 100
 915    for i in range(0, h, interval):
 916        _a_canvas.create_line(0, i, w, i, tag="grid_line")
 917    # Creates axis labels
 918    offset = 2
 919    for y in range(0, h, interval):
 920        for x in range(0, w, interval):
 921            _a_canvas.create_oval(
 922                x - offset, y - offset, x + offset, y + offset, fill="black"
 923            )
 924            _a_canvas.create_text(
 925                x + offset,
 926                y + offset,
 927                text="({0}, {1})".format(x, y),
 928                anchor="nw",
 929                font=("Purisa", 8),
 930            )
 931
 932
 933def _safe_bbox(shape):
 934    try
 935        bbox = _a_canvas.bbox(shape)
 936        if bbox is None
 937            Exception(
 938                f"We couldn"t find the shape with tag/id: {shape}. Make sure this shape exists!"
 939            )
 940        return bbox
 941    except
 942        raise Exception(
 943            f"We couldn"t find the shape with tag/id: {shape}. Make sure this shape exists!"
 944        )
 945
 946
 947def _tupelize_color(color):
 948    R = (color[13], 16)
 949    G = (color[35], 16)
 950    B = (color[57], 16)
 951    return R, G, B
 952
 953
 954def _interpolate_tuple(startcolor, goalcolor, frac):
 955    R = startcolor[0]
 956    G = startcolor[1]
 957    B = startcolor[2]
 958
 959    targetR = goalcolor[0]
 960    targetG = goalcolor[1]
 961    targetB = goalcolor[2]
 962
 963    DiffR = targetR - R
 964    DiffG = targetG - G
 965    DiffB = targetB - B
 966
 967    iR = (R + (DiffR * frac))
 968    iG = (G + (DiffG * frac))
 969    iB = (B + (DiffB * frac))
 970
 971    hR = hex(iR).replace("0x", "")
 972    hG = hex(iG).replace("0x", "")
 973    hB = hex(iB).replace("0x", "")
 974
 975    if len(hR) == 1
 976        hR = "0" + hR
 977    if len(hB) == 1
 978        hB = "0" + hB
 979    if len(hG) == 1
 980        hG = "0" + hG
 981
 982    color = ("#" + hR + hG + hB).upper()
 983
 984    return color
 985
 986
 987def does_tag_exist(tag):
 988    """
 989    Returns `True` if a given tag exists otherwise returns `False`.
 990
 991    Args:
 992        `tag` (`str`): [Required] The tag of the object to lookup.
 993
 994    """
 995    result = _a_canvas.find_withtag(tag)
 996
 997    if result
 998        return True
 999    else
1000        return False
1001
1002
1003def random_color():
1004    """
1005    Returns a random color as a `string` to be used with `tkinter`.
1006    It does not accept any inputs.
1007    """
1008    r = lambda randint(0, 255)
1009    return "#%02X%02X%02X" % (r(), r(), r())
1010
1011
1012from tkinter import Tk, Canvas
1013
1014
1015def setup_shapes(title, background="white", width=600, height=600):
1016    """
1017    A static function that sets up the pop-up window. DO NOT USE THIS FUNCTION.
1018    """
1019    global _a_canvas
1020    gui = Tk()
1021    gui.title(title)
1022    _a_canvas = Canvas(gui, background=background, width=width, height=width)
1023    _a_canvas.pack()
1024    make_grid(_a_canvas, width, height)
1025    return _a_canvas
def rectangle( top_left=(0, 0), width=25, height=50, color="hot pink", outline="", tag="",):
15def rectangle(
16    top_left=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 
17):
18    """
19    A reporter function that draws a rectangle.
20    Args:
21        top_left (`tuple`): A coordinate representing the top left-hand corner of the shape.
22        width (`int`): How wide to draw the shape.
23        height (`int`): How tall to draw the shape.
24        color (`str`): What color to draw the shape.
25        outline (`str`): What color should the border of the shape be.
26        tag (`str`): The tag to assign to the shape.
27
28    Returns:
29         `Shape`: The rectangle that was created.
30    """
31    point_0 = top_left
32    point_1 = (top_left[0] + width, top_left[1])
33    point_2 = (top_left[0] + width, top_left[1] + height)
34    point_3 = (top_left[0], top_left[1] + height)
35    return _a_canvas.create_polygon(
36        point_0, point_1, point_2, point_3, fill=_safe_color(color), tags=tag, 
37    )

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.

def square( top_left=(0, 0), size=25, color="hot pink", outline="", tag="",):
40def square(top_left=(0, 0), size=25, color="hot pink", outline="", tag="", ):
41    """
42    A reporter function that draws a square.
43    Args:
44        top_left (`tuple`): A coordinate representing the top left-hand corner of the shape.
45        size (`int`): How big to draw the shape.
46        color (`str`): What color to draw the shape.
47        outline (`str`): What color should the border of the shape be.
48        tag (`str`): The tag to assign to the shape.
49
50    Returns:
51         `Shape`: The square that was created.
52    """
53    return rectangle(
54        top_left=top_left, width=size, height=size, color=color, tag=tag, 
55    )

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.

def oval( center=(0, 0), radius_x=25, radius_y=50, color="hot pink", outline="", tag="",):
 58def oval(
 59    center=(0, 0),
 60    radius_x=25,
 61    radius_y=50,
 62    color="hot pink",
 63    outline="",
 64    tag="",
 65    ,
 66):
 67    """
 68    A reporter function that draws an oval.
 69    Args:
 70        center (`tuple`): A coordinate representing the center of the shape.
 71        radius_x (`int`): Specifies the oval"s radius on the x-axis.
 72        radius_y (`int`): Specifies the oval"s radius on the y-axis.
 73        color (`str`): What color to draw the shape.
 74        outline (`str`): What color should the border of the shape be.
 75        tag (`str`): The tag to assign to the shape.
 76
 77    Returns:
 78         `Shape`: The oval that was created.
 79    """
 80    x = center[0]
 81    y = center[1]
 82    x0, y0, x1, y1 = (x - radius_x, y - radius_y, x + radius_x, y + radius_y)
 83    steps = 100
 84    # major and minor axes
 85    a = (x1 - x0) / 2.0
 86    b = (y1 - y0) / 2.0
 87    # center
 88    xc = x0 + a
 89    yc = y0 + b
 90    point_list = []
 91    # create the oval as a list of points
 92    for i in range(steps):
 93        # Calculate the angle for this step
 94        theta = (pi * 2) * (float(i) / steps)
 95        x = a * cos(theta)
 96        y = b * sin(theta)
 97        point_list.append(round(x + xc))
 98        point_list.append(round(y + yc))
 99
100    return _a_canvas.create_polygon(
101        point_list, fill=_safe_color(color), tags=tag, 
102    )

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.

def circle( center=(0, 0), radius=25, color="hot pink", outline="", tag="",):
105def circle(center=(0, 0), radius=25, color="hot pink", outline="", tag="", ):
106    """
107    A reporter function that draws a circle.
108    Args:
109        center (`tuple`): A coordinate representing the center of the shape.
110        radius (`int`): Specifies the circle"s radius.
111        color (`str`): What color to draw the shape.
112        outline (`str`): What color should the border of the shape be.
113        tag (`str`): The tag to assign to the shape.
114
115    Returns:
116         `Shape`: The circle that was created.
117    """
118    return oval(
119        center=center, radius_x=radius, radius_y=radius, color=color, tag=tag, 
120    )

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.

def wedge( center=(0, 0), radius=25, angle=180, color="hot pink", outline="", tag="",):
123def wedge(
124    center=(0, 0), radius=25, angle=180, color="hot pink", outline="", tag="", 
125):
126    """
127    A reporter function that draws a circle.
128    Args:
129        center (`tuple`): A coordinate representing the center of the shape.
130        radius (`int`): Specifies the circle"s radius.
131        angle (`int`): A number between 0 and 360 that specifies how much of the circle to draw.
132        color (`str`): What color to draw the shape.
133        outline (`str`): What color should the border of the shape be.
134        tag (`str`): The tag to assign to the shape.
135
136    Returns:
137         `Shape`: The wedge that was created.
138    """
139    point_list = [center[0], center[1]]
140    for i in range(0, 0 + angle):
141        x1 = center[0] + radius * cos(radians(i))
142        point_list.append(x1)
143        y1 = center[1] + radius * sin(radians(i))
144        point_list.append(y1)
145
146    point_list.append(center[0])
147    point_list.append(center[1])
148
149    return _a_canvas.create_polygon(
150        point_list, fill=_safe_color(color), outline=outline, tags=tag, 
151    )

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.

def triangle( bottom_center=(0, 0), width=25, top_shift=0, height=0, color="hot pink", outline="", tag="",):
154def triangle(
155    bottom_center=(0, 0),
156    width=25,
157    top_shift=0,
158    height=0,
159    color="hot pink",
160    outline="",
161    tag="",
162    ,
163):
164    """
165    A reporter function that draws a triangle.
166    Args:
167        bottom_center (`tuple`): A coordinate representing the bottom center of the shape.
168        width (`int`): Specifies the width of the base of the triangle.
169        top_shift (`int`): Specifies the how far to the left or right to shift the top of
170            the triangle from the bottom center.
171        height (`int`): Specifies the triangle"s height.
172        color (`str`): What color to draw the shape.
173        outline (`str`): What color should the border of the shape be.
174        tag (`str`): The tag to assign to the shape.
175
176    Returns:
177         `Shape`: The triangle that was created.
178    """
179    if height == 0
180        height = width * sqrt(3) / 2
181    point_0 = (bottom_center[0] - width / 2, bottom_center[1])
182    point_1 = (bottom_center[0] + width / 2, bottom_center[1])
183    point_2 = (bottom_center[0] + top_shift, bottom_center[1] - height)
184
185    return _a_canvas.create_polygon(
186        point_0, point_1, point_2, fill=_safe_color(color), tags=tag, 
187    )

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.

def line(points=[], curvy=False, color="hot pink", tag="", ):
190def line(points=[], curvy=False, color="hot pink", tag="", ):
191    """
192    A reporter function that draws a line given a list of points.
193    Args:
194        points (`list`): The points that define the line; this should be a list of tuples (coordinates).
195        curvy (`bool`): Makes a curvy line instead.
196        color (`str`): What color to make the shape.
197        tag (`str`): The tag to assign to the shape.
198
199    Returns:
200        `Shape`: The line that was created.
201    """
202    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.

def arc( points=[], width=5, color="hot pink", line_steps=15, tag="",):
205def arc(points=[], width=5, color="hot pink", line_steps=15, tag="", ):
206    """
207    A reporter function that draws an arc ("curve") given a list of points.
208    Args:
209        points (`list`): The points outlining the curve; this should be a list of tuples (coordinates).
210            Make sure to give it at least 3 (x,y) coordinates that aren"t a straight line!
211        color (`str`): What color to make the shape.
212        tag (`str`): The tag to assign to the shape.
213
214    Returns:
215        `Shape`: The arc that was created.
216    """
217    return _a_canvas.create_line(
218        points,
219        width=width,
220        fill=color,
221        splinesteps=line_steps,
222        smooth=True,
223        tags=tag,
224        ,
225    )

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.

def diamond( center=(0, 0), width=25, height=50, color="hot pink", outline="", tag="",):
228def diamond(
229    center=(0, 0), width=25, height=50, color="hot pink", outline="", tag="", 
230):
231    """
232    A reporter function that draws a rectangle.
233    Args:
234        center (`tuple`): A coordinate representing the center of the shape.
235        width (`int`): How wide to draw the shape.
236        height (`int`): How tall to draw the shape.
237        color (`str`): What color to draw the shape.
238        outline (`str`): What color should the border of the shape be.
239        tag (`str`): The tag to assign to the shape.
240
241    Returns:
242         `Shape`: The shape that was created.
243    """
244    point_0 = (center[0] - width / 2, center[1])
245    point_1 = (center[0], center[1] - height / 2)
246    point_2 = (center[0] + width / 2, center[1])
247    point_3 = (center[0], center[1] + height / 2)
248    return _a_canvas.create_polygon(
249        point_0,
250        point_1,
251        point_2,
252        point_3,
253        fill=_safe_color(color),
254        tags=tag,
255        outline=outline,
256        ,
257    )

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.

def star( center=(0, 0), radius=50, color="hot pink", outer_radius=75, points=5, outline="", tag="",):
260def star(
261    center=(0, 0),
262    radius=50,
263    color="hot pink",
264    outer_radius=75,
265    points=5,
266    outline="",
267    tag="",
268    ,
269):
270    """
271    A reporter function that draws a star.
272    Args:
273        center (`tuple`): A coordinate representing the center of the shape.
274        radius (`int`): Specifies the radius of the inside part of the star.
275        color (`str`): Specifies the color of the star.
276        outer_radius (`int`): Specifies the radius of the outside part of the star.
277        points (`int`): Specifies the number of points for the star.
278        outline (`str`): What color should the border of the shape be.
279        tag (`str`): The tag to assign to the shape.
280
281    Returns:
282         `Shape`: The star that was created.
283    """
284    arc_segment = 360 / points
285    vertices = []
286    for i in range(points):
287        inner_point = (
288            radius * cos(radians(arc_segment * i)) + center[0],
289            -1 * radius * sin(radians(arc_segment * i)) + center[1],
290        )
291        vertices.append(inner_point)
292        outer_point = (
293            outer_radius * cos(radians(arc_segment * i + arc_segment / 2)) + center[0],
294            -1 * outer_radius * sin(radians(arc_segment * i + arc_segment / 2))
295            + center[1],
296        )
297        vertices.append(outer_point)
298    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.

def polygon(points=[], color="hot pink", outline="", tag="", ):
301def polygon(points=[], color="hot pink", outline="", tag="", ):
302    """
303    A reporter function that draws a polygon given a list of points.
304    Args:
305        points (`list`): The points outlining the polygon; this should be a list of tuples (coordinates).
306            defaults to an empty list.
307        outline (`str`): What color should the border of the shape be.
308        color (`str`): What color to make the shape.
309
310    Returns:
311        `Shape`: The polygon that was created.
312    """
313    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.

def spiral( center=(0, 0), width=100, roughness=0.01, start=0, spirals=5, line_width=1,):
320def spiral(
321    center=(0, 0), width=100, roughness=0.01, start=0, spirals=5, line_width=1, 
322):
323    """
324    A reporter function that draws a spiral.
325    Args:
326        center (`tuple`): A coordinate representing the center of the shape.
327        width (`int`): Specifies the total width of the spiral.
328        roughness (`float`): Controls how spiral-y the shape is (lower is less spiral-y)
329        start (`int`): Where on the spiral to start drawing.
330        spirals (`int`): How many loops to draw.
331        line_width (`int`): How wide for the line to be drawn.
332        tag (`str`): The tag to assign to the shape.
333
334    Returns:
335         `Shape`: The spiral that was created.
336    """
337    theta = 0.0
338    r = start
339    all_points = []
340    prev_pos = _polar_to_cartesian(r, theta)
341    distance = width / 4 / pi / spirals
342    all_points.append((prev_pos[0] + center[0], prev_pos[1] + center[1]))
343    while theta < 2 * spirals * pi
344        theta += roughness
345        r = start + distance * theta
346        pos = _polar_to_cartesian(r, theta)
347        all_points.append((pos[0] + center[0], pos[1] + center[1]))
348
349    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.

def move(shape, x_shift=0, y_shift=0):
352def move(shape, x_shift=0, y_shift=0):
353    """
354    Purpose: Move the x and y position of all shapes that have been tagged
355    with the tag argument
356
357    Args:
358        shape (`Shape` or Tag): The shape in question.
359        x_shift (`int`; optional): amount to move in the x direction
360        y_shift (`int`; optional): amount to move in the y direction
361    """
362    shape_ids = _a_canvas.find_withtag(shape)
363    for id in shape_ids
364        _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; optional): amount to move in the x direction
  • y_shift (int; optional): amount to move in the y direction
def portion(shape, start=0, end=0.5):
367def portion(shape, start=0, end=0.5):
368    """
369    Purpose: Take a slice or portion of some already created shape.
370
371    Args:
372        shape (`Shape` or Tag): The shape to take a portion of
373        start (`float`): A number between 0 and 1 representing where to start the slice.
374        end (`float`): A number between 0 and 1 representing where to end the slice.
375
376    For example, taking a portion from 0 to 0.5 of a circle would result in a semi-circle.
377
378    Note: this function is experimental. It might produce unexpected results!
379    """
380    all_shapes = _a_canvas.find_withtag(shape)
381
382    for a_shape in all_shapes
383        coords = _a_canvas.coords(a_shape)
384
385        start_coord = floor(start * len(coords))
386        if start_coord % 2 == 1
387            start_coord = start_coord - 1  # need to start with an x,y pair
388        end_coord = floor(end * len(coords))
389        if end_coord % 2 == 1
390            end_coord = end_coord - 1  # need to end with an x,y pair
391
392        # slice is up to not including so get the last x,y pair
393        new_coords = coords[start_coord  end_coord + 2]
394
395        # loop shape back in on itself
396        new_coords.append(new_coords[0])
397        new_coords.append(new_coords[1])
398
399        # set the coordinates:
400        _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!

def put_in_front(shape):
403def put_in_front(shape):
404    """
405    A function that "raises" a shape to the "top" of the screen."
406
407    Args:
408        shape (`Shape` or Tag): The shape in question.
409    """
410    _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.
def put_in_back(shape):
413def put_in_back(shape):
414    """
415    A function that "lowers" a shape to the "bottom" of the screen."
416
417    Args:
418        shape (`Shape` or Tag): The shape in question.
419    """
420    _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.
def align(shape1, shape2, via="middle", offset_x=0, offset_y=0):
444def align(shape1, shape2, via="middle", offset_x=0, offset_y=0):
445    """
446    A reporter function that aligns `shape1` with `shape2`. It does this by moving `shape1` to align with
447    whatever property of `shape2` is selected with the `via` input.
448
449    Args:
450        shape1 (`Shape` or Tag): The first shape to use.
451        shape2 (`Shape` or Tag): The second shape to use.
452        via (`str`): Has to be one of, the following options: `"center"` (horizontal center),
453            `"middle"` (vertical center), `"top"`, `"bottom"`, `"left"`, or `"right"`
454        offset_x (`int`): How much to shift in the x-axis after alignment
455        offset_y (`int`): How much to shift in the y-axis after alignment
456
457    Returns:
458        `Shape`: The modified shape1.
459    """
460    via_options = ["center", "middle", "top", "bottom", "left", "right"]
461    if via not in via_options
462        raise ValueError(
463            "The via input must be one of "
464            + (via_options)
465            + " but instead we found "
466            + (via)
467        )
468
469    outline1 = _get_outline(shape1)
470    outline2 = _get_outline(shape2)
471
472    if via == "center"
473        _a_canvas.move(
474            shape1, (outline2["center"][0] - outline1["center"][0]) + offset_x, offset_y
475        )
476
477    elif via == "middle"
478        _a_canvas.move(
479            shape1, offset_x, (outline2["center"][1] - outline1["center"][1]) + offset_y
480        )
481
482    elif via == "top"
483        _a_canvas.move(shape1, offset_x, (outline2["top"] - outline1["top"]) + offset_y)
484
485    elif via == "bottom"
486        _a_canvas.move(
487            shape1, offset_x, (outline2["bottom"] - outline1["bottom"]) + offset_y
488        )
489
490    elif via == "left"
491        _a_canvas.move(
492            shape1, (outline2["left"] - outline1["left"]) + offset_x, offset_y
493        )
494
495    elif via == "right"
496        _a_canvas.move(
497            shape1, (outline2["right"] - outline1["right"]) + offset_x, offset_y
498        )
499
500    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.

def overlay(shape1, shape2, offset_x=0, offset_y=0):
503def overlay(shape1, shape2, offset_x=0, offset_y=0):
504    """
505    A reporter function that overlays shape1 onto shape2. It does this by moving shape 1"s center
506    to shape 2"s center, and then applying any specified offset.
507    Args:
508        shape1 (`Shape` or Tag): The first shape to use.
509        shape2 (`Shape` or Tag): The second shape to use.
510        offset_x (`int`): How much to shift shape 2 in the x-direction after centering it.
511        offset_y (`int`): How much to shift shape 2 in the x-direction after centering it.
512
513    Returns:
514        `Shape`: The modified shape1.
515    """
516    center1 = get_center(shape1)
517    center2 = get_center(shape2)
518    _a_canvas.move(
519        shape1,
520        (center2[0] - center1[0]) + offset_x,
521        (center2[1] - center1[1]) + offset_y,
522    )
523    _a_canvas.tag_raise(shape1, shape2)
524    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.

def underlay(shape1, shape2, offset_x=0, offset_y=0):
527def underlay(shape1, shape2, offset_x=0, offset_y=0):
528    """
529    A reporter function that underlays shape1 beneath shape2. It does this by moving shape 1"s center
530    to shape 2"s center, and then applying any specified offset.
531    Args:
532        shape1 (`Shape` or Tag): The first shape to use.
533        shape2 (`Shape` or Tag): The second shape to use.
534        offset_x (`int`): How much to shift shape 2 in the x-direction after centering it.
535        offset_y (`int`): How much to shift shape 2 in the x-direction after centering it.
536
537    Returns:
538        `Shape`: The modified shape1.
539    """
540    center1 = get_center(shape1)
541    center2 = get_center(shape2)
542    _a_canvas.move(
543        shape1,
544        (center2[0] - center1[0]) + offset_x,
545        (center2[1] - center1[1]) + offset_y,
546    )
547    _a_canvas.tag_lower(shape1, shape2)
548    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.

def above(shape1, shape2, offset_x=0, offset_y=0):
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

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.

def beside(shape1, shape2, offset_x=0, offset_y=0):
575def beside(shape1, shape2, offset_x=0, offset_y=0):
576    """
577    A reporter function that places shape1 beside shape2 (horizontally). It does this by moving shape 1"s center
578    to shape 2"s center, moving shape 1 in the x-direction the exact width of shape 2, and then applying any
579    specified offset.
580
581    Args:
582        shape1 (`Shape` or Tag): The first shape to use.
583        shape2 (`Shape` or Tag): The second shape to use.
584        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
585        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
586
587    Returns:
588        `Shape`: The modified shape1.
589    """
590    overlay(shape1, shape2)
591    _a_canvas.move(
592        shape1,
593        (get_width(shape2) + get_width(shape1)) / 2 + offset_x,
594        0 + offset_y,
595    )
596    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.

def below(shape1, shape2, offset_x=0, offset_y=0):
599def below(shape1, shape2, offset_x=0, offset_y=0):
600    """
601    A reporter function that places shape1 below shape2 (vertically). It does this by moving shape 1"s center
602    to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any
603    specified offset.
604
605    Args:
606        shape1 (`Shape` or Tag): The first shape to use.
607        shape2 (`Shape` or Tag): The second shape to use.
608        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
609        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
610
611    Returns:
612        `Shape`: The modified shape1.
613    """
614    overlay(shape1, shape2)
615    _a_canvas.move(
616        shape1,
617        0 + offset_x,
618        (get_height(shape2) + get_height(shape1)) / 2 + offset_y,
619    )
620    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.

def delete(shape):
623def delete(shape):
624    """
625    A function that deletes a shape from our screen.
626
627    Args:
628        shape (`Shape` or Tag): The shape to delete.
629    """
630    _a_canvas.delete(shape)

A function that deletes a shape from our screen.

Arguments:
  • shape (Shape or Tag): The shape to delete.
def duplicate(shape, color=None):
633def duplicate(shape, color=None):
634    """
635    A reporter function that perfectly copies a shape and returns that copy.
636
637    Args:
638        shape (`Shape` or Tag): The shape to duplicate.
639        color (`str`): A new color to use with the duplicated shape.
640
641    Returns:
642        `Shape`: The new duplicated shape.
643    """
644    shape_type = _a_canvas.type(shape)
645    shape_config = _a_canvas.itemconfig(shape)
646    shape_coords = _a_canvas.coords(shape)
647    the_copy = None
648    if shape_type == "polygon"
649        new_config = {key shape_config[key][-1] for key in shape_config.keys()}
650        if color != None
651            new_config["fill"] = color
652        the_copy = _a_canvas.create_polygon(shape_coords, new_config)
653        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.

def mirror(shape):
656def mirror(shape):
657    """
658    A function that takes a shape and flips it across its vertical
659    axis, returning the modified shape.
660
661    Args:
662        shape (`Shape` or Tag): The shape in question.
663
664    """
665    center = get_center(shape)[0]
666    shape_ids = _a_canvas.find_withtag(shape)
667    for shape_id in shape_ids
668        flipped_coordinates = []
669        shape_coords = _a_canvas.coords(shape_id)
670        counter = 0
671        for num in shape_coords
672            if counter % 2 == 0
673                if num < center
674                    flipped_coordinates.append(num + 2 * (center - num))
675                elif num > center
676                    flipped_coordinates.append(num - 2 * (num - center))
677                else
678                    flipped_coordinates.append(num)
679            else
680                flipped_coordinates.append(num)
681            counter += 1
682        _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.
def rotate(shape, degrees=5, origin=None):
685def rotate(shape, degrees=5, origin=None):
686    """
687    A reporter function that takes a shape and rotates it by a specified amount around a specified point.
688    It does this by interpolating a polygon around the shape and calculating the shifts of individual
689    points on the edge of the polygon.
690
691    Args:
692        shape (`Shape` or Tag): The shape to rotate.
693        degrees (`int`): The number of degrees to rotate the shape.
694        origin (`tuple`): An `(x,y)` coordinate about which to perform the rotation. Defaults to the center
695            of the given shape.
696
697    Returns:
698        `Shape`: The modified shape.
699    """
700    if origin is None
701        origin = get_center(shape)
702
703    theta = radians(degrees)
704    ox, oy = origin
705
706    all_shapes = _a_canvas.find_withtag(shape)
707
708    for a_shape in all_shapes
709        coords = _a_canvas.coords(a_shape)
710        # update coordinates:
711        for i in range(0, len(coords), 2):
712            px, py = coords[i], coords[i + 1]
713            qx = cos(theta) * (px - ox) - sin(theta) * (py - oy) + ox
714            qy = sin(theta) * (px - ox) + cos(theta) * (py - oy) + oy
715            coords[i] = qx
716            coords[i + 1] = qy
717        # set the coordinates:
718        _a_canvas.coords(a_shape, coords)
719
720    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.

def distance(point1, point2):
723def distance(point1, point2):
724    """
725    A reporter function calculates the distance between two `(x, y)` coordinates.
726
727    Args:
728        point1 (`tuple`): The first `(x, y)` coordinate.
729        point2 (`tuple`): The second `(x, y)` coordinate.
730
731    Returns:
732         A `float` representing the distance between the two points.
733    """
734    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.

def update_color(shape, color):
737def update_color(shape, color):
738    """
739    Change the fill color of a tagged object.
740
741    Args:
742        shape (`Shape` or Tag): The shape or tag to re-fill.
743        color (`str`): A color name or hex code to re-fill with.
744    """
745    ids = _a_canvas.find_withtag(shape)
746    for id in ids
747        _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.
def interpolate_colors(color1, color2, frac):
750def interpolate_colors(color1, color2, frac):
751    """
752    A reporter function that generates a new color between two given colors.
753    Args:
754        color1 (`str`): The path of the file to wrap
755        color2 (`str`): The path of the file to wrap
756        frac (`float`): What fraction of each color to take. An input of 0 returns
757            color1, an input of 1 returns color2, an input of 0.5 returns a color
758            perfectly between the two.
759
760    Returns:
761         A color (as a hex `str`) to be used elsewhere
762    """
763    if "#" not in color1
764        color1 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color1)))
765    else
766        color1 = _tupelize_color(color1)
767    if "#" not in color2
768        color2 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color2)))
769    else
770        color2 = _tupelize_color(color2)
771    return _interpolate_tuple(color1, color2, frac)

A reporter function that generates a new color between two given colors.

Arguments:
  • color1 (str): The path of the file to wrap
  • color2 (str): The path of the file to wrap
  • frac (float): What fraction of each color to take. An input of 0 returns color1, an input of 1 returns color2, an input of 0.5 returns a color perfectly between the two.
Returns:

A color (as a hex str) to be used elsewhere

def get_colors(shape_or_shapes):
774def get_colors(shape_or_shapes):
775    """
776    A reporter function that returns all the colors associated with a tag or list of tags.
777
778    Args:
779        shape_or_shapes (`str`/`Shape` or `List`): the shape/tag or list of shapes/tags you"d like to find the colors of
780
781    Returns:
782        A `List` containing all unique colors associated with that tag(s)
783    """
784    all_shapes = []
785    if not isinstance(shape_or_shapes, ):
786        shape_or_shapes = [shape_or_shapes]
787    for shape in shape_or_shapes
788        all_shapes += _a_canvas.find_withtag(shape)
789
790    all_colors = []
791    for shape in all_shapes
792        color = _a_canvas.itemcget(shape, "fill")
793        if color not in all_colors
794            all_colors.append(color)
795
796    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 or List): 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)

def get_center(shape):
799def get_center(shape):
800    """
801    A reporter function calculates the a coordinate at the center of some shape.
802
803    Args:
804        shape (`Shape` or Tag): The shape in question.
805
806    Returns:
807         A `tuple` representing center of the given shape.
808    """
809    bbox = _safe_bbox(shape)
810
811    if bbox is None
812        raise Exception(
813            f"We couldn"t find the shape with id/tag {shape}. Make sure it exists!"
814        )
815
816    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.

def get_top(shape):
819def get_top(shape):
820    """
821    A reporter function calculates the minimum y-value of a given shape (since the y-axis is flipped).
822
823    Args:
824        shape (`Shape` or Tag): The shape in question.
825
826    Returns:
827         A `int` representing the minimum y-coordinate of the shape.
828    """
829    bbox = _safe_bbox(shape)
830    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.

def get_bottom(shape):
833def get_bottom(shape):
834    """
835    A reporter function calculates the maximum y-value of a given shape (since the y-axis is flipped).
836
837    Args:
838        shape (`Shape` or Tag): The shape in question.
839
840    Returns:
841         A `int` representing the maximum y-coordinate of the shape.
842    """
843    bbox = _safe_bbox(shape)
844    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.

def get_left(shape):
847def get_left(shape):
848    """
849    A reporter function calculates the minimum x-value of a given shape.
850
851    Args:
852        shape (`Shape` or Tag): The shape in question.
853
854    Returns:
855         A `int` representing the minimum x-coordinate of the shape.
856    """
857    bbox = _safe_bbox(shape)
858    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.

def get_right(shape):
861def get_right(shape):
862    """
863    A reporter function calculates the maximum x-value of a given shape.
864
865    Args:
866        shape (`Shape` or Tag): The shape in question.
867
868    Returns:
869         A `int` representing the maximum x-coordinate of the shape.
870    """
871    bbox = _safe_bbox(shape)
872    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.

def get_height(shape):
875def get_height(shape):
876    """
877    A reporter function calculates the height of some given shape.
878
879    Args:
880        shape (`Shape` or Tag): The shape in question.
881
882    Returns:
883         A `int` representing the height of the shape.
884    """
885    bbox = _safe_bbox(shape)
886    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.

def get_width(shape):
889def get_width(shape):
890    """
891    A reporter function calculates the width of some given shape.
892
893    Args:
894        shape (`Shape` or Tag): The shape in question.
895
896    Returns:
897         An `int` representing width of the shape.
898    """
899    bbox = _safe_bbox(shape)
900    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.

def make_grid(c, w, h):
903def make_grid(c, w, h):
904    """
905    Draws a grid on a screen with intervals of 100.
906
907    Args:
908        w (`int`): The width of the grid to draw
909        h (`int`): The height of the grid to draw
910    """
911    interval = 100
912    # Creates all vertical lines at intervals of 100
913    for i in range(0, w, interval):
914        _a_canvas.create_line(i, 0, i, h, tag="grid_line")
915    # Creates all horizontal lines at intervals of 100
916    for i in range(0, h, interval):
917        _a_canvas.create_line(0, i, w, i, tag="grid_line")
918    # Creates axis labels
919    offset = 2
920    for y in range(0, h, interval):
921        for x in range(0, w, interval):
922            _a_canvas.create_oval(
923                x - offset, y - offset, x + offset, y + offset, fill="black"
924            )
925            _a_canvas.create_text(
926                x + offset,
927                y + offset,
928                text="({0}, {1})".format(x, y),
929                anchor="nw",
930                font=("Purisa", 8),
931            )

Draws a grid on a screen with intervals of 100.

Arguments:
  • w (int): The width of the grid to draw
  • h (int): The height of the grid to draw
def does_tag_exist(tag):
 988def does_tag_exist(tag):
 989    """
 990    Returns `True` if a given tag exists otherwise returns `False`.
 991
 992    Args:
 993        `tag` (`str`): [Required] The tag of the object to lookup.
 994
 995    """
 996    result = _a_canvas.find_withtag(tag)
 997
 998    if result
 999        return True
1000    else
1001        return False

Returns True if a given tag exists otherwise returns False.

Arguments:
  • tag (str): [Required] The tag of the object to lookup.
def random_color():
1004def random_color():
1005    """
1006    Returns a random color as a `string` to be used with `tkinter`.
1007    It does not accept any inputs.
1008    """
1009    r = lambda randint(0, 255)
1010    return "#%02X%02X%02X" % (r(), r(), r())

Returns a random color as a string to be used with tkinter. It does not accept any inputs.

def setup_shapes(title, background="white", width=600, height=600):
1016def setup_shapes(title, background="white", width=600, height=600):
1017    """
1018    A static function that sets up the pop-up window. DO NOT USE THIS FUNCTION.
1019    """
1020    global _a_canvas
1021    gui = Tk()
1022    gui.title(title)
1023    _a_canvas = Canvas(gui, background=background, width=width, height=width)
1024    _a_canvas.pack()
1025    make_grid(_a_canvas, width, height)
1026    return _a_canvas

A static function that sets up the pop-up window. DO NOT USE THIS FUNCTION.