Want to run more than one program on your Pico? It can be done

I am the proud owner of a Tufty 2040. It’s main.py file scans for py files and then lists them and lets you pick which one to run. That main.py file can be run on a Pico, Pico Lipo or Tiny etc. All it needs is modification for the display your using.
I did this on my Pico Display Pack. X is the up button and Y is the down button.

from picographics import PicoGraphics, DISPLAY_PICO_DISPLAY, PEN_RGB332
from os import listdir
import time
import gc
from pimoroni import Button
from pimoroni import RGBLED

display = PicoGraphics(display=DISPLAY_PICO_DISPLAY, pen_type=PEN_RGB332, rotate=0)
display.set_font("bitmap8") 

def hsv_to_rgb(h, s, v):
    if s == 0.0:
        return v, v, v
    i = int(h * 6.0)
    f = (h * 6.0) - i
    p = v * (1.0 - s)
    q = v * (1.0 - s * f)
    t = v * (1.0 - s * (1.0 - f))
    v = int(v * 255)
    t = int(t * 255)
    p = int(p * 255)
    q = int(q * 255)
    i = i % 6
    if i == 0:
        return v, t, p
    if i == 1:
        return q, v, p
    if i == 2:
        return p, v, t
    if i == 3:
        return p, q, v
    if i == 4:
        return t, p, v
    if i == 5:
        return v, p, q


def get_applications():
    # fetch a list of the applications that are stored in the filesystem
    applications = []
    for file in listdir():
        if file.endswith(".py") and file != "main.py":
            # convert the filename from "something_or_other.py" to "Something Or Other"
            # via weird incantations and a sprinkling of voodoo
            title = " ".join([v[:1].upper() + v[1:] for v in file[:-3].split("_")])

            applications.append(
                {
                    "file": file,
                    "title": title
                }
            )

    # sort the application list alphabetically by title and return the list
    return sorted(applications, key=lambda x: x["title"])


def launch_application(application):
    for k in locals().keys():
        if k not in ("gc", "file", "badger_os"):
            del locals()[k]

    gc.collect()

    __import__(application["file"])


applications = get_applications()

button_a = Button(12)
button_b = Button(13)
button_x = Button(14)
button_y = Button(15)

led = RGBLED(6, 7, 8)
led.set_rgb(0, 0, 0)
display.set_backlight(1.0)

WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
RED = display.create_pen(200, 0, 0)


def text(text, x, y, pen, s):
    display.set_pen(pen)
    display.text(text, x, y, -1, s)


selected_item = 2
scroll_position = 2
target_scroll_position = 2

selected_pen = display.create_pen(255, 255, 255)
unselected_pen = display.create_pen(80, 80, 100)
background_pen = display.create_pen(50, 50, 70)
shadow_pen = display.create_pen(0, 0, 0)

while True:
    t = time.ticks_ms() / 1000.0

    if button_x.read():
        target_scroll_position -= 1
        target_scroll_position = target_scroll_position if target_scroll_position >= 0 else len(applications) - 1

    if button_y.read():
        target_scroll_position += 1
        target_scroll_position = target_scroll_position if target_scroll_position < len(applications) else 0

    if button_a.read():
        launch_application(applications[selected_item])

    display.set_pen(background_pen)
    display.clear()

    scroll_position += (target_scroll_position - scroll_position) / 5

    grid_size = 40
    for y in range(0, 240 / grid_size):
        for x in range(0, 240 / grid_size):
            h = x + y + int(t * 5)
            h = h / 50.0
            r, g, b = hsv_to_rgb(h, .5, 1)

            display.set_pen(display.create_pen(r, g, b))
            display.rectangle(x * grid_size, y * grid_size, grid_size, grid_size)

    # work out which item is selected (closest to the current scroll position)
    selected_item = round(target_scroll_position)

    start = time.ticks_ms()

    for list_index, application in enumerate(applications):
        distance = list_index - scroll_position

        text_size = 3 if selected_item == list_index else 3

        # center text horixontally
        title_width = display.measure_text(application["title"], text_size)
        text_x = int(120 - title_width / 2)

        row_height = text_size * 5 + 20

        # center list items vertically
        text_y = int(120 + distance * row_height - (row_height / 2))

        # draw the text, selected item brightest and with shadow
        if selected_item == list_index:
            text(application["title"], text_x + 1, text_y + 1, shadow_pen, text_size)

        text_pen = selected_pen if selected_item == list_index else unselected_pen
        text(application["title"], text_x, text_y, text_pen, text_size)

    start = time.ticks_ms()

    display.update()

