{"id":18860268,"url":"https://github.com/thajiyev/zebra-beautify","last_synced_at":"2026-05-01T00:31:45.492Z","repository":{"id":161871241,"uuid":"524749588","full_name":"THajiyev/Zebra-Beautify","owner":"THajiyev","description":"The best way to format ZEBRA MotionWorks data from The Blue Alliance","archived":false,"fork":false,"pushed_at":"2023-03-23T05:29:22.000Z","size":7,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-30T08:50:31.526Z","etag":null,"topics":["frc","frc-scouting","scouting","tba","tba-api","zebra-motionworks"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/THajiyev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-14T18:29:43.000Z","updated_at":"2024-04-04T17:35:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"329cb0ac-1b24-4565-b2ba-d706b693647c","html_url":"https://github.com/THajiyev/Zebra-Beautify","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/THajiyev/Zebra-Beautify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/THajiyev%2FZebra-Beautify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/THajiyev%2FZebra-Beautify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/THajiyev%2FZebra-Beautify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/THajiyev%2FZebra-Beautify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/THajiyev","download_url":"https://codeload.github.com/THajiyev/Zebra-Beautify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/THajiyev%2FZebra-Beautify/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32481553,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["frc","frc-scouting","scouting","tba","tba-api","zebra-motionworks"],"created_at":"2024-11-08T04:23:16.587Z","updated_at":"2026-05-01T00:31:45.461Z","avatar_url":"https://github.com/THajiyev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zebra-Beautify\n\nThe Blue Alliance API is one of the most helpful APIs for scouting. However, its Zebra MotionWorks data is pretty hard to use. Apart from being in a format that doesn't meet the needs of most applications for scouting, the lists also contain null values that can cause errors in the code. So to use Zebra MotionWorks data in my code, I created a class that solved these two issues. Using it to retrieve data from TBA will make scouting a little easier and save a lot of time.\n\n## Setup\n\nFirst, install Requests by typing the following command in your command prompt.\n\n```\npip install requests\n```\n\nThen in a Python file separate from zebra.py, import Zebra.\n\n```python\nfrom zebra import Zebra\n```\n\nTBA API requires an authentication key, so you need to pass it in as a parameter when instantiating an object of class Zebra.\n\n```python\n  data_extractor = Zebra(\"your_auth_key\")\n```\n\n## Getting Zebra MotionWorks Data for a Match\n\nThen call the **get_match_zebra()** function and pass the match key as a parameter.\n\n```python\ndata = data_extractor.get_match_zebra(\"match_key\")\n```\n\nSome past Zebra MotionWorks data on TBA is missing a lot of coordinates from the start of the match. By default, the algorithm ignores any data where the first 10 coordinate pairs are missing(the first pair on 1.0 second or later). But you can change the maximum number of coordinate pairs missing for data to still be accepted.\n\nFor example, let's say you can tolerate the first 50 coordinate pairs missing.\n\n```python\ndata = data_extractor.get_match_zebra(\"match_key\", max_data_loss=50)\n```\n\nThe output will have the team's data associated with the team's key.\n\n```mermaid\ngraph TB\n\nA[Team Key] --\u003e B[alliance]\n\nA[Team Key] --\u003e C[starting_time]\n\nA[Team Key] --\u003e D[x]\n\nA[Team Key] --\u003e E[y]\n\n```\n\nThe \u003cem\u003ealliance\u003c/em\u003e will be set to the color of the alliance. It helps map the coordinates.\n\n\u003cem\u003estarting_time\u003c/em\u003e is the second of the match at which the first pair of coordinates was collected. Since coordinates are reported every 0.1 seconds, you can keep track of the second of the match by incrementing the time by 0.1 for each point.\n\n\u003cem\u003ex\u003c/em\u003e is the list of all x-coordinates.\n\n\u003cem\u003ey\u003c/em\u003e is the list of all y-coordinates.\n\n```\nNote: The max_data_loss will also be equal to the latest potential starting_time(converted to deciseconds) in your data set.\n```\n\nIf this data gets put in a JSON file, it will look like this:\n\n```js\n{\n\t\"frc0000\": {\n\t\t\"alliance\": \"\",\n\t\t\"starting_time\": 0,\n\t\t\"x\": [],\n\t\t\"y\": []\n\t}\n}\n```\n\n## Getting data for an event\n\nTo get the data for an event, you will need to call the function **get_event_zebra()** and pass the event key as a parameter.\n\n```python\ndata = data_extractor.get_event_zebra(\"your_event\")\n```\n\nSome past Zebra MotionWorks data on TBA is missing a lot of coordinates from the start of the match. By default, the algorithm ignores any data where the first 10 coordinate pairs are missing(the first pair on 1.0 second or later). But you can change the maximum number of coordinate pairs missing for data to still be accepted.\n\nFor example, let's say you can tolerate the first 50 coordinate pairs missing.\n\n```python\ndata = data_extractor.get_event_zebra(\"your_event\", max_data_loss=50)\n```\n\n## Formatting for event data\n\nThe generated dictionary will have a key for every team that data is available for. Then the data for that team will be categorized by the competition level.\n\n```mermaid\n\ngraph TB\n\nA[Team Key] --\u003e B[f]\n\nA[Team Key] --\u003e C[qf]\n\nA[Team Key] --\u003e D[qm]\n\nA[Team Key] --\u003e E[sf]\n\n```\n\n```\nNote: Competition levels are sorted alphabetically.\n```\n\nThen for each competition level, we will have data categorized by the match number.\n\n```mermaid\n\ngraph TB\n\nA[f] --\u003e B[1]\n\nA[f] --\u003e C[2]\n\nA[f] --\u003e D[3]\n\n```\n\nThen for each match, these metrics will be provided.\n\n```mermaid\n\ngraph TB\n\nA[1] --\u003e B[alliance]\n\nA[1] --\u003e C[starting_time]\n\nA[1] --\u003e D[x]\n\nA[1] --\u003e E[y] \n\n```\n\nThe \u003cem\u003ealliance\u003c/em\u003e will be set to the color of the alliance. It helps map the coordinates.\n\n\u003cem\u003estarting_time\u003c/em\u003e is the second of the match at which the first pair of coordinates was collected. Since coordinates are reported every 0.1 seconds, you can keep track of the second of the match by incrementing the time by 0.1 for each point.\n\n\u003cem\u003ex\u003c/em\u003e is the list of all x-coordinates.\n\n\u003cem\u003ey\u003c/em\u003e is the list of all y-coordinates.\n\n```\nNote: The max_data_loss will also be equal to the latest potential starting_time(converted to deciseconds) in your data set.\n```\n\nIf that data is dumped into a JSON file, the format will look like this:\n\n```js\n{\n\t\"frc0000\": {\n\t\t\"f\": {\n\t\t\t\"1\": {\n\t\t\t\t\"alliance\": \"\",\n\t\t\t\t\"starting_time\": 0,\n\t\t\t\t\"x\": [],\n\t\t\t\t\"y\": []\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\nSummary Graph:\n\n```mermaid\n\ngraph TD\n\nA[Team Key] --\u003e B[f]\n\nA[Team Key] --\u003e C[qf]\n\nA[Team Key] --\u003e D[qm]\n\nA[Team Key] --\u003e E[sf]\n\nB[f] --\u003e F[1]\n\nB[f] --\u003e G[2]\n\nB[f] --\u003e H[3]\n\nF[1] --\u003e I[alliance]\n\nF[1] --\u003e J[starting_time]\n\nF[1] --\u003e K[x]\n\nF[1] --\u003e L[y]\n\n```\n\n## License\n\nMIT\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthajiyev%2Fzebra-beautify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthajiyev%2Fzebra-beautify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthajiyev%2Fzebra-beautify/lists"}