AndroidEnv is a Python library that exposes an Android device as a Reinforcement Learning (RL) environment.

Overview

AndroidEnv - The Android Learning Environment

AndroidEnv is a Python library that exposes an Android device as a Reinforcement Learning (RL) environment. The library provides a flexible platform for defining custom tasks on top of the Android Operating System, including any Android application. Agents interact with the device through a universal action interface - the touchscreen - by sending localized touch and lift events to the system. The library processes these events and returns pixel observations and rewards as provided by specific task definitions. For example, rewards might be given for events such as successfully scrolling down a page, sending an email, or achieving some score in a game, depending on the research purpose and how the user configures the task.

Index

Environment features

There are a number of aspects that make AndroidEnv a challenging yet suitable environment for Reinforcement Learning research:

  • Allowing agents to interact with a system used daily by billions of users around the world, AndroidEnv offers a platform for RL agents to navigate, learn tasks and have direct impact in real-world contexts. The environment wraps a simulated Android device, which runs independently from the environment, completely unaltered, and works in exactly the same way as the devices that humans use, exposing exactly the same features and services.

  • The platform offers a virtually infinite range of possible tasks, all sharing a common action interface. The library facilitates the design of Reinforcement Learning tasks for any existing or custom built Android application. For example, it exposes the broad world of Android games, ranging from card games, puzzle games, time reactive games, all requiring a diverse set of action combinations and interaction types.

  • The environment runs on top of a real-time simulation of an Android device. In other words, the environment dynamics does not wait for the agent to deliberate, and the speed of the simulation cannot be increased.

  • The observation is a collection of RGB values corresponding to the displayed pixels on the screen. The exact screen resolution depends on the simulated device, but in general it will be considered relatively large in an RL context. However, users have the option of downsampling each observation.

  • The learning environment has an interesting, complex action space unique to the touchscreen interface of Android.

    • The raw, hybrid action space consists of a continuous tuple signifying the action location, and a discrete signal determining whether the agent wants to touch the screen or lift its virtual finger.
    • Raw actions are highly composable: the Android UI and most applications were designed so that they could be intuitively navigated via common touchscreen gestures such as tapping, scrolling, swiping, pinching, drag & drop etc. This is still the case in AndroidEnv: to trigger meaningful changes in the environment, the agent often has to perform carefully timed and positioned sequences of raw actions. For example, in order to navigate to the next image in a photo gallery, the agent would have to perform a swipe, touching the screen multiple times, gradually shifting the actions' positions to the right. Thus, in most contexts raw actions do not trigger changes in the state of the environment unless correctly chained together to make up a human gesture.
    • The action interface is closely related to the observation space, as meaningful touch and lift events are often either co-localized or strongly correlated to the location or movement of salient objects in the observation. For example, the position of a button on the screen aligns with the location of the actions that trigger the button press.
    • The library provides tools for flexibly altering the action interface if needed for particular studies, such as discretization or hard-coding gesture skills. Still, we believe that the real challenge remains in devising agents that are capable of dealing with a large suite of diverse tasks, through acting and learning in the complex unifying action interface.

Getting started

Installation

The easiest way to get AndroidEnv is from the latest AndroidEnv codebase from git's main branch:

$ git clone https://github.com/deepmind/android_env/
$ cd android_env
$ python3 setup.py install

Create a simulator

Before running the environment, you will need access to an emulated Android device. For instructions on creating a virtual Android device, see the Emulator guide.

Define a task

Then, you will want to define what the agent's task is. At this point, the agent will be able to communicate with the emulated device, but it will not yet have an objective, or access to signals such as rewards or RL episode ends. Learn how to define an RL task of your own, or use one of the existing task definitions for training.

Load and run

To find out how to run and train agents on AndroidEnv, see these detailed instructions. Here you can also find example scripts demonstrating how to run a random agent, an acme agent, or a human agent on AndroidEnv.

About

This library is developed and maintained by DeepMind.
You can find the technical report on Arxiv.

If you use AndroidEnv in your research, you can cite the paper using the following BibTeX:

