Example #1
0
def scroll_txt(image, text_width):
    unicornhathd.rotation(0)
    for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)
        unicornhathd.show()
        time.sleep(0.02)
    unicornhathd.off()
def main():
    uhat.clear()
    uhat.set_rotation(90)
    uhat.show()

    try:
        while True:
            sky_show()
            ground_show()
    except KeyboardInterrupt:
        uhat.off()
        exit()
def UnicornTextScroll():

    TEXT_FULL = conf.SCROLL_TEXT_RND
    TEXT_LEN = RandomNum(len(TEXT_FULL))
    TEXT = TEXT_FULL[TEXT_LEN]
    print("Scrolling text: " + TEXT)

    #TEXT = conf.SCROLL_TEXT
    FONT = ('/usr/share/fonts/truetype/freefont/FreeSansBold.ttf', 12)

    width, height = unicorn.get_shape()

    unicorn.rotation(270)

    text_x = 1
    text_y = 2

    font_file, font_size = FONT
    font = ImageFont.truetype(font_file, font_size)
    text_width, text_height = font.getsize(TEXT)
    text_width += width + text_x
    image = Image.new('RGB', (text_width, max(height, text_height)), (0, 0, 0))
    draw = ImageDraw.Draw(image)
    draw.text((text_x, text_y), TEXT, fill=(255, 255, 255), font=font)

    for scroll in range(text_width - width):
        for x in range(width):
            hue = (x + scroll) / float(text_width)

            br, bg, bb = [
                int(n * 255) for n in colorsys.hsv_to_rgb(hue, 1.0, 1.0)
            ]

            for y in range(height):

                pixel = image.getpixel((x + scroll, y))

                r, g, b = [float(n / 255.0) for n in pixel]

                r = int(br * r)
                g = int(bg * g)
                b = int(bb * b)
                unicorn.set_pixel(width - 1 - x, y, r, g, b)

        unicorn.show()

        # And sleep for a little bit, so it doesn't scroll too quickly!
        time.sleep(0.02)

    unicorn.off()

    return 0
Example #4
0
def main(run, running):
    running(True)
    setup()
    shouldRun = run()
    while shouldRun:
        for i in range(0, (uh_width - 2) * (uh_height - 1)):
            shouldRun = drop_ball(run)
            if not shouldRun:
                break
        time.sleep(1)
        setup()
    unicorn.off()
    running(False)
Example #5
0
def main():
    try:
        os.mkdir(SAVES_DIR)
    except:
        pass
    try:
        print("Serving on port 3001")
        server = pywsgi.WSGIServer(('', 3001),
                                   app,
                                   handler_class=WebSocketHandler)
        server.serve_forever()
    finally:
        unicorn.off()
Example #6
0
def main(run, running):
    running(True)
    candle, palette = candle_setup()
    step = 0
    v = 500
    oldv = v

    while run():
        # step for waving animation, adds some randomness
        step += randint(0, 15)

        # clone the current candle
        temp = candle[:]

        # seed new heat
        v = 500

        set_pixel(candle, 6, 15, v)
        set_pixel(candle, 7, 15, v)
        set_pixel(candle, 8, 15, v)
        set_pixel(candle, 9, 15, v)
        set_pixel(candle, 6, 14, v)
        set_pixel(candle, 7, 14, v)
        set_pixel(candle, 8, 14, v)
        set_pixel(candle, 9, 14, v)

        # blur, wave, and shift up one step
        for x in range(0, 16):
            for y in range(0, 16):
                s = math.sin((y / 30.0) + (step / 10.0)) * ((16 - y) / 20.0)
                v = 0
                for i in range(0, 3):
                    for j in range(0, 3):
                        # r = randint(0, 2) - 1
                        v += get_pixel(candle, x + i + s - 1, y + j)

                v /= 10
                set_pixel(temp, x, y, v)

        candle = temp

        # copy candle into UHHD with palette
        for x in range(0, 16):
            for y in range(0, 16):
                o = (i * 3) + 1
                r, g, b = palette[max(0, min(255, get_pixel(candle, x, y)))]
                unicornhathd.set_pixel(x, y, r, g, b)

        unicornhathd.show()
    unicornhathd.off()
    running(False)