And this on my Display pack V2

import time
import gc

from picographics import PicoGraphics, DISPLAY_PICO_DISPLAY_2, PEN_RGB332
from os import listdir
from pimoroni import Button
from pimoroni import RGBLED

display = PicoGraphics(display=DISPLAY_PICO_DISPLAY_2, pen_type=PEN_RGB332, rotate=0)
display.set_backlight(1.0)
display.set_font("bitmap8") 

def hsv_to_rgb(h, s, v):
    if s == 0.0:
        return v, v, v
    i = int(h * 6.0)
    f = (h * 6.0) - i
    p = v * (1.0 - s)
    q = v * (1.0 - s * f)
    t = v * (1.0 - s * (1.0 - f))
    v = int(v * 255)
    t = int(t * 255)
    p = int(p * 255)
    q = int(q * 255)
    i = i % 6
    if i == 0:
        return v, t, p
    if i == 1:
        return q, v, p
    if i == 2:
        return p, v, t
    if i == 3:
        return p, q, v
    if i == 4:
        return t, p, v
    if i == 5:
        return v, p, q

def get_applications():
    # fetch a list of the applications that are stored in the filesystem
    applications = []
    for file in listdir():
        if file.endswith(".py") and file != "main.py":
            # convert the filename from "something_or_other.py" to "Something Or Other"
            # via weird incantations and a sprinkling of voodoo
            title = " ".join([v[:1].upper() + v[1:] for v in file[:-3].split("_")])

            applications.append(
                {
                    "file": file,
                    "title": title
                }
            )

    # sort the application list alphabetically by title and return the list
    return sorted(applications, key=lambda x: x["title"])

def launch_application(application):
    for k in locals().keys():
        if k not in ("gc", "file", "badger_os"):
            del locals()[k]

    gc.collect()

    __import__(application["file"])

applications = get_applications()

button_a = Button(12)
button_b = Button(13)
button_x = Button(14)
button_y = Button(15)

led = RGBLED(6, 7, 8)


WHITE = display.create_pen(255, 255, 255)
BLACK = display.create_pen(0, 0, 0)
RED = display.create_pen(200, 0, 0)


def text(text, x, y, pen, s):
    display.set_pen(pen)
    display.text(text, x, y, -1, s)


selected_item = 2
scroll_position = 2
target_scroll_position = 2

selected_pen = display.create_pen(255, 255, 255)
unselected_pen = display.create_pen(80, 80, 100)
background_pen = display.create_pen(50, 50, 70)
shadow_pen = display.create_pen(0, 0, 0)

while True:
    t = time.ticks_ms() / 1000.0

    if button_x.read():
        target_scroll_position -= 1
        target_scroll_position = target_scroll_position if target_scroll_position >= 0 else len(applications) - 1

    if button_y.read():
        target_scroll_position += 1
        target_scroll_position = target_scroll_position if target_scroll_position < len(applications) else 0

    if button_a.read():
        launch_application(applications[selected_item])

    display.set_pen(background_pen)
    display.clear()

    scroll_position += (target_scroll_position - scroll_position) / 5

    grid_size = 40
    for y in range(0, 240 / grid_size):
        for x in range(0, 320 / grid_size):
            h = x + y + int(t * 5)
            h = h / 50.0
            r, g, b = hsv_to_rgb(h, .5, 1)

            display.set_pen(display.create_pen(r, g, b))
            display.rectangle(x * grid_size, y * grid_size, grid_size, grid_size)

    # work out which item is selected (closest to the current scroll position)
    selected_item = round(target_scroll_position)

    start = time.ticks_ms()

    for list_index, application in enumerate(applications):
        distance = list_index - scroll_position

        text_size = 4 if selected_item == list_index else 3

        # center text horixontally
        title_width = display.measure_text(application["title"], text_size)
        text_x = int(160 - title_width / 2)

        row_height = text_size * 5 + 20

        # center list items vertically
        text_y = int(120 + distance * row_height - (row_height / 2))

        # draw the text, selected item brightest and with shadow
        if selected_item == list_index:
            text(application["title"], text_x + 1, text_y + 1, shadow_pen, text_size)

        text_pen = selected_pen if selected_item == list_index else unselected_pen
        text(application["title"], text_x, text_y, text_pen, text_size)

    start = time.ticks_ms()
    led.set_rgb(r, g, b)
    display.update()