@article{ToyamaEtAl2021AndroidEnv,
  title     = {{AndroidEnv}: A Reinforcement Learning Platform for Android},
  author    = {Daniel Kenji Toyama and Philippe Hamel and Anita Gergely and
               Gheorghe Comanici and Amelia Glaese and Zafarali Ahmed and Tyler
               Jackson and Shibl Mourad and Doina Precup},
  year      = {2021},
  eprint    = {2105.13231},
  archivePrefix = {arXiv},
  primaryClass = {cs.LG},
  volume    = {abs/2105.13231},
  url       = {http://arxiv.org/abs/2105.13231},
}

Disclaimer: This is not an official Google product.

Comments
  • Crash on

    Crash on "run_acme_agent.py"

    Hello,

    I did install all dependencies for acme and i am running it on python3.8 (linux) using the pong textproto and pong apk

    python3 run_acme_agent.py --avd_name='Pixel_XL_API_30' --android_avd_home='/home/username/.android/avd' --android_sdk_root=/home/username/Android/Sdk/ --emulator_path=/home/username/Android/Sdk/emulator/emulator --adb_path=/home/username/Android/Sdk/platform-tools/adb --num_episodes=100 --task_path=/home/username/Dev/android_env/examples/pong_default.textproto

    I am getting the following error

    I0622 02:01:27.057457 139624755865408 environment.py:37] Action spec: {'action_type': DiscreteArray(shape=(), dtype=int32, name=action_type, minimum=0, maximum=2, num_values=3), 'touch_position': BoundedArray(shape=(2,), dtype=dtype('float32'), name='touch_position', minimum=[0. 0.], maximum=[1. 1.])} I0622 02:01:27.058849 139624755865408 environment.py:38] Observation spec: {'pixels': Array(shape=(2560, 1440, 3), dtype=dtype('uint8'), name='pixels'), 'timedelta': Array(shape=(), dtype=dtype('int64'), name='timedelta'), 'orientation': Array(shape=(4,), dtype=dtype('uint8'), name='orientation')} I0622 02:01:27.059457 139624755865408 environment.py:39] Task extras spec: {'ball': Array(shape=(4,), dtype=dtype('int32'), name='ball'), 'computer': Array(shape=(4,), dtype=dtype('int32'), name='computer'), 'human': Array(shape=(4,), dtype=dtype('int32'), name='human'), 'collision': Array(shape=(1,), dtype=dtype('int32'), name='collision'), 'state': Array(shape=(1,), dtype=dtype('int32'), name='state')} Traceback (most recent call last): File "run_acme_agent.py", line 88, in <module> app.run(main) File "/home/username/.local/lib/python3.8/site-packages/absl/app.py", line 312, in run _run_main(main, args) File "/home/username/.local/lib/python3.8/site-packages/absl/app.py", line 258, in _run_main sys.exit(main(argv)) File "run_acme_agent.py", line 73, in main num_actions=env_spec.actions.num_values), AttributeError: 'dict' object has no attribute 'num_values' I0622 02:01:27.711886 139624755865408 environment.py:127] Cleaning up AndroidEnv...

    Thank you for any insights

    good first issue 
    opened by ouya99 13
  • Emulator crashes on load()

    Emulator crashes on load()

    After following the instructions for set up, I run the android emulator along with the following code:

    env = android_env.load(
        avd_name='pixel2_30',
        android_avd_home='/path/.android/avd',
        android_sdk_root='/path/Android/Sdk',
        emulator_path='/path/Android/Sdk/emulator/emulator',
        adb_path='/path/Android/Sdk/platform-tools/adb',
        task_path='/path/android_env/tasks/accessibility_forwarder_clock_set_timer.textproto',
    )
    

    And the emulator crashes:

    Traceback (most recent call last):
      File "/path/android_env/android_env/components/emulator_launcher.py", line 137, in launch
        self._emulator.expect('emulator: INFO: boot completed', timeout=wait_time)
      File "/path/anaconda3/lib/python3.6/site-packages/pexpect/spawnbase.py", line 344, in expect
        timeout, searchwindowsize, async_)
      File "/path/anaconda3/lib/python3.6/site-packages/pexpect/spawnbase.py", line 372, in expect_list
        return exp.expect_loop(timeout)
      File "/path/anaconda3/lib/python3.6/site-packages/pexpect/expect.py", line 179, in expect_loop
        return self.eof(e)
      File "/path/anaconda3/lib/python3.6/site-packages/pexpect/expect.py", line 122, in eof
        raise exc
    pexpect.exceptions.EOF: End Of File (EOF).
    <pexpect.popen_spawn.PopenSpawn object at 0x7f5a4e4416a0>
    searcher: searcher_re:
        0: re.compile(b'emulator: INFO: boot completed')
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "test.py", line 11, in <module>
        env = android_env.load(
      File "/path/android_env/android_env/loader.py", line 73, in load
        coordinator = coordinator_lib.Coordinator(simulator, task_manager)
      File "/path/android_env/android_env/components/coordinator.py", line 88, in __init__
        self._restart_simulator()
      File "/path/android_env/android_env/components/coordinator.py", line 181, in _restart_simulator
        self._simulator.launch()
      File "/path/android_env/android_env/components/base_simulator.py", line 135, in launch
        self._launch_impl()
      File "/path/android_env/android_env/components/emulator_simulator.py", line 114, in _launch_impl
        self.restart()
      File "/path/android_env/android_env/components/base_simulator.py", line 144, in restart
        self._restart_impl()
      File "/path/android_env/android_env/components/emulator_simulator.py", line 102, in _restart_impl
        self._launcher.restart()
      File "/path/android_env/android_env/components/emulator_launcher.py", line 151, in restart
        self.launch()
      File "/path/android_env/android_env/components/emulator_launcher.py", line 143, in launch
        raise errors.SimulatorCrashError('The emulator has crashed: %r' % e)
    android_env.components.errors.SimulatorCrashError: The emulator has crashed: EOF("End Of File (EOF).\n<pexpect.popen_spawn.PopenSpawn object at 0x7f5a4e4416a0>\nsearcher: searcher_re:\n    0: re.compile(b'emulator: INFO: boot completed')",)
    
    

    I'm not sure why this happens, any idea? Thanks!

    opened by AdamIshay 7
  • AndroidEnv does not work in WSL

    AndroidEnv does not work in WSL

    I've setup android studio on windows and am trying to load the environment from WSL. I have got an unexpected keyword argument 'use_poll' error while trying to load the environment. Any ideas on how I can fix this?

    Full error:

    >>> import android_env
    >>> env = android_env.load(avd_name='Pixel_2_API_30', android_avd_home='/mnt/c/Users/Surya Penmetsa/.android/avd/Pixel_2_API_30.avd', android_sdk_root='/mnt/c/Users/Surya Penmetsa/AppData/Local/Android/Sdk', emulator_path='/mnt/c/Users/Surya Penmetsa/AppData/Local/Android/Sdk/emulator/emulator.exe', adb_path='/mnt/c/Users/Surya Penmetsa/AppData/Local/Android/Sdk/platform-tools/adb.exe', task_path='downloads/classic_2048.textproto')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/loader.py", line 73, in load
        coordinator = coordinator_lib.Coordinator(simulator, task_manager)
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/coordinator.py", line 88, in __init__
        self._restart_simulator()
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/coordinator.py", line 181, in _restart_simulator
        self._simulator.launch()
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/base_simulator.py", line 136, in launch
        self._post_launch_setup()
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/emulator_simulator.py", line 117, in _post_launch_setup
        super()._post_launch_setup()
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/base_simulator.py", line 151, in _post_launch_setup
        self._adb_controller.get_screen_dimensions())
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 459, in get_screen_dimensions
        self._wait_for_device(timeout=timeout)
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 234, in _wait_for_device
        ready = self._check_device_is_ready(timeout=timeout)
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 247, in _check_device_is_ready
        ['shell', 'service', 'check', service], timeout=timeout)
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 116, in _execute_command
        adb_output = self._execute_shell_command(args[1:], timeout=timeout)
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 149, in _execute_shell_command
        self._init_shell(timeout=timeout)
      File "/home/surya/anaconda3/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 191, in _init_shell
        self._adb_shell = pexpect.spawn(command, use_poll=True, timeout=timeout)
    TypeError: __init__() got an unexpected keyword argument 'use_poll'
    
    opened by psurya1994 5
  • Acme example for AndroidEnv requires `reverb` (Linux only)

    Acme example for AndroidEnv requires `reverb` (Linux only)

    The Acme run_acme_agent.py example appears to require /deepmind/reverb but that package - can only run on Linux systems at the moment:

    ⚠️ Reverb currently only supports Linux based OSes.

    (from https://github.com/deepmind/reverb)

    Core Acme installation:

    pip install dm-acme
    pip install dm-acme[reverb]
    

    (https://github.com/deepmind/acme)

    opened by 8bitmp3 5
  • AndroidEnv quits because of an unexpected keyword argument 'use_poll'

    AndroidEnv quits because of an unexpected keyword argument 'use_poll'

    I tried running run_random_agent.py and got a crash right after the virtual device booted. What might be the problem? Does AndroidEnv need a newer version of Python than 3.6?

    I0908 16:13:04.342051 140434626111232 coordinator.py:175] Simulator launch attempt 1 of 3
    I0908 16:13:04.342184 140434626111232 emulator_launcher.py:87] Booting the emulator [/home/sagar/Android/Sdk/emulator/emulator]
    I0908 16:13:04.342311 140434626111232 emulator_launcher.py:107] extra_env_vars: {'ANDROID_HOME': '', 'ANDROID_SDK_ROOT': '/home/sagar/Android/Sdk', 'ANDROID_AVD_HOME': '/home/sagar/.android/avd', 'ANDROID_EMULATOR_KVM_DEVICE': '/dev/kvm', 'ANDROID_ADB_SERVER_PORT': '5037', 'LD_LIBRARY_PATH': '/home/sagar/Android/Sdk/emulator/lib64/x11/:/home/sagar/Android/Sdk/emulator/lib64/qt/lib/:/home/sagar/Android/Sdk/emulator/lib64/gles_swiftshader/:/home/sagar/Android/Sdk/emulator/lib64/', 'QT_DEBUG_PLUGINS': '1', 'QT_XKB_CONFIG_ROOT': '/home/sagar/Android/Sdk/emulator/qt_config/'}
    I0908 16:13:04.342589 140434626111232 emulator_launcher.py:123] Emulator launch command: /home/sagar/Android/Sdk/emulator/emulator -no-snapshot -gpu swiftshader_indirect -no-audio -verbose -avd pixel4 -ports 19811,15342
    I0908 16:13:04.345738 140434626111232 emulator_launcher.py:136] Waiting for boot for 300.0 seconds...
    I0908 16:13:33.728062 140434626111232 emulator_launcher.py:138] Emulator log matched: b'emulator: INFO: boot completed'
    I0908 16:13:33.728239 140434626111232 emulator_launcher.py:146] Done booting the emulator (in 29.385461 seconds).
    I0908 16:13:33.728819 140434626111232 emulator_console.py:264] Connecting to Emulator console on port 19811...
    I0908 16:13:33.730707 140434626111232 emulator_console.py:279] Done connecting to Emulator console on port 19811.
    I0908 16:13:33.730814 140434626111232 emulator_console.py:282] Authenticating to console.
    I0908 16:13:33.784988 140434626111232 adb_controller.py:458] Fetching screen dimensions...
    I0908 16:13:33.785164 140434626111232 adb_controller.py:184] Initialising ADB shell with command: /home/sagar/Android/Sdk/platform-tools/adb -P 5037 -s emulator-15341 shell
    I0908 16:13:33.785252 140434626111232 adb_controller.py:190] Spawning ADB shell...
    Traceback (most recent call last):
      File "run_random_agent.py", line 82, in <module>
        app.run(main)
      File "/home/sagar/.local/lib/python3.6/site-packages/absl/app.py", line 303, in run
        _run_main(main, args)
      File "/home/sagar/.local/lib/python3.6/site-packages/absl/app.py", line 251, in _run_main
        sys.exit(main(argv))
      File "run_random_agent.py", line 54, in main
        run_headless=False) as env:
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/loader.py", line 73, in load
        coordinator = coordinator_lib.Coordinator(simulator, task_manager)
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/coordinator.py", line 88, in __init__
        self._restart_simulator()
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/coordinator.py", line 181, in _restart_simulator
        self._simulator.launch()
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/base_simulator.py", line 136, in launch
        self._post_launch_setup()
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/emulator_simulator.py", line 117, in _post_launch_setup
        super()._post_launch_setup()
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/base_simulator.py", line 151, in _post_launch_setup
        self._adb_controller.get_screen_dimensions())
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 459, in get_screen_dimensions
        self._wait_for_device(timeout=timeout)
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 234, in _wait_for_device
        ready = self._check_device_is_ready(timeout=timeout)
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 247, in _check_device_is_ready
        ['shell', 'service', 'check', service], timeout=timeout)
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 116, in _execute_command
        adb_output = self._execute_shell_command(args[1:], timeout=timeout)
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 149, in _execute_shell_command
        self._init_shell(timeout=timeout)
      File "/home/sagar/.local/lib/python3.6/site-packages/android_env/components/adb_controller.py", line 191, in _init_shell
        self._adb_shell = pexpect.spawn(command, use_poll=True, timeout=timeout)
    TypeError: __init__() got an unexpected keyword argument 'use_poll'
    I0908 16:13:33.866050 140434626111232 emulator_launcher.py:156] Killing the emulator process...
    I0908 16:13:33.972082 140434626111232 emulator_launcher.py:161] Done killing the emulator process.
    
    bug wontfix 
    opened by s-gv 4
  • AndroidEnv Example Tasks doc: fix download UI for APK/textproto ZIP files in dark mode

    AndroidEnv Example Tasks doc: fix download UI for APK/textproto ZIP files in dark mode

    The download buttons for APK/textproto ZIP files are barely visible in GitHub web UI's dark mode, so they may be hard to find:

    image

    A simple solution could be just to have the word "Download" - it renders well in Markdown:

    image

    Hope this helps 👍

    opened by 8bitmp3 3
  • Incompatible with Python3.10

    Incompatible with Python3.10

    I tried to install android_env both from pip and source code but I get an error on install. Digging a little more I found out that the installed version of numpy (which is 1.19.5) is incompatible with Python3.10.

    For now I removed the version requirement from setup.py and the installation completed successfully.

    opened by thelicato 2
  • .textproto log_regexp syntax

    .textproto log_regexp syntax

    Hello. Thanks for your work.

    I want to clarify the usage of log_regexp in classic_2048.textproto file.

    score: "^[Ss]core: ([-+]?[0-9]*\\.?[0-9]*)$"
    

    However, in the console I see logs in a format: score: 4.0, which gives no match (but a string of score 4.\0 matches with regexp). Why do we need \\ in this regexp? Am I misunderstanding something?

    I want to parse logs from my own apk.

    opened by yefremenko 2
  • 1V1 environmnet

    1V1 environmnet

    Hi ,

    Thank you very much for giving such a nice tool. I just have one problem, will you offer some compatible 1v1 environments in the future? For example, in current Pong and droidfish chess, we can train an rl-agent against built-in bots. But you know, we need the help of selfplay to get a stronger rl-agent.
    Besides, will you also consider environments that need two ro more players to coorparate?
    Thanks.
    

    Regards, Shenghan

    opened by sheng-han-zhang 2
  • Running on Docker

    Running on Docker

    Hi,

    Thanks for the great work. I want to ask if it is possible to integrate it with Android docker image like this one. It would allow a much more cleaner setup.

    Thanks

    opened by NaxAlpha 2
  • Extras not always returned . ( in case of floodit_basic).

    Extras not always returned . ( in case of floodit_basic).

    I tried to print The extras using logging.info('**Extras: %r ', env.task_extras()) in thr run_human_agent.py and found out that sometimes , it does print the corrent extras whereas quite often it just prints an empty dictionary!. Could you please point out any possible reasons for it. Any help would be greatly appreciated. Regards

    opened by anshmn 1