Example #7
0
def display_text(data):
    text = "{} from {} backers = {}%!".format(data['pledged'], data['backers'],
                                              data['percent'])

    colours = [
        tuple([int(n * 255) for n in colorsys.hsv_to_rgb(x / 1.0, 1.0, 1.0)])
        for x in range(1)
    ]

    FONT = ("/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf", 12)

    unicornhathd.rotation(0)
    unicornhathd.brightness(1.0)

    width, height = unicornhathd.get_shape()

    text_x = width
    text_y = 2

    font_file, font_size = FONT

    font = ImageFont.truetype(font_file, font_size)

    text_width, text_height = width, 0

    w, h = font.getsize(text)
    text_width += w + width
    text_height = max(text_height, h)

    text_width += width + text_x + 1

    image = Image.new("RGB", (text_width, max(16, text_height)), (0, 0, 0))
    draw = ImageDraw.Draw(image)

    offset_left = 0

    draw.text((text_x, text_y), text, colours[index], font=font)

    for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)

        unicornhathd.show()
        time.sleep(0.01)

    unicornhathd.off()
    return
Example #8
0
def flash_all(flash_count, delay, color):
    # light all of the LEDs in a RGB single color. Repeat 'flash_count' times
    # keep illuminated for 'delay' value
    for index in range(flash_count):
        # fill the light buffer with the specified color
        unicornhathd.set_all(*color)
        # show the color
        unicornhathd.show()
        # wait a bit
        time.sleep(delay)
        # turn everything off
        unicornhathd.off()
        # wait a bit more
        time.sleep(delay)
Example #9
0
def setup():

    global heights
    heights = []
    for b in range(0, (uh_width - 2)):
        heights.append(0)
    unicorn.off()
    for b in range(0, uh_height):
        unicorn.set_pixel(0, b, 255, 255, 255)
    for b in range(0, uh_height):
        unicorn.set_pixel((uh_width - 1), b, 255, 255, 255)
    for b in range(1, (uh_width - 1)):
        unicorn.set_pixel(b, 0, 255, 255, 255)
    unicorn.show()
Example #10
0
def flash_random(flash_count, delay, between_delay=0):
    # Copied from https://github.com/pimoroni/unicorn-hat-hd/blob/master/examples/test.py
    for index in range(flash_count):
        # fill the light buffer with random colors
        unicornhathd._buf = unicornhathd.numpy.random.randint(low=0, high=255, size=(16, 16, 3))
        # show the colors
        unicornhathd.show()
        # wait a bit
        time.sleep(delay)
        # turn everything off
        unicornhathd.off()
        # do we have a between_delay value??
        if between_delay > 0:
            # wait a bit more
            time.sleep(between_delay)
Example #11
0
    def _animate_text(self, line, cycle_time=0.10, font=None):
        if line == None or type(line) is str == False:
            print("Not a string:", line)
            return

        self._lock_ui.acquire()

        text_font = self._default_font

        if font != None:
            # TODO: Check whether file exists
            custom_self._default_font_file = 'fonts/' + font + '.ttf'
            try:
                text_font = ImageFont.truetype(custom_self._default_font_file, self._default_font_size)
            except IOError:
                text_font = self._default_font

        text_width = self._unicorn_width
        text_height = 0
        text_x = self._unicorn_width
        text_y = 2

        w, h = text_font.getsize(line)
        text_width += w + self._unicorn_width
        text_height = max(text_height, h)

        text_width += self._unicorn_width + text_x + 1

        image = Image.new('RGB', (text_width, max(16, text_height)), (0, 0, 0))
        draw = ImageDraw.Draw(image)

        offset_left = 0

        draw.text((text_x + offset_left, text_y), line, font=self._default_font, fill=(255,255,255,255))
        offset_left += self._default_font.getsize(line)[0] + self._unicorn_width

        for scroll in range(text_width - self._unicorn_width):
            for x in range(self._unicorn_width):
                for y in range(self._unicorn_height):
                    pixel = image.getpixel((x + scroll, y))
                    r, g, b = [int(n) for n in pixel]
                    unicorn.set_pixel(self._unicorn_width - 1 - x, y, r, g, b)

            unicorn.show()
            time.sleep(cycle_time / 5)
        unicorn.off()

        self._lock_ui.release()
