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

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

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

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

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

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

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="", ):
192def line(points=[], curvy=False, color="hot pink", tag="", ):
193    """
194    A reporter function that draws a line given a list of points.
195    Args:
196        points (`list`): The points that define the line; this should be a list of tuples (coordinates).
197        curvy (`bool`): Makes a curvy line instead.
198        color (`str`): What color to make the shape.
199        tag (`str`): The tag to assign to the shape.
200
201    Returns:
202        `Shape`: The line that was created.
203    """
204    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="",):
207def arc(points=[], width=5, color="hot pink", line_steps=15, tag="", ):
208    """
209    A reporter function that draws an arc ("curve") given a list of points.
210    Args:
211        points (`list`): The points outlining the curve; this should be a list of tuples (coordinates).
212            Make sure to give it at least 3 (x,y) coordinates that aren"t a straight line!
213        color (`str`): What color to make the shape.
214        tag (`str`): The tag to assign to the shape.
215
216    Returns:
217        `Shape`: The arc that was created.
218    """
219    return _a_canvas.create_line(
220        points,
221        width=width,
222        fill=color,
223        splinesteps=line_steps,
224        smooth=True,
225        tags=tag,
226        ,
227    )

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

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="",):
262def star(
263    center=(0, 0),
264    radius=50,
265    color="hot pink",
266    outer_radius=75,
267    points=5,
268    outline="",
269    tag="",
270    ,
271):
272    """
273    A reporter function that draws a star.
274    Args:
275        center (`tuple`): A coordinate representing the center of the shape.
276        radius (`int`): Specifies the radius of the inside part of the star.
277        color (`str`): Specifies the color of the star.
278        outer_radius (`int`): Specifies the radius of the outside part of the star.
279        points (`int`): Specifies the number of points for the star.
280        outline (`str`): What color should the border of the shape be.
281        tag (`str`): The tag to assign to the shape.
282
283    Returns:
284         `Shape`: The star that was created.
285    """
286    arc_segment = 360 / points
287    vertices = []
288    for i in range(points):
289        inner_point = (
290            radius * cos(radians(arc_segment * i)) + center[0],
291            -1 * radius * sin(radians(arc_segment * i)) + center[1],
292        )
293        vertices.append(inner_point)
294        outer_point = (
295            outer_radius * cos(radians(arc_segment * i + arc_segment / 2)) + center[0],
296            -1 * outer_radius * sin(radians(arc_segment * i + arc_segment / 2))
297            + center[1],
298        )
299        vertices.append(outer_point)
300    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="", ):
303def polygon(points=[], color="hot pink", outline="", tag="", ):
304    """
305    A reporter function that draws a polygon given a list of points.
306    Args:
307        points (`list`): The points outlining the polygon; this should be a list of tuples (coordinates).
308            defaults to an empty list.
309        outline (`str`): What color should the border of the shape be.
310        color (`str`): What color to make the shape.
311
312    Returns:
313        `Shape`: The polygon that was created.
314    """
315    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,):
322def spiral(
323    center=(0, 0), width=100, roughness=0.01, start=0, spirals=5, line_width=1, 
324):
325    """
326    A reporter function that draws a spiral.
327    Args:
328        center (`tuple`): A coordinate representing the center of the shape.
329        width (`int`): Specifies the total width of the spiral.
330        roughness (`float`): Controls how spiral-y the shape is (lower is less spiral-y)
331        start (`int`): Where on the spiral to start drawing.
332        spirals (`int`): How many loops to draw.
333        line_width (`int`): How wide for the line to be drawn.
334        tag (`str`): The tag to assign to the shape.
335
336    Returns:
337         `Shape`: The spiral that was created.
338    """
339    theta = 0.0
340    r = start
341    all_points = []
342    prev_pos = _polar_to_cartesian(r, theta)
343    distance = width / 4 / pi / spirals
344    all_points.append((prev_pos[0] + center[0], prev_pos[1] + center[1]))
345    while theta < 2 * spirals * pi
346        theta += roughness
347        r = start + distance * theta
348        pos = _polar_to_cartesian(r, theta)
349        all_points.append((pos[0] + center[0], pos[1] + center[1]))
350
351    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):
354def move(shape, x_shift=0, y_shift=0):
355    """
356    Purpose: Move the x and y position of all shapes that have been tagged
357    with the tag argument
358
359    Args:
360        shape (`Shape` or Tag): The shape in question.
361        x_shift (`int`; optional): amount to move in the x direction
362        y_shift (`int`; optional): amount to move in the y direction
363    """
364    shape_ids = _a_canvas.find_withtag(shape)
365    for id in shape_ids
366        _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):
369def portion(shape, start=0, end=0.5):
370    """
371    Purpose: Take a slice or portion of some already created shape.
372
373    Args:
374        shape (`Shape` or Tag): The shape to take a portion of
375        start (`float`): A number between 0 and 1 representing where to start the slice.
376        end (`float`): A number between 0 and 1 representing where to end the slice.
377
378    For example, taking a portion from 0 to 0.5 of a circle would result in a semi-circle.
379
380    Note: this function is experimental. It might produce unexpected results!
381    """
382    all_shapes = _a_canvas.find_withtag(shape)
383
384    for a_shape in all_shapes
385        coords = _a_canvas.coords(a_shape)
386
387        start_coord = floor(start * len(coords))
388        if start_coord % 2 == 1
389            start_coord = start_coord - 1  # need to start with an x,y pair
390        end_coord = floor(end * len(coords))
391        if end_coord % 2 == 1
392            end_coord = end_coord - 1  # need to end with an x,y pair
393
394        # slice is up to not including so get the last x,y pair
395        new_coords = coords[start_coord  end_coord + 2]
396
397        # loop shape back in on itself
398        new_coords.append(new_coords[0])
399        new_coords.append(new_coords[1])
400
401        # set the coordinates:
402        _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):
405def put_in_front(shape):
406    """
407    A function that "raises" a shape to the "top" of the screen."
408
409    Args:
410        shape (`Shape` or Tag): The shape in question.
411    """
412    _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):
415def put_in_back(shape):
416    """
417    A function that "lowers" a shape to the "bottom" of the screen."
418
419    Args:
420        shape (`Shape` or Tag): The shape in question.
421    """
422    _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):
446def align(shape1, shape2, via="middle", offset_x=0, offset_y=0):
447    """
448    A reporter function that aligns `shape1` with `shape2`. It does this by moving `shape1` to align with
449    whatever property of `shape2` is selected with the `via` input.
450
451    Args:
452        shape1 (`Shape` or Tag): The first shape to use.
453        shape2 (`Shape` or Tag): The second shape to use.
454        via (`str`): Has to be one of, the following options: `"center"` (horizontal center),
455            `"middle"` (vertical center), `"top"`, `"bottom"`, `"left"`, or `"right"`
456        offset_x (`int`): How much to shift in the x-axis after alignment
457        offset_y (`int`): How much to shift in the y-axis after alignment
458
459    Returns:
460        `Shape`: The modified shape1.
461    """
462    via_options = ["center", "middle", "top", "bottom", "left", "right"]
463    if via not in via_options
464        raise ValueError(
465            "The via input must be one of "
466            + (via_options)
467            + " but instead we found "
468            + (via)
469        )
470
471    outline1 = _get_outline(shape1)
472    outline2 = _get_outline(shape2)
473
474    if via == "center"
475        _a_canvas.move(
476            shape1, (outline2["center"][0] - outline1["center"][0]) + offset_x, offset_y
477        )
478
479    elif via == "middle"
480        _a_canvas.move(
481            shape1, offset_x, (outline2["center"][1] - outline1["center"][1]) + offset_y
482        )
483
484    elif via == "top"
485        _a_canvas.move(shape1, offset_x, (outline2["top"] - outline1["top"]) + offset_y)
486
487    elif via == "bottom"
488        _a_canvas.move(
489            shape1, offset_x, (outline2["bottom"] - outline1["bottom"]) + offset_y
490        )
491
492    elif via == "left"
493        _a_canvas.move(
494            shape1, (outline2["left"] - outline1["left"]) + offset_x, offset_y
495        )
496
497    elif via == "right"
498        _a_canvas.move(
499            shape1, (outline2["right"] - outline1["right"]) + offset_x, offset_y
500        )
501
502    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):
505def overlay(shape1, shape2, offset_x=0, offset_y=0):
506    """
507    A reporter function that overlays shape1 onto shape2. It does this by moving shape 1"s center
508    to shape 2"s center, and then applying any specified offset.
509    Args:
510        shape1 (`Shape` or Tag): The first shape to use.
511        shape2 (`Shape` or Tag): The second shape to use.
512        offset_x (`int`): How much to shift shape 2 in the x-direction after centering it.
513        offset_y (`int`): How much to shift shape 2 in the x-direction after centering it.
514
515    Returns:
516        `Shape`: The modified shape1.
517    """
518    center1 = get_center(shape1)
519    center2 = get_center(shape2)
520    _a_canvas.move(
521        shape1,
522        (center2[0] - center1[0]) + offset_x,
523        (center2[1] - center1[1]) + offset_y,
524    )
525    _a_canvas.tag_raise(shape1, shape2)
526    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):
529def underlay(shape1, shape2, offset_x=0, offset_y=0):
530    """
531    A reporter function that underlays shape1 beneath shape2. It does this by moving shape 1"s center
532    to shape 2"s center, and then applying any specified offset.
533    Args:
534        shape1 (`Shape` or Tag): The first shape to use.
535        shape2 (`Shape` or Tag): The second shape to use.
536        offset_x (`int`): How much to shift shape 2 in the x-direction after centering it.
537        offset_y (`int`): How much to shift shape 2 in the x-direction after centering it.
538
539    Returns:
540        `Shape`: The modified shape1.
541    """
542    center1 = get_center(shape1)
543    center2 = get_center(shape2)
544    _a_canvas.move(
545        shape1,
546        (center2[0] - center1[0]) + offset_x,
547        (center2[1] - center1[1]) + offset_y,
548    )
549    _a_canvas.tag_lower(shape1, shape2)
550    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):
553def above(shape1, shape2, offset_x=0, offset_y=0):
554    """
555    A reporter function that places shape1 above shape2 (vertically). It does this by moving shape 1"s center
556    to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any
557    specified offset.
558
559    Args:
560        shape1 (`Shape` or Tag): The first shape to use.
561        shape2 (`Shape` or Tag): The second shape to use.
562        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
563        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
564
565    Returns:
566        `Shape`: The modified shape1.
567    """
568    overlay(shape1, shape2)
569    _a_canvas.move(
570        shape1,
571        0 + offset_x,
572        -1 * (get_height(shape2) + get_height(shape1)) / 2 + offset_y,
573    )
574    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):
577def beside(shape1, shape2, offset_x=0, offset_y=0):
578    """
579    A reporter function that places shape1 beside shape2 (horizontally). It does this by moving shape 1"s center
580    to shape 2"s center, moving shape 1 in the x-direction the exact width of shape 2, and then applying any
581    specified offset.
582
583    Args:
584        shape1 (`Shape` or Tag): The first shape to use.
585        shape2 (`Shape` or Tag): The second shape to use.
586        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
587        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
588
589    Returns:
590        `Shape`: The modified shape1.
591    """
592    overlay(shape1, shape2)
593    _a_canvas.move(
594        shape1,
595        (get_width(shape2) + get_width(shape1)) / 2 + offset_x,
596        0 + offset_y,
597    )
598    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):
601def below(shape1, shape2, offset_x=0, offset_y=0):
602    """
603    A reporter function that places shape1 below shape2 (vertically). It does this by moving shape 1"s center
604    to shape 2"s center, moving shape 1 in the y-direction the exact height of shape 2, and then applying any
605    specified offset.
606
607    Args:
608        shape1 (`Shape` or Tag): The first shape to use.
609        shape2 (`Shape` or Tag): The second shape to use.
610        offset_x (`int`): How much to shift shape 2 in the x-direction after moving it.
611        offset_y (`int`): How much to shift shape 2 in the x-direction after moving it.
612
613    Returns:
614        `Shape`: The modified shape1.
615    """
616    overlay(shape1, shape2)
617    _a_canvas.move(
618        shape1,
619        0 + offset_x,
620        (get_height(shape2) + get_height(shape1)) / 2 + offset_y,
621    )
622    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):
625def delete(shape):
626    """
627    A function that deletes a shape from our screen.
628
629    Args:
630        shape (`Shape` or Tag): The shape to delete.
631    """
632    _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):
635def duplicate(shape, color=None):
636    """
637    A reporter function that perfectly copies a shape and returns that copy.
638
639    Args:
640        shape (`Shape` or Tag): The shape to duplicate.
641        color (`str`): A new color to use with the duplicated shape.
642
643    Returns:
644        `Shape`: The new duplicated shape.
645    """
646    shape_type = _a_canvas.type(shape)
647    shape_config = _a_canvas.itemconfig(shape)
648    shape_coords = _a_canvas.coords(shape)
649    the_copy = None
650    if shape_type == "polygon"
651        new_config = {key shape_config[key][-1] for key in shape_config.keys()}
652        if color != None
653            new_config["fill"] = color
654        the_copy = _a_canvas.create_polygon(shape_coords, new_config)
655        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):
658def mirror(shape):
659    """
660    A function that takes a shape and flips it across its vertical
661    axis, returning the modified shape.
662
663    Args:
664        shape (`Shape` or Tag): The shape in question.
665
666    """
667    center = get_center(shape)[0]
668    shape_ids = _a_canvas.find_withtag(shape)
669    for shape_id in shape_ids
670        flipped_coordinates = []
671        shape_coords = _a_canvas.coords(shape_id)
672        counter = 0
673        for num in shape_coords
674            if counter % 2 == 0
675                if num < center
676                    flipped_coordinates.append(num + 2 * (center - num))
677                elif num > center
678                    flipped_coordinates.append(num - 2 * (num - center))
679                else
680                    flipped_coordinates.append(num)
681            else
682                flipped_coordinates.append(num)
683            counter += 1
684        _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):
687def rotate(shape, degrees=5, origin=None):
688    """
689    A reporter function that takes a shape and rotates it by a specified amount around a specified point.
690    It does this by interpolating a polygon around the shape and calculating the shifts of individual
691    points on the edge of the polygon.
692
693    Args:
694        shape (`Shape` or Tag): The shape to rotate.
695        degrees (`int`): The number of degrees to rotate the shape.
696        origin (`tuple`): An `(x,y)` coordinate about which to perform the rotation. Defaults to the center
697            of the given shape.
698
699    Returns:
700        `Shape`: The modified shape.
701    """
702    if origin is None
703        origin = get_center(shape)
704
705    theta = radians(degrees)
706    ox, oy = origin
707
708    all_shapes = _a_canvas.find_withtag(shape)
709
710    for a_shape in all_shapes
711        coords = _a_canvas.coords(a_shape)
712        # update coordinates:
713        for i in range(0, len(coords), 2):
714            px, py = coords[i], coords[i + 1]
715            qx = cos(theta) * (px - ox) - sin(theta) * (py - oy) + ox
716            qy = sin(theta) * (px - ox) + cos(theta) * (py - oy) + oy
717            coords[i] = qx
718            coords[i + 1] = qy
719        # set the coordinates:
720        _a_canvas.coords(a_shape, coords)
721
722    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):
725def distance(point1, point2):
726    """
727    A reporter function calculates the distance between two `(x, y)` coordinates.
728
729    Args:
730        point1 (`tuple`): The first `(x, y)` coordinate.
731        point2 (`tuple`): The second `(x, y)` coordinate.
732
733    Returns:
734         A `float` representing the distance between the two points.
735    """
736    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 scale(shape, x_scale=1.0, y_scale=1.0):
739def scale(shape, x_scale=1.0, y_scale=1.0):
740    """
741    A function that takes a given `Shape` or tag and scales it on either/both the x and y-axis.
742
743    The two optional inputs accept floats between 0.0 and 1.0. Values greater than 1 will cause
744    the shape to grow along that access. Values less than 1.0 will cause the shape to shrink.
745
746    Args:
747        shape (`Shape` or Tag): The shape or tag to re-fill.
748        x_scale (`float`): How much to scale in the x-axis.
749        y_scale (`float`): How much to scale in the y-axis.
750    """
751    ids = _a_canvas.find_withtag(shape)
752
753    coord = get_center(shape)
754
755    for i in ids
756        _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.
def update_color(shape, color):
759def update_color(shape, color):
760    """
761    Change the fill color of a tagged object.
762
763    Args:
764        shape (`Shape` or Tag): The shape or tag to re-fill.
765        color (`str`): A color name or hex code to re-fill with.
766    """
767    ids = _a_canvas.find_withtag(shape)
768    for id in ids
769        _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):
772def interpolate_colors(color1, color2, frac):
773    """
774    A reporter function that generates a new color between two given colors.
775    Args:
776        color1 (`str`): The path of the file to wrap
777        color2 (`str`): The path of the file to wrap
778        frac (`float`): What fraction of each color to take. An input of 0 returns
779            color1, an input of 1 returns color2, an input of 0.5 returns a color
780            perfectly between the two.
781
782    Returns:
783         A color (as a hex `str`) to be used elsewhere
784    """
785    if "#" not in color1
786        color1 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color1)))
787    else
788        color1 = _tupelize_color(color1)
789    if "#" not in color2
790        color2 = tuple((c // 256 for c in _a_canvas.winfo_rgb(color2)))
791    else
792        color2 = _tupelize_color(color2)
793    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):
796def get_colors(shape_or_shapes):
797    """
798    A reporter function that returns all the colors associated with a tag or list of tags.
799
800    Args:
801        shape_or_shapes (`str`/`Shape` or `List`): the shape/tag or list of shapes/tags you"d like to find the colors of
802
803    Returns:
804        A `List` containing all unique colors associated with that tag(s)
805    """
806    all_shapes = []
807    if not isinstance(shape_or_shapes, ):
808        shape_or_shapes = [shape_or_shapes]
809    for shape in shape_or_shapes
810        all_shapes += _a_canvas.find_withtag(shape)
811
812    all_colors = []
813    for shape in all_shapes
814        color = _a_canvas.itemcget(shape, "fill")
815        if color not in all_colors
816            all_colors.append(color)
817
818    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):
821def get_center(shape):
822    """
823    A reporter function calculates the a coordinate at the center of some shape.
824
825    Args:
826        shape (`Shape` or Tag): The shape in question.
827
828    Returns:
829         A `tuple` representing center of the given shape.
830    """
831    bbox = _safe_bbox(shape)
832
833    if bbox is None
834        raise Exception(
835            f"We couldn"t find the shape with id/tag {shape}. Make sure it exists!"
836        )
837
838    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):
841def get_top(shape):
842    """
843    A reporter function calculates the minimum y-value of a given shape (since the y-axis is flipped).
844
845    Args:
846        shape (`Shape` or Tag): The shape in question.
847
848    Returns:
849         A `int` representing the minimum y-coordinate of the shape.
850    """
851    bbox = _safe_bbox(shape)
852    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):
855def get_bottom(shape):
856    """
857    A reporter function calculates the maximum y-value of a given shape (since the y-axis is flipped).
858
859    Args:
860        shape (`Shape` or Tag): The shape in question.
861
862    Returns:
863         A `int` representing the maximum y-coordinate of the shape.
864    """
865    bbox = _safe_bbox(shape)
866    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):
869def get_left(shape):
870    """
871    A reporter function calculates the minimum x-value of a given shape.
872
873    Args:
874        shape (`Shape` or Tag): The shape in question.
875
876    Returns:
877         A `int` representing the minimum x-coordinate of the shape.
878    """
879    bbox = _safe_bbox(shape)
880    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):
883def get_right(shape):
884    """
885    A reporter function calculates the maximum x-value of a given shape.
886
887    Args:
888        shape (`Shape` or Tag): The shape in question.
889
890    Returns:
891         A `int` representing the maximum x-coordinate of the shape.
892    """
893    bbox = _safe_bbox(shape)
894    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):
897def get_height(shape):
898    """
899    A reporter function calculates the height of some given shape.
900
901    Args:
902        shape (`Shape` or Tag): The shape in question.
903
904    Returns:
905         A `int` representing the height of the shape.
906    """
907    bbox = _safe_bbox(shape)
908    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):
911def get_width(shape):
912    """
913    A reporter function calculates the width of some given shape.
914
915    Args:
916        shape (`Shape` or Tag): The shape in question.
917
918    Returns:
919         An `int` representing width of the shape.
920    """
921    bbox = _safe_bbox(shape)
922    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):
925def make_grid(c, w, h):
926    """
927    Draws a grid on a screen with intervals of 100.
928
929    Args:
930        w (`int`): The width of the grid to draw
931        h (`int`): The height of the grid to draw
932    """
933    interval = 100
934    # Creates all vertical lines at intervals of 100
935    for i in range(0, w, interval):
936        _a_canvas.create_line(i, 0, i, h, tag="grid_line")
937    # Creates all horizontal lines at intervals of 100
938    for i in range(0, h, interval):
939        _a_canvas.create_line(0, i, w, i, tag="grid_line")
940    # Creates axis labels
941    offset = 2
942    for y in range(0, h, interval):
943        for x in range(0, w, interval):
944            _a_canvas.create_oval(
945                x - offset, y - offset, x + offset, y + offset, fill="black"
946            )
947            _a_canvas.create_text(
948                x + offset,
949                y + offset,
950                text="({0}, {1})".format(x, y),
951                anchor="nw",
952                font=("Purisa", 8),
953            )

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):
1010def does_tag_exist(tag):
1011    """
1012    Returns `True` if a given tag exists otherwise returns `False`.
1013
1014    Args:
1015        `tag` (`str`): [Required] The tag of the object to lookup.
1016
1017    """
1018    result = _a_canvas.find_withtag(tag)
1019
1020    if result
1021        return True
1022    else
1023        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():
1026def random_color():
1027    """
1028    Returns a random color as a `string` to be used with `tkinter`.
1029    It does not accept any inputs.
1030    """
1031    r = lambda randint(0, 255)
1032    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):
1038def setup_shapes(title, background="white", width=600, height=600):
1039    """
1040    A static function that sets up the pop-up window. DO NOT USE THIS FUNCTION.
1041    """
1042    global _a_canvas
1043    gui = Tk()
1044    gui.title(title)
1045    _a_canvas = Canvas(gui, background=background, width=width, height=width)
1046    _a_canvas.pack()
1047    make_grid(_a_canvas, width, height)
1048    return _a_canvas

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