Releases(v1.0.0)
Owner
DeepMind
DeepMind
Python interface to IEX and IEX cloud APIs

Python interface to IEX Cloud Referral Please subscribe to IEX Cloud using this referral code. Getting Started Install Install from pip pip install py

IEX Cloud 41 Dec 21, 2022
💡 Fully automatic light management based on conditions like motion, illuminance, humidity, and other clever features

Fully automatic light management based on motion as AppDaemon app. 🕓 multiple daytimes to define different scenes for morning, noon, ... 💡 supports

Ben 105 Dec 23, 2022
Parser for RISC OS Font control characters in Python

RISC OS Font control parsing in Python This repository contains a class (FontControlParser) for parsing font control codes from a byte squence, in Pyt

Charles Ferguson 1 Nov 02, 2021
Subscribe, listen and (in the future) download your favorite podcasts, quickly and easily.

Minimal Podcasts Player https://github.com/son-link/minimal-podcasts-player Subscribe, listen and (in the future) download your favorite podcasts, qui

Alfonso Saavedra 14 Nov 11, 2022
Calculator in command line using python programming language

Calculator in command line using python programming language University of the People Python fundamental Chapter 5 Conditionals and recursion The main

mark sikaundi 3 Dec 09, 2021
Python Excuse Generator

Excuse Generator Python Excuse Generator This project is an excuse generator that provides the user with an excuse as to why they weren't paying atten