def paint():
    try:
        result = request.json
        for x in range(width):
            for y in range(height):
                if result[x][y] == '1':
                    r, g, b = randint(0, 255), randint(0, 255), randint(0, 255)
                else:
                    r, g, b = 0, 0, 0
                unicornhathd.set_pixel(x, y, r, g, b)
            # change flash timming
            unicornhathd.show()
        return jsonify({'result': 0})
    except:
        unicornhathd.off()
        return jsonify({'result': 1})
Example #13
0
def do_swirl(duration):
    # modified from: https://github.com/pimoroni/unicorn-hat-hd/blob/master/examples/demo.py
    step = 0
    for i in range(duration):
        for y in range(u_height):
            for x in range(u_width):
                r, g, b = swirl(x, y, step)
                r = int(max(0, min(255, r)))
                g = int(max(0, min(255, g)))
                b = int(max(0, min(255, b)))
                unicornhathd.set_pixel(x, y, r, g, b)
        step += 2
        unicornhathd.show()
        time.sleep(0.01)
    # turn off all lights when you're done
    unicornhathd.off()
Example #14
0
def icon_show(run, running):
    running(True)
    list = []
    try:
        cmd = "echo ~/lamp2/icons/*"
        cmd2 = "pwd"
        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        output, error = process.communicate()
        output = str(output)[2:-3]
        print(output)
        list = output.split()
        print(list)
    except:
        print("except 1")
    shuffle(list)
    print(list)
    for path in list:
        img = Image.open(path)
        img.load()
        #img = img.convert("RGB")
        try:
            background = Image.new("RGB", img.size, (0, 0, 0))
            background.paste(img,
                             mask=img.split()[3])  # 3 is the alpha channel
        except:
            background = img
        A = np.asarray(background)
        for x in range(16):
            for y in range(16):
                #print(A[x][y], end = "\t")
                temp = A[x][y]
                try:
                    unicorn.set_pixel(x, y, temp[0], temp[1], temp[2])
                except:
                    unicorn.set_pixel(x, y, temp, 0, temp)
                #print()
        unicorn.show()
        now = time.monotonic()
        while time.monotonic() - now < 10:

            if not run():
                unicorn.off()
                running(False)
                return
            time.sleep(0.1)
    unicorn.off()
    running(False)
Example #15
0
def tidal_handler(*args):

    try:
        unicornhathd.brightness(1)

        red = 0
        blue = 0
        green = 0
        crush = False
        sustain = 1
        ldecay = 0.05

        for num, arg in enumerate(args, start=1):
            ##            print("{0}: {1}".format(num, arg))

            if arg == "red":
                red = int(args[num])
            elif arg == "green":
                green = int(args[num])
            elif arg == "blue":
                blue = int(args[num])
            elif arg == "ldecay":
                ldecay = float(args[num])
            elif arg == "sustain":
                sustain = float(args[num])
            elif arg == "crush":
                crush = True

        print("r: {0}, g: {1}, b: {2}, crush: {3}, sustain: {4}, ldecay: {5}".
              format(red, green, blue, crush, sustain, ldecay))

        if crush == True:
            red = 255
            blue = 255
            green = 255
            ldecay = 1.0

        unicornhathd.set_all(red, green, blue)
        unicornhathd.show()

        ##        print("about to sleep for {0}".format(ldecay * sustain))
        time.sleep(ldecay * sustain)
        ##        print(".....awake!")
        unicornhathd.off()

    except KeyboardInterrupt:
        unicornhathd.off()
def draw(pixels):
  print('DRAW', len(pixels))
  valid = False
  try:
    for p in pixels:
      valid = False
      x, y, r, g, b = int(p[0]), int(p[1]), int(p[2]), int(p[3]), int(p[4])
      if x != '' and y != '':
        if r or g or b:
          valid = True
          unicornhathd.set_pixel(x, y, r, g, b)

    if valid:
      unicornhathd.show()

  except:
    unicornhathd.off()
Example #17
0
def main(run, running):
    running(True)
    life = GameOfLife()

    life_last_seeded = time.monotonic()
    while run():
        life.next_generation()
        life.show_board()

        duration = time.monotonic() - life_last_seeded
        if life.all_dead() or ((randint(0, 1000) > 990)
                               and duration > 15) or duration > 100:
            life.random_new_live()
            life_last_seeded = time.monotonic()
        time.sleep(0.05)
    unicornhathd.off()
    running(False)
