diff --git a/docs/img/fill_square.png b/docs/img/fill_square.png new file mode 100644 index 0000000..6818450 Binary files /dev/null and b/docs/img/fill_square.png differ diff --git a/docs/img/square.png b/docs/img/square.png new file mode 100644 index 0000000..380dad9 Binary files /dev/null and b/docs/img/square.png differ diff --git a/docs/img/square_comparison.png b/docs/img/square_comparison.png new file mode 100644 index 0000000..9833a39 Binary files /dev/null and b/docs/img/square_comparison.png differ diff --git a/docs/img/stroke_square.png b/docs/img/stroke_square.png new file mode 100644 index 0000000..3f72c36 Binary files /dev/null and b/docs/img/stroke_square.png differ diff --git a/docs/shapes_text.md b/docs/shapes_text.md index 4a275c7..3900675 100644 --- a/docs/shapes_text.md +++ b/docs/shapes_text.md @@ -107,6 +107,108 @@ Results in: ![stroke_rect() example](img/stroke_rect.png) +### Squares + +To create a square there are 3 options: + +| Function | Description | +|------------------------------------------|----------------------------------------------------| +| [square(x, y, s)](#square) | Draw a square filled with color, and with a stroke | +| [fill_square(x, y, s)](#fill_square) | Draw an square filled with a color | +| [stroke_square(x, y, s)](#stroke_square) | Draw the outline of a square (its stroke) | + +
+ +
Comparison of 3 functions, note the red color was added for visibility, by default fill is black
+
+ +#### square() +```python +square(x, y, s) +``` + +**Parameters** + +- x: (int or float) The value of the x position of the square +- y: (int or float) The value of the y position of the square +- s: (int or float) The width and height of the square + +**Example(s):** + +*Creating a filled and stroked square at (100, 100) with a width and height of 75* + +```python hl_lines="7" +%%ignite + +def setup(): + size(200, 200) + +def draw(): + square(100, 100, 75) +``` + +Results in: + +![square() example](img/square.png) + +#### fill_square() +```python +fill_square(x, y, s) +``` + +**Parameters** + +- x: (int or float) The value of the x position of the square +- y: (int or float) The value of the y position of the square +- s: (int or float) The width and height of the square + +**Example(s):** + +*Creating a filled square at (100, 100) with a width and height of 75* + +```python hl_lines="7" +%%ignite + +def setup(): + size(200, 200) + +def draw(): + fill_square(100, 100, 75) +``` + +Results in: + +![fill_square() example](img/fill_square.png) + +#### stroke_square() +```python +stroke_square(x, y, s) +``` + +**Parameters** + +- x: (int or float) The value of the x position of the square +- y: (int or float) The value of the y position of the square +- s: (int or float) The width and height of the square + +**Example(s):** + +*Creating a stroked square at (100, 100) with a width and height of 75* + +```python hl_lines="7" +%%ignite + +def setup(): + size(200, 200) + +def draw(): + stroke_square(100, 100, 75) +``` + +Results in: + +![stroke_square() example](img/stroke_square.png) + ### Circles To create a circle there are 3 options: diff --git a/exercises/snek_game.ipynb b/exercises/snek_game.ipynb new file mode 100644 index 0000000..8fefb35 --- /dev/null +++ b/exercises/snek_game.ipynb @@ -0,0 +1,421 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import spark\n", + "%reload_ext spark" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Snek Game\n", + "\n", + "This is a recreation of snake; basically try to collect the red squares with the white snek (what you control). \n", + "\n", + "If you collide the head of the snek with any other segments you lose.\n", + "\n", + "## Controls\n", + "\n", + "w - Move snek up\n", + "\n", + "s - Move snek down\n", + "\n", + "a - Move snek left\n", + "\n", + "d - Move snek right\n", + "\n", + "## Notes\n", + "\n", + "- Make sure you run the first cell **before** the game so the spark library is imported\n", + "- Your mouse must be **in** the canvas for the keyboard events to register" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Running...\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{R}\\PY{err}{u}\\PY{err}{n}\\PY{err}{n}\\PY{err}{i}\\PY{err}{n}\\PY{err}{g}\\PY{err}{.}\\PY{err}{.}\\PY{err}{.}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Running..." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b7fbd6e0587e4747872281e83f413676", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e514713d2a3d45f897d393b1c752733f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Player state\n", + "score = 0\n", + "speed_y = 0\n", + "speed_x = 10\n", + "positions = [[150, 100]]\n", + "\n", + "# Game state\n", + "highscore = 0\n", + "game_over = False\n", + "WIDTH = 300\n", + "HEIGHT = 300\n", + "\n", + "def get_treat_pos() -> tuple: # Needs to be defined here so treat_pos can be initialized\n", + " \"\"\"Generates the new treat position\n", + " \n", + " Returns\n", + " -------\n", + " list:\n", + " The new coordinates in (x, y) order\n", + " \"\"\"\n", + " global WIDTH, HEIGHT\n", + " # Generate x pos\n", + " value_x = randint(WIDTH - 30) + 10\n", + " while not (value_x % 10 == 0):\n", + " value_x = randint(WIDTH - 30) + 10\n", + " \n", + " # Generate y pos\n", + " value_y = randint(HEIGHT - 30) + 10\n", + " while not (value_y % 10 == 0):\n", + " value_y = randint(HEIGHT - 30) + 10\n", + " \n", + " return [value_x, value_y]\n", + "\n", + "# Initialize treat position\n", + "treat_pos = get_treat_pos()\n", + "\n", + "def setup():\n", + " size(WIDTH, HEIGHT)\n", + " \n", + "def draw():\n", + " if not game_over:\n", + " gameloop()\n", + " else:\n", + " restart()\n", + "\n", + "def gameloop():\n", + " global highscore, score, game_over, positions, speed_x, speed_y, treat_pos\n", + " background(0)\n", + "\n", + " # Check and draw player treat\n", + " fill_style(\"Red\")\n", + " square(treat_pos[0], treat_pos[1], 10)\n", + " \n", + " # Set drawing colors\n", + " fill_style(\"White\")\n", + " seen = [] # Holds seen chunk positions\n", + " \n", + " # treat collision\n", + " if positions[0] == treat_pos:\n", + " score += 1\n", + "\n", + " # Create new treat\n", + " treat_pos = get_treat_pos()\n", + "\n", + " # Append new segment to snake\n", + " positions.append([positions[-1][0], positions[-1][1]])\n", + " \n", + " # Set new highscore if reached\n", + " if highscore < score:\n", + " highscore = score\n", + "\n", + " # Print helpful text at the top \n", + " text_size(20)\n", + " text(f\"Score: {score}\", 50, 10) \n", + " text(f\"Highscore: {highscore}\", 150, 10)\n", + "\n", + " # Move all snek chunks besides head, starting from the back\n", + " for index in range(len(positions)-1, 0, -1): \n", + " positions[index][0] = positions[index-1][0]\n", + " positions[index][1] = positions[index-1][1]\n", + "\n", + " # Check for all collisions besides treat collision\n", + " for index, position in enumerate(positions):\n", + " # Check collision with snek head and other segments\n", + " if position in seen:\n", + " game_over = True\n", + " break\n", + " else:\n", + " seen.append(position)\n", + " \n", + " if index == 0: # update First square\n", + " # Check keypress in key_pressed\n", + " position[0] += speed_x\n", + " position[1] += speed_y\n", + "\n", + " # Segment colisions with outer bounds\n", + " if position[0] > WIDTH - 10: # Hit right boundary\n", + " position[0] = 0\n", + " if position[0] < 0: # Hit left boundary\n", + " position[0] = 290\n", + " \n", + " # Check y colisions\n", + " if position[1] < 20: # Hit top boundary\n", + " position[1] = 290\n", + "\n", + " if position[1] > HEIGHT - 10: # Hit bottom boundary\n", + " position[1] = 20\n", + "\n", + " # Update current square to new position\n", + " square(position[0], position[1], 10) \n", + " \n", + "def key_pressed():\n", + " \"\"\"Controls all snek movement\"\"\"\n", + " global speed_x, speed_y\n", + " if key == \"d\": # Right\n", + " speed_x = 10\n", + " speed_y = 0\n", + " if key == \"a\": # Left\n", + " speed_x = -10\n", + " speed_y = 0\n", + " if key == \"s\": # Down\n", + " speed_y = 10\n", + " speed_x = 0\n", + " if key == \"w\": # Up\n", + " speed_y = -10\n", + " speed_x = 0\n", + " \n", + "def restart():\n", + " \"\"\"Resets game state after colliding with yourself\"\"\"\n", + " global score, game_over, positions\n", + " score = 0\n", + " game_over = False\n", + " positions = [[150,100]]\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/setup.py b/setup.py index dce9035..62b619b 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="schulich-ignite", - version="0.1.0", + version="0.1.1", author="Schulich Ignite", author_email="info@shulichignite.com", description="Spark library for Shulich Ignite sessions", diff --git a/spark/core.py b/spark/core.py index ee07ad1..a4f7b08 100644 --- a/spark/core.py +++ b/spark/core.py @@ -309,8 +309,10 @@ def key_repeated(self): pass # From .util.helper_functions.keyboard_functions @extern - def keys_held(self, *args): - pass + def keys_held(self, *args): pass + + @extern + def key_held(self, *args): pass # From .util.helper_functions.canvas_functions @@ -424,6 +426,10 @@ def line_width(self, *args): pass @extern def stroke_width(self, *args): pass + # From util.helper_functions.image_functions + @extern + def image(self, *args): pass + ### Helper Functions ### # From util.helper_functions.misc_functions @@ -431,6 +437,9 @@ def stroke_width(self, *args): pass @extern def parse_color(self, *args, func_name="parse_color"): pass + @extern + def color(self, *args): pass + @extern def parse_color_string(self, func_name, s): pass @@ -442,3 +451,12 @@ def random(self, *args): pass @extern def randint(self, *args): pass + + @extern + def bounding_box(self, *args): pass + + @extern + def collided(self, *args): pass + + @extern + def axis_overlapped(self, *args): pass diff --git a/spark/util/core_methods.py b/spark/util/core_methods.py index 2679932..ddc251b 100644 --- a/spark/util/core_methods.py +++ b/spark/util/core_methods.py @@ -8,6 +8,7 @@ from .helper_functions.square_functions import * from .helper_functions.text_functions import * from .helper_functions.triangle_functions import * +from .helper_functions.image_functions import * from .helper_functions.keyboard_functions import * diff --git a/spark/util/helper_functions/image_functions.py b/spark/util/helper_functions/image_functions.py new file mode 100644 index 0000000..cb46dc9 --- /dev/null +++ b/spark/util/helper_functions/image_functions.py @@ -0,0 +1,39 @@ +from __future__ import annotations +from typing import TYPE_CHECKING, Dict, Tuple +if TYPE_CHECKING: + from ...core import Core + +from ..decorators import * +from numbers import Real +from ipywidgets import Image +from ipycanvas import Canvas + + +_loaded_images: Dict[Tuple[str, int, int], Canvas] = {} + + +@validate_args([str, Real, Real, Real, Real]) +@ignite_global +def helper_image(self: Core, *args): + filename: str = args[0] + x: int = int(args[1]) + y: int = int(args[2]) + w: int = int(args[3]) + h: int = int(args[4]) + + key = (filename, abs(w), abs(h)) + + if key not in _loaded_images: + _loaded_images[key] = Canvas(width=abs(w), height=abs(h)) + _loaded_images[key].draw_image(Image.from_file(filename, width=abs(w), height=abs(h)), 0, 0, abs(w), abs(h)) + self.canvas.translate(x, y) + if w < 0: + self.canvas.scale(-1, 1) + if h < 0: + self.canvas.scale(1, -1) + self.canvas.draw_image(_loaded_images[key], 0, 0) + if h < 0: + self.canvas.scale(1, -1) + if w < 0: + self.canvas.scale(-1, 1) + self.canvas.translate(-x, -y) diff --git a/spark/util/helper_functions/keyboard_functions.py b/spark/util/helper_functions/keyboard_functions.py index a9f7979..b81a616 100644 --- a/spark/util/helper_functions/keyboard_functions.py +++ b/spark/util/helper_functions/keyboard_functions.py @@ -66,3 +66,11 @@ def helper_keys_held(self: Core, *keys, pattern=None): pattern = [True]*len(keys) match = [self._keys_held.get(key, False) == want for key, want in zip(keys, pattern)] return reduce(and_, match) + + +@validate_args([str], [str, bool]) +@ignite_global +def helper_key_held(self: Core, *args): + if len(args) == 1: + args.append(True) + return self.keys_held(args[0], pattern=[args[1]]) \ No newline at end of file diff --git a/spark/util/helper_functions/misc_functions.py b/spark/util/helper_functions/misc_functions.py index 34d36ff..7471af6 100644 --- a/spark/util/helper_functions/misc_functions.py +++ b/spark/util/helper_functions/misc_functions.py @@ -50,6 +50,10 @@ def clip(x, lb, ub): else: raise ArgumentNumError(func_name, [1, 3, 4], argc) +@validate_args([str], [Real], [Real, Real, Real], [Real, Real, Real, Real]) +@ignite_global +def helper_color(self, *args): + return self.parse_color(*args) @validate_args([Real, Real, Real, Real], [Real, Real, Real, Real, Real], @@ -83,3 +87,40 @@ def helper_random(self, *args): @ignite_global def helper_randint(self, *args): return random.randint(0, args[0]) + + +@validate_args([Real, Real, Real, Real]) +@ignite_global +def helper_bounding_box(self, *args): + x, y, w, h = args + left = min(x, x + w) + abs_width = abs(w) + top = min(y, y + h) + abs_height = abs(h) + + return (left, top, abs_width, abs_height) + +@validate_args([list, list], [list, list, bool], [tuple, tuple], [tuple, tuple, bool]) +@ignite_global +def helper_collided(self, *args): + x1, y1, width1, height1 = args[0] + x2, y2, width2, height2 = args[1] + + sizes = {'bounding_box1 width': width1, 'bounding_box1 height': height1, 'bounding_box2 width': width2, 'bounding_box2 height': height2} + + for size_name, size_val in sizes.items(): + if size_val < 0: + raise ArgumentError("collided expected {} to be greater or equal to 0, got {}".format(size_name, size_val)) + + overlap_on_equal = len(args) == 3 and args[2] + return self.axis_overlapped(x1, width1, x2, width2, overlap_on_equal) and self.axis_overlapped(y1, height1, y2, height2, overlap_on_equal) + +@validate_args([Real, Real, Real, Real], [Real, Real, Real, Real, bool]) +@ignite_global +def helper_axis_overlapped(self, *args): + point1, length1, point2, length2 = args[:4] + + if len(args) == 5 and args[4]: + return point1 + length1 >= point2 and point2 + length2 >= point1 + else: + return point1 + length1 > point2 and point2 + length2 > point1 diff --git a/test/CollidedTest.ipynb b/test/CollidedTest.ipynb new file mode 100644 index 0000000..b67a355 --- /dev/null +++ b/test/CollidedTest.ipynb @@ -0,0 +1,1276 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import spark\n", + "%reload_ext spark" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Stopped\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Stopped" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "85c831e38187414ab871d6be64ac4cea", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "81552cdfd3974aeab4e6ae4a654fd5ff", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Change the background color if the red square collides with the blue square\n", + "\n", + "base_back_color = \"rgb(255, 255, 200)\"\n", + "back_color = base_back_color\n", + "\n", + "def setup():\n", + " size(500, 500)\n", + " \n", + "def draw():\n", + " global base_back_color, back_color\n", + " background(back_color)\n", + " \n", + " fill_style(\"red\")\n", + " square(mouse_x, mouse_y, 100)\n", + " b1 = bounding_box(mouse_x, mouse_y, 100, 100)\n", + " \n", + " fill_style(\"blue\")\n", + " square(200, 200, 100)\n", + " b2 = bounding_box(200, 200, 100, 100)\n", + " \n", + " if collided(b1, b2):\n", + " back_color = \"green\"\n", + " else:\n", + " back_color = base_back_color" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Stopped\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Stopped" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "aac8114247054db5897e96315cdc1cf2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7fd9331242324f8c818fcce08644ea03", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Collide and stick - Red and blue rects should collide in middle and stop moving\n", + "\n", + "x1 = 0\n", + "y1 = 200\n", + "w1 = 50\n", + "h1 = 100\n", + "speed1 = 1.5\n", + "\n", + "x2 = 475\n", + "y2 = 225\n", + "w2 = 25\n", + "h2 = 50\n", + "speed2 = -1\n", + "\n", + "def setup():\n", + " size(500, 500)\n", + " \n", + "def draw():\n", + " global x1, y1, w1, h1, speed1\n", + " global x2, y2, w2, h2, speed2\n", + " background(\"pink\")\n", + " \n", + " if collided(bounding_box(x1 + speed1, y1, w1, h1), bounding_box(x2 + speed2, y2, w2, h2)):\n", + " speed1 = 0\n", + " speed2 = 0\n", + " \n", + " x1 += speed1\n", + " x2 += speed2\n", + " \n", + " fill_style(\"red\")\n", + " rect(x1, y1, w1, h1)\n", + " \n", + " fill_style(\"blue\")\n", + " rect(x2, y2, w2, h2)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Stopped\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Stopped" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1d120a4dd447458c970e85fc6ac6bec4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e1c76a76971146dab7bae413295b1c28", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Collide and bounce - Red and blue rects should collide in middle and bounce in opposire directions\n", + "\n", + "x1 = 0\n", + "y1 = 200\n", + "w1 = 50\n", + "h1 = 100\n", + "speed1 = 3\n", + "\n", + "x2 = 475\n", + "y2 = 225\n", + "w2 = 25\n", + "h2 = 50\n", + "speed2 = -4\n", + "\n", + "def setup():\n", + " size(500, 500)\n", + " \n", + "def draw():\n", + " global x1, y1, w1, h1, speed1\n", + " global x2, y2, w2, h2, speed2\n", + " background(\"purple\")\n", + " \n", + " if collided(bounding_box(x1, y1, w1, h1), bounding_box(x2, y2, w2, h2)):\n", + " speed1 *= -1\n", + " speed2 *= -1\n", + " \n", + " x1 += speed1\n", + " x2 += speed2\n", + " \n", + " fill_style(\"red\")\n", + " rect(x1, y1, w1, h1)\n", + " \n", + " fill_style(\"blue\")\n", + " rect(x2, y2, w2, h2)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Stopped\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Stopped" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4bcee6c187df454b94b0536705a3baf5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "66c860ce7aaf42b48b2767463820c9f3", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Check that bounding_box always is aligned from the top-left corner with positive width/height\n", + "\n", + "base_back_color = \"rgb(255, 255, 200)\"\n", + "back_color = base_back_color\n", + "\n", + "def setup():\n", + " global b2\n", + " size(500, 500)\n", + " b2 = bounding_box(300, 400, -100, -50)\n", + " if b2[0] != 200:\n", + " raise Exception(\"Expected b2 left edge to be 200, got \" + str(b2[0]))\n", + " if b2[1] != 350:\n", + " raise Exception(\"Expected b2 top edge to be 350, got \" + str(b2[1]))\n", + " if b2[2] != 100:\n", + " raise Exception(\"Expected b2 absolute width to be 100, got \" + str(b2[2]))\n", + " if b2[3] != 50:\n", + " raise Exception(\"Expected b2 absolute width to be 50, got \" + str(b2[3]))\n", + " \n", + "def draw():\n", + " global base_back_color, back_color, b2\n", + " background(back_color)\n", + " \n", + " fill_style(\"red\")\n", + " square(mouse_x, mouse_y, 100)\n", + " b1 = bounding_box(mouse_x, mouse_y, 100, 100)\n", + " \n", + " fill_style(\"blue\")\n", + " rect(*b2)\n", + " \n", + " if collided(b1, b2):\n", + " back_color = \"green\"\n", + " else:\n", + " back_color = base_back_color" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Done drawing.\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{D}\\PY{err}{o}\\PY{err}{n}\\PY{err}{e}\\PY{err}{ }\\PY{err}{d}\\PY{err}{r}\\PY{err}{a}\\PY{err}{w}\\PY{err}{i}\\PY{err}{n}\\PY{err}{g}\\PY{err}{.}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Done drawing." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0d98ba4834ab4210ac9bd8d5f204bf78", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
collided throws expected exceptions\n",
+       "with_negative_width1\n",
+       "with_negative_height2\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{c}\\PY{err}{o}\\PY{err}{l}\\PY{err}{l}\\PY{err}{i}\\PY{err}{d}\\PY{err}{e}\\PY{err}{d}\\PY{err}{ }\\PY{err}{t}\\PY{err}{h}\\PY{err}{r}\\PY{err}{o}\\PY{err}{w}\\PY{err}{s}\\PY{err}{ }\\PY{err}{e}\\PY{err}{x}\\PY{err}{p}\\PY{err}{e}\\PY{err}{c}\\PY{err}{t}\\PY{err}{e}\\PY{err}{d}\\PY{err}{ }\\PY{err}{e}\\PY{err}{x}\\PY{err}{c}\\PY{err}{e}\\PY{err}{p}\\PY{err}{t}\\PY{err}{i}\\PY{err}{o}\\PY{err}{n}\\PY{err}{s}\n", + "\\PY{err}{w}\\PY{err}{i}\\PY{err}{t}\\PY{err}{h}\\PY{err}{\\PYZus{}}\\PY{err}{n}\\PY{err}{e}\\PY{err}{g}\\PY{err}{a}\\PY{err}{t}\\PY{err}{i}\\PY{err}{v}\\PY{err}{e}\\PY{err}{\\PYZus{}}\\PY{err}{w}\\PY{err}{i}\\PY{err}{d}\\PY{err}{t}\\PY{err}{h}\\PY{err}{1}\n", + "\\PY{err}{w}\\PY{err}{i}\\PY{err}{t}\\PY{err}{h}\\PY{err}{\\PYZus{}}\\PY{err}{n}\\PY{err}{e}\\PY{err}{g}\\PY{err}{a}\\PY{err}{t}\\PY{err}{i}\\PY{err}{v}\\PY{err}{e}\\PY{err}{\\PYZus{}}\\PY{err}{h}\\PY{err}{e}\\PY{err}{i}\\PY{err}{g}\\PY{err}{h}\\PY{err}{t}\\PY{err}{2}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "collided throws expected exceptions\n", + "with_negative_width1\n", + "with_negative_height2" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Unhappy path\n", + "# Negative inputs are given directly to collided()\n", + "\n", + "def setup():\n", + " print(\"collided throws expected exceptions\")\n", + " size(100, 100)\n", + " expect_arg_error(with_negative_width1, \"collided expected bounding_box1 width to be greater or equal to 0, got -100\")\n", + " expect_arg_error(with_negative_height2, \"collided expected bounding_box2 height to be greater or equal to 0, got -50\")\n", + " \n", + "def expect_arg_error(func, expected_error):\n", + " try:\n", + " func()\n", + " except Exception as e:\n", + " if str(e) != expected_error:\n", + " print(\"FAIL:\\n\\tExpected \" + str(func.__name__) + \" to raise error:\\n\\t\\t\" + expected_error)\n", + " print(\"\\tbut received:\\n\\t\\t\" + str(e).replace(\"\\n\",\"\\n\\t\\t\"))\n", + " else:\n", + " print(\"FAIL:\\n\\tExpected \" + str(func.__name__) + \" to raise error:\\n\\t\\t\" + expected_error)\n", + " print(\"\\tbut it didn't raise any errors\")\n", + " \n", + "def with_negative_width1():\n", + " print(\"with_negative_width1\")\n", + " collided([0, 0, -100, 0], [0, 0, 0, 50])\n", + " \n", + "def with_negative_height2():\n", + " print(\"with_negative_height2\")\n", + " collided([0, 0, 100, 0], [0, 0, 0, -50])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/test/ColorTest.ipynb b/test/ColorTest.ipynb new file mode 100644 index 0000000..afa5ddb --- /dev/null +++ b/test/ColorTest.ipynb @@ -0,0 +1,675 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import spark\n", + "%reload_ext spark" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Done drawing.\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{D}\\PY{err}{o}\\PY{err}{n}\\PY{err}{e}\\PY{err}{ }\\PY{err}{d}\\PY{err}{r}\\PY{err}{a}\\PY{err}{w}\\PY{err}{i}\\PY{err}{n}\\PY{err}{g}\\PY{err}{.}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Done drawing." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "83740a812c2545f783b2c4d20e5a3ee7", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "#Expose parse_color as a global function called \"color\" #54\n", + "\n", + "def setup():\n", + " color('red')\n", + " color('blue')\n", + " color(0, 0, 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Error in setup() function: parse_color expected argument to match "Valid HTML format or color names", got notAColor\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{E}\\PY{err}{r}\\PY{err}{r}\\PY{err}{o}\\PY{err}{r}\\PY{err}{ }\\PY{err}{i}\\PY{err}{n}\\PY{err}{ }\\PY{err}{s}\\PY{err}{e}\\PY{err}{t}\\PY{err}{u}\\PY{err}{p}\\PY{err}{(}\\PY{err}{)}\\PY{err}{ }\\PY{err}{f}\\PY{err}{u}\\PY{err}{n}\\PY{err}{c}\\PY{err}{t}\\PY{err}{i}\\PY{err}{o}\\PY{err}{n}\\PY{err}{:}\\PY{err}{ }\\PY{err}{p}\\PY{err}{a}\\PY{err}{r}\\PY{err}{s}\\PY{err}{e}\\PY{err}{\\PYZus{}}\\PY{err}{c}\\PY{err}{o}\\PY{err}{l}\\PY{err}{o}\\PY{err}{r}\\PY{err}{ }\\PY{err}{e}\\PY{err}{x}\\PY{err}{p}\\PY{err}{e}\\PY{err}{c}\\PY{err}{t}\\PY{err}{e}\\PY{err}{d}\\PY{err}{ }\\PY{err}{a}\\PY{err}{r}\\PY{err}{g}\\PY{err}{u}\\PY{err}{m}\\PY{err}{e}\\PY{err}{n}\\PY{err}{t}\\PY{err}{ }\\PY{err}{t}\\PY{err}{o}\\PY{err}{ }\\PY{err}{m}\\PY{err}{a}\\PY{err}{t}\\PY{err}{c}\\PY{err}{h}\\PY{err}{ }\\PY{err}{\\PYZdq{}}\\PY{err}{V}\\PY{err}{a}\\PY{err}{l}\\PY{err}{i}\\PY{err}{d}\\PY{err}{ }\\PY{err}{H}\\PY{err}{T}\\PY{err}{M}\\PY{err}{L}\\PY{err}{ }\\PY{err}{f}\\PY{err}{o}\\PY{err}{r}\\PY{err}{m}\\PY{err}{a}\\PY{err}{t}\\PY{err}{ }\\PY{err}{o}\\PY{err}{r}\\PY{err}{ }\\PY{err}{c}\\PY{err}{o}\\PY{err}{l}\\PY{err}{o}\\PY{err}{r}\\PY{err}{ }\\PY{err}{n}\\PY{err}{a}\\PY{err}{m}\\PY{err}{e}\\PY{err}{s}\\PY{err}{\\PYZdq{}}\\PY{err}{,}\\PY{err}{ }\\PY{err}{g}\\PY{err}{o}\\PY{err}{t}\\PY{err}{ }\\PY{err}{n}\\PY{err}{o}\\PY{err}{t}\\PY{err}{A}\\PY{err}{C}\\PY{err}{o}\\PY{err}{l}\\PY{err}{o}\\PY{err}{r}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Error in setup() function: parse_color expected argument to match \"Valid HTML format or color names\", got notAColor" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "d05be34004874205ab7297886359bb7c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "def setup():\n", + " color('notAColor')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Done drawing.\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{D}\\PY{err}{o}\\PY{err}{n}\\PY{err}{e}\\PY{err}{ }\\PY{err}{d}\\PY{err}{r}\\PY{err}{a}\\PY{err}{w}\\PY{err}{i}\\PY{err}{n}\\PY{err}{g}\\PY{err}{.}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Done drawing." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0d56ce0edea24722b8162fd6cc914d36", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "def setup():\n", + " size(300, 300)\n", + " r = color(\"red\")\n", + " g = color(\"green\")\n", + " b = color(\"blue\")\n", + " col_temps = [r, g, b]\n", + " diams = [25*(11-i) for i in range(1, 11)]\n", + " cols = [col_temps[i%3] for i in range(1,11)]\n", + " for d, c in zip(diams, cols):\n", + " fill_style(c)\n", + " fill_circle(width/2, height/2, d)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/test/EllipseAndArcTest.ipynb b/test/EllipseAndArcTest.ipynb index f64e00c..11dbd39 100644 --- a/test/EllipseAndArcTest.ipynb +++ b/test/EllipseAndArcTest.ipynb @@ -271,7 +271,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.6" } }, "nbformat": 4, diff --git a/test/ImageTest.ipynb b/test/ImageTest.ipynb new file mode 100644 index 0000000..064072c --- /dev/null +++ b/test/ImageTest.ipynb @@ -0,0 +1,494 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import spark\n", + "%reload_ext spark" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Stopped\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{S}\\PY{err}{t}\\PY{err}{o}\\PY{err}{p}\\PY{err}{p}\\PY{err}{e}\\PY{err}{d}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Stopped" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "0ddbc8cde8d045f88a6c017718515c44", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e046aeb247a14f4e8b2d1d56f40eddfb", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Renders an image of BugBuster.png\n", + "\n", + "x = 0\n", + "\n", + "def setup():\n", + " size(500, 500)\n", + " \n", + "def draw():\n", + " global x\n", + " background(\"aqua\")\n", + " image(\"assets/BugBuster.png\", x, 10, 200, 200)\n", + " x += 2\n", + " x %= width" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Error in draw() function: [Errno 2] No such file or directory: 'assets/not_an_image'\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{E}\\PY{err}{r}\\PY{err}{r}\\PY{err}{o}\\PY{err}{r}\\PY{err}{ }\\PY{err}{i}\\PY{err}{n}\\PY{err}{ }\\PY{err}{d}\\PY{err}{r}\\PY{err}{a}\\PY{err}{w}\\PY{err}{(}\\PY{err}{)}\\PY{err}{ }\\PY{err}{f}\\PY{err}{u}\\PY{err}{n}\\PY{err}{c}\\PY{err}{t}\\PY{err}{i}\\PY{err}{o}\\PY{err}{n}\\PY{err}{:}\\PY{err}{ }\\PY{err}{[}\\PY{err}{E}\\PY{err}{r}\\PY{err}{r}\\PY{err}{n}\\PY{err}{o}\\PY{err}{ }\\PY{err}{2}\\PY{err}{]}\\PY{err}{ }\\PY{err}{N}\\PY{err}{o}\\PY{err}{ }\\PY{err}{s}\\PY{err}{u}\\PY{err}{c}\\PY{err}{h}\\PY{err}{ }\\PY{err}{f}\\PY{err}{i}\\PY{err}{l}\\PY{err}{e}\\PY{err}{ }\\PY{err}{o}\\PY{err}{r}\\PY{err}{ }\\PY{err}{d}\\PY{err}{i}\\PY{err}{r}\\PY{err}{e}\\PY{err}{c}\\PY{err}{t}\\PY{err}{o}\\PY{err}{r}\\PY{err}{y}\\PY{err}{:}\\PY{err}{ }\\PY{err}{\\PYZsq{}}\\PY{err}{a}\\PY{err}{s}\\PY{err}{s}\\PY{err}{e}\\PY{err}{t}\\PY{err}{s}\\PY{err}{/}\\PY{err}{n}\\PY{err}{o}\\PY{err}{t}\\PY{err}{\\PYZus{}}\\PY{err}{a}\\PY{err}{n}\\PY{err}{\\PYZus{}}\\PY{err}{i}\\PY{err}{m}\\PY{err}{a}\\PY{err}{g}\\PY{err}{e}\\PY{err}{\\PYZsq{}}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Error in draw() function: [Errno 2] No such file or directory: 'assets/not_an_image'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "7450d824fedd4658b65030a7194d8664", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Button(description='Stop', style=ButtonStyle())" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9e225f45d15e499697fd6b55ff55ab3a", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "# Throws appropriate error when image is not found\n", + "\n", + "def setup():\n", + " size(500, 500)\n", + " \n", + "def draw():\n", + " background(\"aqua\")\n", + " image(\"assets/not_an_image\", 10, 10, 200, 200)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/test/RectAndCircleTest.ipynb b/test/RectAndCircleTest.ipynb index 18d92b3..c4829ef 100644 --- a/test/RectAndCircleTest.ipynb +++ b/test/RectAndCircleTest.ipynb @@ -255,7 +255,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.8.6" } }, "nbformat": 4, diff --git a/test/SquareTest.ipynb b/test/SquareTest.ipynb new file mode 100644 index 0000000..c3b4c1e --- /dev/null +++ b/test/SquareTest.ipynb @@ -0,0 +1,255 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import spark\n", + "%reload_ext spark" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Done drawing.\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{err}{D}\\PY{err}{o}\\PY{err}{n}\\PY{err}{e}\\PY{err}{ }\\PY{err}{d}\\PY{err}{r}\\PY{err}{a}\\PY{err}{w}\\PY{err}{i}\\PY{err}{n}\\PY{err}{g}\\PY{err}{.}\n", + "\\end{Verbatim}\n" + ], + "text/plain": [ + "Done drawing." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8fd8f5e012094139bb3f5162c42064a5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Canvas(height=100, width=100)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "
\n" + ], + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\n", + "\\end{Verbatim}\n" + ], + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%%ignite\n", + "\n", + "def setup():\n", + " size(200, 500)\n", + " background(\"default\")\n", + " fill_style(\"green\")\n", + " stroke_style(\"magenta\")\n", + " square(50, 50, 100)\n", + " fill_square(50, 200, 100)\n", + " stroke_square(50, 350, 100)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/test/assets/BugBuster.png b/test/assets/BugBuster.png new file mode 100644 index 0000000..6480b57 Binary files /dev/null and b/test/assets/BugBuster.png differ