{"id":16508625,"url":"https://github.com/osteele/classroom-tools","last_synced_at":"2025-10-28T03:31:30.256Z","repository":{"id":50040355,"uuid":"77299048","full_name":"osteele/classroom-tools","owner":"osteele","description":"Tools for collecting and analyzing assignments – mostly related to GitHub and Jupyter notebooks – plus a few other tasks.","archived":false,"fork":false,"pushed_at":"2021-06-05T17:51:08.000Z","size":141,"stargazers_count":5,"open_issues_count":5,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-06T17:13:46.732Z","etag":null,"topics":["classroom-tools","github-classroom","jupyter-notebook"],"latest_commit_sha":null,"homepage":"https://olin-computing.github.io/classroom-tools/","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/osteele.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}},"created_at":"2016-12-24T20:22:29.000Z","updated_at":"2022-02-03T16:10:04.000Z","dependencies_parsed_at":"2022-08-03T17:01:15.015Z","dependency_job_id":null,"html_url":"https://github.com/osteele/classroom-tools","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fclassroom-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fclassroom-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fclassroom-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osteele%2Fclassroom-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osteele","download_url":"https://codeload.github.com/osteele/classroom-tools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238590593,"owners_count":19497350,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["classroom-tools","github-classroom","jupyter-notebook"],"created_at":"2024-10-11T15:46:40.603Z","updated_at":"2025-10-28T03:31:30.251Z","avatar_url":"https://github.com/osteele.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Classroom Tools\n\nThis repository contains tools for collecting and processing projects and\nassignments, mostly related to GitHub, [GitHub\nClassroom](https://classroom.github.com), and [Jupyter\nnotebooks](http://jupyter.org).\n\nIt also contains a smattering of other class-related tools, specific to the Olin\nCollege IT infrastructure.\n\nReport issues [here](https://github.com/osteele/classroom-tools/issues).\n\n## Status\n\nThe scripts in this file are still under (occasional) active development, and\nare under-tested and under-documented.\n\n## Setup\n\n### 1. Download this repository\n\n```bash\n$ git clone https://github.com/olin-computing/classroom-tools.git\n```\n\n### 2. Install Python\n\nInstall Python 3.7 or greater. [Lesser versions of Python 3 will likely work, but are untested. Python 2.x is right out.]\n\nTesting whether Python 3.7 is installed:\n\n1. Execute `python3 --version`,\n2. Verify the output version:\n\n```bash\n$ python3 --version\nPython 3.7.5\n```\n\n### 3. Install Poetry and packages\n\n1. Install [Poetry](https://python-poetry.org)\n2. `poetry install`\n\n### 4. [Optional] Retrieve a GitHub personal API token\n\nSome of these scripts use GitHub's API.\n\nGitHub limits the rate at which a particular machine can make API calls. If you\nrepeatedly run these scripts on a repo with many forks, you may run into these\nlimits. (You may also run into them if you work on developing the scripts.)\n\nYou will also need a personal API token in order to access any private\nrepositories. You will need this for use with [GitHub\nClassroom](https://classroom.github.com).\n\nTo increase the limit, [create a personal GitHub API\ntoken](https://github.com/blog/1509-personal-api-tokens), and set the\n`GITHUB_API_TOKEN` environment variable to this value.\n\nFor example, my macOS and Ubuntu shells are set to **zsh**, so my startup files\ninclude `~/.zshenv`. My `~/.zshenv` includes this line (where `xxxxxxxx` is my\npersonal GitHub API token):\n\n    export GITHUB_API_TOKEN=xxxxxxxx\n\n## Usage\n\n### General Usage\n\nThe repository consists of a number of Python scripts in the `scripts`\ndirectory.\n\nInvoke a script with `--help` to see options that aren't listed below.\n\nThe scripts assume the following directory organization. These subdirectories\nare not committed to the repository.\n\n    ./\n    ├── build\n    │     Files that are created by script (as opposed to downloaded) are placed here.\n    ├── config – optional configuration files\n    │     student-nicknames.txt\n    └── downloads\n          Scripts look here for manually downloaded files. Scripts that download files also place them here.\n\n`REPO_NAME` is a GitHub repository full name, in the format\n_org_name_/_short_name_. For example, this repo is\n`olin-computing/classroom-tools`.\n\n### GitHub Tools\n\n#### Clone Forks\n\n`./scripts/clone-repo-forks REPO_NAME`\n\n`./scripts/clone-repo-forks --classroom REPO_NAME`\n\nClone the forks of a repo.\n\n`REPO_NAME` is in `org_name/repo_name` format.\n\nWith the `--classroom` option, the script clones the repos `org_name/repo_name-$login` in the `org_name` account.\nThis is the format of repos created by GitHub Classroom.\n\nI no longer use this script. [multiclone](https://github.com/osteele/multiclone) is an alternate golang implementation, that clones the repos in parallel.\n\n#### Download Forked Files\n\n`./scripts/download-repo-fork-files REPO_NAME`\n\n`./scripts/download-repo-fork-files --classroom REPO_NAME`\n\nDownload a repo's forks' modified files. (Files whose contents are different\nfrom the source repo.) This is suitable for collecting assignments, and quickly\ninspecting which files have changed.\n\nOnly files that are different from the version in the origin repository are\ndownloaded.\n\nWith the `--classroom` option, the script downloads repos\n`org_name/repo_name-$login` in the `org_name` account. This is the format of\nrepos created by GitHub Classroom.\n\nThis script also omits repos that belong to members of _org_name_.\n\n(Both of these are suitable for my purposes, but could easily be turned into\ncommand-line options.)\n\nThis script downloads files into the directory structure:\n\n    ./downloads/\n    └── ${github_organization}-${github_repo}/\n        └── ${student_github_id}/\n            └── files…\n\n#### Collect Fork File Modification Times\n\n`./scripts/github-fork-file-modtimes REPO_NAME`\n\nCreate a spreadsheet that contains the student names and file modification\ndates, for each file in a forked repository.\n\n#### Collate Downloaded Files\n\n`./scripts/collate-downloaded-files` (under development)\n\nCollect downloaded notebooks into a common directory.\n\nThis script expects a directory structure created by the\n`download-repo-fork-files` script. It creates:\n\n    ./downloads/\n    └── ${github_organization}-${github_repo}-combined/\n        └── ${filename_without_extension}/\n            ├── ${student1_github_login}.${filename_extension}\n            ├── ${student2_github_login}.${filename_extension}\n            ├── …\n            └── ${student${n}_github_login}.${filename_extension}\n\nThe name of the repository is currently hard-coded into the script.\n\n### Jupyter Tools\n\n#### Collate Jupyter Notebooks\n\n`./scripts/combine-notebooks REPO_NAME NOTEBOOK_FILE_NAME`\n\nCombine notebooks into a single notebook.\n\nThis script expects a directory structure created by the\n`download-repo-fork-files` script. It creates:\n\n    ./build/${github_organization}-${github_repo}\n    ├── processed_notebooks/\n    │   └── notebook_name.ipynb\n    └── summaries/\n        ├── poll1.csv\n        ├── poll2.csv\n        ├── …\n        └── poll${n}.csv\n\nThis script is derived from, and documented at,\n[osteele/assignment-tools](https://github.com/osteele/assignment-tools) (which\nwas in turn forked from\n[paulruvolo/SoftDesSp16Prep](https://github.com/paulruvolo/SoftDesSp16Prep)).\n\nThe version in this directory is not the latest, and is not under active\ndevelopment here. The [nbcollate\npackage](https://github.com/olin-computing/nbcollate) is the successor. `pip install nbcollate` to install this package, and the `nbcollate` command-line\ntool.\n\nA web application with similar functionality is at\n[olin-computing/assignment-dashboard](https://github.com/olin-computing/assignment-dashboard).\nThat application caches the state of GitHub into a local **sqlite3** store, and\nprovides a web interface for inspect completion status by student or by question\nand for browsing the original and collated notebooks.\n\n### Other Scripts\n\n#### Create Flashcards and Contact Sheet\n\n`./scripts/create-enrollment-flashcards HTML_FILE`\n\nGenerate a file and media directory suitable for consumption by [FlashCard\nDeluxe](http://orangeorapple.com/Flashcards/), from a Course Enrollment page\ndownloaded from the Portal.\n\n#### Create Student Contact Sheet\n\n`./scripts/create-enrollment-contact-sheet HTML_FILE`\n\nGenerate HTML \"contact sheet\" page, that displays all the student names and\nfaces in a grid, from a Course Enrollment page downloaded from the Portal.\n\n#### Summarize Scope Survey\n\n`./scripts/summarize-scope-survey CSV_FILE`\n\nGiven a SCOPE Peer and Self review spreadsheet, create an HTML report organized\nby student.\n\n## Contributing\n\nSome things to work on are listed\n[here](https://github.com/olin-computing/classroom-tools/issues).\n\n### Setting up a development environment\n\n`pip install -r requirements-dev.txt`\n\nTo test in new conda environment:\n\n```bash\n$ conda create --name classroom-tools python=3.5 pip\n$ source activate classroom-tools\n$ pip install -r requirements-dev.txt\n```\n\n### Style\n\nWith exceptions listed in `setup.cfg`, code should conform to\n[PEP8](https://www.python.org/dev/peps/pep-0008/),\n[PEP257](https://www.python.org/dev/peps/pep-0257/), and the [Google Python\nStyle Guide](http://google.github.io/styleguide/pyguide.html).\n\nYou can verify code against these style guides via:\n\n    $ pip3 install -r requirements-dev.txt  # once\n    $ flake8 scripts                        # before each commit\n\nor by setting up a [git pre-commit\nhook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) to run the\nlatter command.\n\nThese scripts are written in a Jupyter-notebook-like style, for easy development\nwith the [Hydrogen Atom plugin-in](https://atom.io/packages/hydrogen) and the\n[Python Visual Studio Code\nextension](\u003chttps://github.com/DonJayamanne/pythonVSCode/wiki/Jupyter-(IPython)\u003e).\n\nSpecifically, they are light on functions and heavy on global variables.\n\nThis is an experiment, and may not have legs. For example, it would be nice to\nbe able to re-organize the scripts as modules, and invoke them as subcommands\nfrom a single CLI entry point, or make them available to a web or desktop\napplication. The current style may not be compatible with that.\n\n### Directory Organization\n\n    classroom-tools/\n    ├── build – not committed to the repo\n    ├── config – not committed to the repo\n    ├── downloads – not committed to the repo\n    ├── scripts\n    │     Script functions, invoked from the command line.\n    ├── src\n    │     Utility functions that aren't scripts; potentially shared by multiple scripts.\n    └── templates\n          HTML jinja2 template files\n\n### Acknowledgements\n\n`combine-notebooks.py` is derived from a script by Paul Ruvolo at Olin\n[paulruvolo/SoftDesSp16Prep](https://github.com/paulruvolo/SoftDesSp16Prep).\n\n`create-enrollment-flashcards` is based on an idea by Ben Hill at Olin. His code\nwas simpler and cleaner but I added more functionality (nicknames, HTML\ngeneration) before I saw his, and haven't yet backed out my complexity in favor\nof his simplicity.\n\n### License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosteele%2Fclassroom-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosteele%2Fclassroom-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosteele%2Fclassroom-tools/lists"}