Example #18
0
def Color(h, s, v, run, running):
    running(True)
    h = float(h) / 360.0
    s = float(s)
    v = float(v)
    # x0, y0 current center
    x0 = uniform(0, 15)
    y0 = uniform(0, 15)

    # y_goal, x_goal -> goal
    y_goal = uniform(0, 15)
    x_goal = uniform(0, 15)
    while run() and v != 0:
        if x0 == x_goal and y0 == y_goal:
            print("color - arrived", end="\tx:\t")
            print(x_goal, end="\ty:\t")
            print(y_goal)

            # goal reached, create new goal
            y_goal = uniform(0, 15)
            x_goal = uniform(0, 15)

        direction = [x_goal - x0, y_goal - y0]
        distance = np.linalg.norm(direction)

        # 0.05 is max velocity of movement
        if distance > 0.05:
            rescale = 0.05 / distance
            direction[0] *= rescale
            direction[1] *= rescale

        # move towards goal
        x0 += direction[0]
        y0 += direction[1]

        #create dists and v_map
        make_mapping(v, x0, y0)

        for x in range(u_width):
            for y, v_from_v_map in zip(range(u_height), v_map[x]):
                unicorn.set_pixel_hsv(x, y, h, s, v_from_v_map)
        unicorn.show()

    unicorn.off()
    running(False)
def icon(image):
    try:
        for o_x in range(int(image.size[0] / width)):
            for o_y in range(int(image.size[1] / height)):
                valid = False
                for x in range(width):
                    for y in range(height):
                        pixel = image.getpixel(
                            ((o_x * width) + y, (o_y * height) + x))
                        r, g, b = int(pixel[0]), int(pixel[1]), int(pixel[2])
                        if r or g or b:
                            valid = True
                        unicorn.set_pixel(x, y, r, g, b)
                if valid:
                    unicorn.show()
                    time.sleep(2)
    except KeyboardInterrupt:
        unicorn.off()
Example #20
0
def set_activity_light(color, increment):
    # used to turn on one LED at a time across the bottom row of lights. The app uses this as an unobtrusive
    # indicator when it connects to Google to check the calendar. Its intended as a subtle reminder that things
    # are still working.
    global current_activity_light
    # turn off (clear) any lights that are on
    unicornhathd.off()
    if increment:
        # OK. Which light will we be illuminating?
        if current_activity_light < 1:
            # start over at the beginning when you're at the end of the row
            current_activity_light = u_width
        # increment the current light (to the next one)
        current_activity_light -= 1
    # set the pixel color
    unicornhathd.set_pixel(current_activity_light, indicator_row, *color)
    # show the pixel
    unicornhathd.show()
Example #21
0
def setPicture(pic, run, running):
    running(True)
    pic = decompress(pic)
    list = re.findall('......', pic)
    x = 0
    y = 0
    for val in list:
        pixel = fromHex(val)
        unicorn.set_pixel(x, y, pixel[0], pixel[1], pixel[2])

        x += 1
        if x == 16:
            x = 0
            y += 1
    unicorn.show()
    while run():
        time.sleep(0.01)
    unicorn.off()
    running(False)
Example #22
0
def im_capture(bg):
    '''Cycles valve and captures an image to a numpy array'''
    #if bg == False:
    GPIO.output(VALVE, True)
    time.sleep(valve_time)
    GPIO.output(VALVE, False)
    time.sleep(valve_time)
    a = 255
    with picamera.PiCamera() as camera:
        pihat.brightness(1.0)
        pihat.clear()
        for y in range(16):
            for x in range(16):
                v = display[x, y]  # brightness depends on range
                if v == 0:
                    red = int(a)  # makes 0-1 range > 0-255 range
                    green = int(a)
                    blue = int(a)
                elif v == 1:
                    red = int(0)
                    green = int(0)
                    blue = int(0)
                elif v == 2:
                    red = int(0)
                    green = int(0)
                    blue = int(0)
                pihat.set_pixel(x, y, red, green, blue)  # sets pixels on the hat
        pihat.rotation(180)
        pihat.show()  # show the pixels
        camera.resolution = (1664, 1232)
        camera.awb_mode = 'off'
        camera.awb_gains = (1.2, 1.2)
        camera.framerate = 30
        output = np.empty((1232, 1664, 3), dtype=np.uint8)
        #camera.start_preview()
        time.sleep(2)
        camera.capture(output, 'rgb')
        time.sleep(1)
        #camera.stop_preview()
        pihat.clear()
        pihat.off()
    return output/255.