Collin Sanders 5 Jul 07, 2022
An a simple sistem code in python

AMS OS An a simple code in python ⁕¿What is AMS OS? AMS OS is an a simple sistem code writed in python. This code helps you with the cotidian task, yo

1 Nov 10, 2021
A data driven app for bicycle hiring in London(UK)

bicycle_hiring_app_deployed A data driven app for bicycle hiring in London(UK). It predicts expected number of bicycle hire in London. It asks users t

Rajarshi Roy Raju 1 Dec 10, 2021
A Desktop application for the signalum python library

Signalum Desktop A Desktop application on the Signalum Python Library/CLI Tool. The Signalum Desktop application is an attempt to develop a single too

BISOHNS 35 Feb 15, 2021
An example project that shows how to check if a certain macro is active in a file.

PlatformIO Check Compiler Flags Example Description Demonstrates the usage of an extra script and a special compilter invocation to get the active mac

Maximilian Gerhardt 1 Oct 28, 2021
Placeholders is a single-unit storage solution for your Frontend.

Placeholder Placeholders is a single-unit file storage solution for your Frontend. Why Placeholder? Generally, when a website/service requests for fil

Tanmoy Sen Gupta 1 Nov 09, 2021
This an Anki add on that automatically converts Notion notes into Anki flash cards. Currently in development!

