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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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!
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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
orList
): the shape/tag or list of shapes/tags you'd like to find the colors of
Returns:
A
List
containing all unique colors associated with that tag(s)
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.