Example #23
0
def display_text(message, color=WHITE):
    # Use `fc-list` to show a list of installed fonts on your system,
    # or `ls /usr/share/fonts/` and explore.
    FONT = ('/usr/share/fonts/truetype/roboto/Roboto-Bold.ttf', 10)

    global u_height, u_width

    # do we have a message?
    if len(message) > 0:
        # then display it
        # code borrowed from: https://github.com/pimoroni/unicorn-hat-hd/blob/master/examples/text.py
        text_x = u_width
        text_y = 2

        font_file, font_size = FONT

        font = ImageFont.truetype(font_file, font_size)

        # =====================================================================
        # I'm really not sure what all this code does...that's what happens when you 'borrow' code
        # it basically sets up the width of the display string to include the string as well as enough
        # space to scroll it off the screen
        # =====================================================================
        text_width, text_height = u_width, 0
        w, h = font.getsize(message)
        text_width += w + u_width
        text_height = max(text_height, h)
        text_width += u_width + text_x + 1
        image = Image.new("RGB", (text_width, max(16, text_height)), (0, 0, 0))
        draw = ImageDraw.Draw(image)
        offset_left = 0
        draw.text((text_x + offset_left, text_y), message, color, font=font)
        offset_left += font.getsize(message)[0] + u_width
        for scroll in range(text_width - u_width):
            for x in range(u_width):
                for y in range(u_height):
                    pixel = image.getpixel((x + scroll, y))
                    r, g, b = [int(n) for n in pixel]
                    unicornhathd.set_pixel(u_width - 1 - x, y, r, g, b)
            unicornhathd.show()
            time.sleep(0.01)
        unicornhathd.off()
Example #24
0
def weather_icons():
    try:

        if argv[1] == 'loop':

            loop()

        elif argv[1] in os.listdir(folder_path):

            print('Drawing Image: {}'.format(argv[1]))

            img = Image.open(folder_path + argv[1])

            draw_animation(img)
            unicorn.off()

        else:
            help()

    except IndexError:
        help()
Example #25
0
def main():
    uh.rotation(180)
    display(greeting)
    time.sleep(1.0)
    unsorted_array = build_array()
    uh.rotation(270)
    show_array(unsorted_array, False)
    time.sleep(1.0)
    arr = bubble_sort(list(unsorted_array))
    #show_array(arr, False)
    time.sleep(1.0)
    show_array(unsorted_array, False)
    time.sleep(1.0)
    arr = insertion_sort(list(unsorted_array))
    #show_array(arr, False)
    time.sleep(1.0)
    show_array(unsorted_array, False)
    time.sleep(1.0)
    arr = quicksort(list(unsorted_array))
    show_array(arr, False)
    time.sleep(1)
    uh.off()
Example #26
0
    def control_LED(self):
        while True:
            try:
                try:
                    targetImage = Image.open(RESOURCE_DIR +
                                             self._curImageName +
                                             LED_SPRITE_FORMAT)
                    self.show_LED(self._curImageName, targetImage,
                                  self._curType)

                except IOError, e:
                    print "Waiting loading Image (After Download Image)"
                    print e

                except KeyError:
                    print("not exist image")

            except KeyboardInterrupt:
                print("disconnected")
                unicornhathd.off()
                print("receiveMsg KeyboardInterrupt")
                break
def UnicornMatrix():

    print("Running matrix")

    unicorn.rotation(90)
    lenght = conf.MATRIX_LENGHT
    current_pos = 1

    wrd_rgb = [[154, 173, 154], [0, 255, 0], [0, 235, 0], [0, 220, 0],
               [0, 185, 0], [0, 165, 0], [0, 128, 0], [0, 0, 0],
               [154, 173, 154], [0, 145, 0], [0, 125, 0], [0, 100, 0],
               [0, 80, 0], [0, 60, 0], [0, 40, 0], [0, 0, 0]]

    clock = 0

    blue_pilled_population = [[randint(0, 15), 15]]

    while (current_pos <= lenght):
        for person in blue_pilled_population:
            y = person[1]
            for rgb in wrd_rgb:
                if (y <= 15) and (y >= 0):
                    unicorn.set_pixel(person[0], y, rgb[0], rgb[1], rgb[2])
                y += 1
            person[1] -= 1
        unicorn.show()
        time.sleep(0.1)
        clock += 1

        if clock % 5 == 0:
            blue_pilled_population.append([randint(0, 15), 15])
        if clock % 7 == 0:
            blue_pilled_population.append([randint(0, 15), 15])

        while len(blue_pilled_population) > 100:
            blue_pilled_population.pop(0)
        current_pos = current_pos + 1
    unicorn.off()
    return 0