NotionFlash This is an Anki add on in development that will allow automatically convert your Notion study notes into Anki flash cards. The Anki deck c

Neeraj Patel 10 Oct 07, 2022
UUID_ApiGenerator - This an API that will return a key-value pair of randomly generated UUID

This an API that will return a key-value pair of randomly generated UUID. Key will be a timestamp and value will be UUID. While the

1 Jan 28, 2022
Something like Asteroids but not really, done in CircuitPython

CircuitPython Staroids Something like Asteroids, done in CircuitPython. Works with FunHouse, MacroPad, Pybadge, EdgeBadge, CLUE, and Pygamer. circuitp

Tod E. Kurt 14 May 31, 2022
NUM Alert - A work focus aid created for the Hack the Job hackathon

Contributors: Uladzislau Kaparykha, Amanda Hahn, Nicholas Waller Hackathon Team Name: N.U.M General Purpose: The general purpose of this program is to

Amanda Hahn 1 Jan 10, 2022
A fluid medium for storing, relating, and surfacing thoughts.

Conceptarium A fluid medium for storing, relating, and surfacing thoughts. Read more... Instructions The conceptarium takes up about 1GB RAM when runn

115 Dec 19, 2022
NYCU(NCTU)-差勤-助教

NCTU-TA-fill 填寫 差勤-助教時數 有沒有覺得在差勤系統填助教時數有點浪費生命? 今天有個懶鬼浪費好多時間幫大家寫了code 只要填好的必要的資料,就可以讓電腦自動幫你完成差勤助教的時數填寫喔! https://pt-attendance.nctu.edu.tw/verify/userL

14 Dec 21, 2021
Module to align code with thoughts of users and designers. Also magically handles navigation and permissions.

This readme will introduce you to Carteblanche and walk you through an example app, please refer to carteblanche-django-starter for the full example p

Eric Neuman 42 May 28, 2021
A simple package for interacting with the 9kw.eu anti-captcha service.

Welcome to captcha9kw’s documentation! captcha9kw is a smallish Python package for making use of the 9kw.eu services, including solving of interactive

2 Feb 26, 2022
一个Graia-Saya的插件仓库

一个Graia-Saya的插件仓库 这是一个存储基于 Graia-Saya 的插件的仓库 如果您有这类项目

ZAPHAKIEL 111 Oct 24, 2022