From ad4c12028a83bb2426ba5ba34dc8542c99dbc176 Mon Sep 17 00:00:00 2001 From: "Reese D." <61914473+fenreese@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:55:52 -0500 Subject: [PATCH] Create an automator for user sessions i used the serializable script thing woo --- README.md | 17 +++++++- SessionData/.gitignore | 1 + SessionData/.gitkeep | 0 SessionData/test.json | 7 --- create_session.py | 97 ++++++++++++++++++++++++++++++++++++++++++ vocab_items.json | 6 +++ 6 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 SessionData/.gitignore create mode 100644 SessionData/.gitkeep delete mode 100644 SessionData/test.json create mode 100644 create_session.py create mode 100644 vocab_items.json diff --git a/README.md b/README.md index fc57016..d3122e3 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,26 @@ Also see: the [character recognition API](https://github.com/vialab/JPHandwritin # Setup +## Sessions + +Sessions for each user are loaded from a .json file. These files can be created via a Python script in the root. Run + +```sh +python3 create_session.py -h +``` + +to see what it does. + +The resulting file is saved as `SessionData/[userID].json` and a folder named after the ID is created in `SessionLogs`. + +## Program + 1. Make sure you have Unity 2022.3.11f1 installed. 2. Clone this repository and the [character recognition API repository](https://github.com/vialab/JPHandwritingModel). (Make sure the API repo is checked out to the `fastapi` branch.) 3. Set up the API (there are instructions on its repo). 4. Open this repository in Unity. -5. Put on your VR headset and press Play. +5. Fill the user's ID in by clicking on the Game object and filling in the "User ID" field in the Inspector. +6. Put on your VR headset and press Play. # Credits See [CREDITS.md](CREDITS.md). \ No newline at end of file diff --git a/SessionData/.gitignore b/SessionData/.gitignore new file mode 100644 index 0000000..94a2dd1 --- /dev/null +++ b/SessionData/.gitignore @@ -0,0 +1 @@ +*.json \ No newline at end of file diff --git a/SessionData/.gitkeep b/SessionData/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/SessionData/test.json b/SessionData/test.json deleted file mode 100644 index f70a0aa..0000000 --- a/SessionData/test.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "UserID": "test", - "VocabItems": [ - {"Type": "Lunchbox", "Data": "{\"EnableTracing\": false}"}, - {"Type": "Textbook", "Data": "{\"EnableTracing\": true}"} - ] -} \ No newline at end of file diff --git a/create_session.py b/create_session.py new file mode 100644 index 0000000..c5ca5f4 --- /dev/null +++ b/create_session.py @@ -0,0 +1,97 @@ +import argparse +import json +import os +import pathlib +import random +from typing import Any + +# prompt user for User ID, number of items, and number of items with tracing on +# limitations: only built-in libraries + +MAX_ITEMS = 2 + +class VocabItem: + def __init__(self, name: str, tracing: bool) -> None: + self.Type = name + self.EnableTracing = tracing + + def to_json(self) -> dict[str, str]: + return { + "Type": self.Type, + "Data": json.dumps({"EnableTracing": self.EnableTracing}) + } + +def import_items() -> list[str]: + with open("vocab_items.json", "r") as file: + contents = json.load(file) + return contents["VocabItems"] + +def generate_items(num_items: int, num_tracing: int) -> list: + vocab = import_items() + + generated_vocab = [] + num_traced = 0 + + for i in range(num_items): + tracing = False + + if (num_traced < num_tracing): + tracing = bool(random.getrandbits(1)) + + if (tracing): + num_traced += 1 + + vocab_item = vocab.pop(random.randint(0, len(vocab) - 1)) + generated_vocab.append(VocabItem(vocab_item, tracing)) + + return generated_vocab + +def generate_json(items: list[VocabItem], id: str) -> dict[str, Any]: + return { + "UserID": id, + "VocabItems": [x.to_json() for x in items] + } + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description = "Automatically creates sessions for users for user studies.", + ) + + parser.add_argument( + "--id", + type = str, + required = True, + help = "The user ID to generate a session file for." + ) + + parser.add_argument( + "--items", + type = int, + default = MAX_ITEMS, + help = "The number of items to generate." + ) + + parser.add_argument( + "--traced-items", + type = int, + default = 0, + help = "The number of items to enable tracing for." + ) + + return parser.parse_args() + +def main(): + args = parse_args() + contents = generate_json(generate_items(args.items, args.traced_items), args.id) + + with open(os.path.join("SessionData", f"{args.id}.json"), "w") as file: + json_contents = json.dumps(contents) + file.write(json_contents) + + print(f"Session has been generated and saved in the SessionData folder as {args.id}.json") + + pathlib.Path(f"SessionLogs/{args.id}").mkdir(parents = True, exist_ok = True) + print(f"Created SessionLogs/{args.id} folder") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/vocab_items.json b/vocab_items.json new file mode 100644 index 0000000..019bc2a --- /dev/null +++ b/vocab_items.json @@ -0,0 +1,6 @@ +{ + "VocabItems": [ + "Lunchbox", + "Textbook" + ] +} \ No newline at end of file