Example #28
0
def main():
    handler = test_handler(10)
    try:
        print("Press Ctrl+C to exit")
        unicorn.brightness(0.5)
        #setColor(255,0,255,test_run,test_running)
        flavor = -2
        #eye(handler.test_run, handler.test_running, 0.5, 0.9, 1)
        #Color(0.7, 0.9, 1, handler.test_run, handler.test_running)
        hsv_wave(handler.test_run, handler.test_running, [0, 5, 1, 10])
        while True:
            for x in range(5):
                for y in range(5):
                    flavor_list = [flavor, x, y, 10]
                    print("FlavorList: ", end="\t")
                    print(flavor_list)
                    hsv_wave(handler.test_run, handler.test_running,
                             flavor_list)
            flavor += 1

    except KeyboardInterrupt:
        unicorn.off()
Example #29
0
def display_happy(filename):

    unicornhathd.rotation(90)
    unicornhathd.brightness(0.5)

    width, height = unicornhathd.get_shape()

    img = Image.open(filename)

    valid = False
    for x in range(width):
        for y in range(height):
            pixel = img.getpixel((y, x))
            r, g, b = int(pixel[0]), int(pixel[1]), int(pixel[2])
            if r or g or b:
                valid = True
            unicornhathd.set_pixel(x, y, r, g, b)
    if valid:
        unicornhathd.show()
        time.sleep(5)
        unicornhathd.off()
    return
Example #30
0
def beat():

    unicornhathd.brightness(1)
    # need to rotate the image to have the heart the right way up
    unicornhathd.rotation(0)

    a_list = []
    threading.Thread(target=input_thread, args=(a_list, )).start()

    while not a_list:
        #  go through the range 1-10 backwards, then back up
        #  the 2* makes a ba-BUMP for the heart
        # for i in 2 * (range(10, 0, -1) + range(1, 10)):
        concatenated = chain(range(10, 0, -1), range(1, 10))
        for i in concatenated:
            if a_list:
                break
            for y in range(16):
                if a_list:
                    break
                for x in range(16):
                    if a_list:
                        break
                    h = 0.0  # red
                    s = 1.0  # saturation at the top of the red scale
                    v = heart[x, y] / float(i)  # brightness depends on range
                    r, g, b = colorsys.hsv_to_rgb(h, s,
                                                  v)  # convert hsv back to RGB
                    red = int(r * 255.0)  # makes 0-1 range > 0-255 range
                    green = int(g * 255.0)
                    blue = int(b * 255.0)
                    unicornhathd.set_pixel(x, y, red, green,
                                           blue)  # sets pixels on the hat
            unicornhathd.show()  # show the pixels
            time.sleep(0.005)  # tiny gap, sets frames to a smooth 200/sec
        time.sleep(0.33)  # waiting time between heartbeats

    unicornhathd.off()
Example #31
0
    def move(self):
        self.turn_off()
        self.x, self.dx = self.move_one_axis(self.x, self.dx)
        self.y, self.dy = self.move_one_axis(self.y, self.dy)
        self.turn_on()

    def move_one_axis(self, x_or_y, dx_or_dy):
        x_or_y += dx_or_dy
        if x_or_y < 0 or x_or_y > 15:
            dx_or_dy = dx_or_dy * -1
            x_or_y += dx_or_dy
        return x_or_y, dx_or_dy

print("Press <CTRL+C> to exit...")

unicornhathd.off()

# Bounce backwards and forwards along each edge:
p1 = Point(0, 0, 0, 1)
p2 = Point(0, 15, 1, 0)
p3 = Point(15, 0, -1, 0)
p4 = Point(15, 15, 0, -1)
p1.turn_on()
p2.turn_on()
p3.turn_on()
p4.turn_on()
unicornhathd.show()

try:
    while True:
        p1.move()