# Project export: Protégé

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 11.0
- Tagline: AI-powered platform for learning through teaching and real-time feedback.
- Devpost: https://devpost.com/software/protege-1yf7so
- GitHub: https://github.com/harsita-keerthi/protege
- Demo: https://protege.reflex.run/
- Team: 1 GitHub contributor(s) — harsita-keerthi (7 commits)

## Devpost submission (written by the team)

### Inspiration

We were inspired by the protégé effect, a psychological phenomenon where teaching others helps reinforce the student's own understanding. This concept motivated us to create a platform where users can actively learn by teaching an AI model, helping them deepen their comprehension through explanation and reflection. We wanted to develop a tool that not only allows users to absorb information but also empowers them to explain and teach back, simulating a learning loop that enhances retention and understanding.

### What it does

Protégé enables users to: Create lessons on any subject, either from their own study notes or with AI-generated information. Teach the AI by explaining concepts aloud, using real-time speech-to-text conversion. The AI then evaluates the user’s explanation, identifies errors or areas for improvement, and provides constructive feedback. This helps users better understand the material while reinforcing their knowledge through active participation. The system adapts to user performance, offering customized feedback and lesson suggestions based on their strengths and weaknesses.

### How we built it

Protégé was built using the Reflex framework to manage the front-end and user interface, ensuring a smooth, interactive experience. For the back-end, we integrated Google Gemini to generate lessons and evaluate user responses. To handle real-time speech-to-text conversion, we utilized Deepgram, a highly accurate speech recognition API, allowing users to speak directly to the AI for their explanations. By connecting these technologies through state management, we ensured seamless communication between the user interface and the AI models.

### Challenges we ran into

One of the main challenges was ensuring seamless integration between the AI model and the front-end so that lessons and feedback could be delivered in real time. Any lag would have disrupted the user experience, so we optimized the system to handle data flow efficiently. Another challenge was real-time speech-to-text accuracy. We needed a solution that could handle diverse speech patterns and accents, which led us to Deepgram for its ability to provide fast and accurate transcriptions even in complex environments.

### Accomplishments we're proud of

We’re particularly proud of successfully creating a platform that allows for real-time interaction between users and the AI, providing a smooth and intuitive learning experience. The integration of Deepgram for speech recognition significantly enhanced the teaching feature, enabling users to explain concepts verbally and receive immediate feedback. Additionally, our ability to simulate the protégé effect—where users reinforce their understanding by teaching—marks a key accomplishment in the design of this tool.

### What we learned

Throughout this project, we learned the importance of real-time system optimization, particularly when integrating AI models with front-end interfaces. We also gained valuable experience in balancing accuracy with performance, ensuring that both lesson generation and speech recognition worked seamlessly without compromising user experience. Additionally, building a system that adapts to users’ teaching performance taught us how crucial customization and feedback are in creating effective educational tools.

### What's next

Our next steps include: Developing personalized lesson plans that adapt based on user performance in teaching mode, making learning paths more tailored and effective. Adding gamified progress tracking, where users can earn achievements and track their improvement over time, keeping them motivated. Introducing community and peer learning features, allowing users to collaborate and share their teaching experiences with others. Building a mobile version of Protégé to make the platform more accessible for learning on the go.

## README (from the GitHub repository)

# Protégé

## Overview
**Protégé** is an AI-powered platform designed to enhance learning through teaching. Users create lessons on various topics and explain them to the AI, which provides real-time feedback and suggestions for improvement. This interactive approach reinforces understanding and deepens knowledge retention.

## Inspiration
Inspired by the **protégé effect**, where teaching others strengthens one's own understanding, Protégé aims to empower users to actively learn by explaining concepts to an AI model.

## Features
- **Lesson Creation**: Users can prompt the model to generate lessons based on topics.
- **Teaching Mode**: Users "teach" the AI by explaining concepts verbally.
- **Real-Time Feedback**: The AI evaluates responses and provides constructive suggestions.
- **Personalized Learning Paths**: Future versions will offer customized lesson plans based on user performance.

## Tech Stack
- **Front-End**: Built using the **Reflex framework** for a seamless user experience.
- **Back-End**: Integrated AI models for lesson generation and evaluation.
- **Speech Recognition**: Utilizes **Deepgram** for accurate real-time speech-to-text conversion.

## Installation
1. Clone the repository:
   ```
   git clone https://github.com/yourusername/protege.git
   ```
2. Navigate to the project directory:
    ```
    cd protege
    ```
3. Install Reflex: If you haven't installed Reflex yet, follow the instructions from the Reflex documentation.

4. Install Python dependencies: Ensure you have Python installed, then run:
    ```
    pip install -r requirements.txt
    ```
6. Start the application:
    ```
    reflex run
    ```

## Challenges Faced
- Ensuring seamless integration between the AI model and front-end.
- Achieving accurate real-time speech-to-text functionality.
## Accomplishments
- Developed a responsive platform for real-time interaction with the AI.
- Successfully integrated Deepgram for speech recognition, enhancing user experience.
## Future Plans
- Introduce personalized lesson plans based on user performance.
- Expand subject coverage for broader educational content.
- Add gamification elements to motivate users.
- Develop community features for collaborative learning.
- Create a mobile version for accessibility on the go.



## Detected evidence (automated analysis)

Indexed codebase: 15 recognized source files, 21 KB.
- FastAPI (technology) — detected in the code
- Flask (technology) — detected in the code
- Hugging Face (technology) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- PyTorch (technology) — detected in the code
- Redis (technology) — detected in the code
- TensorFlow (technology) — detected in the code

## Codebase structure (from repository index)

### Files (20 of 20)

```
.gitignore
assets/__init__.py
assets/styles/fonts.py
assets/styles/styles.py
ex.json
feedback.json
protege/__init__.py
protege/components/learn_schedule.py
protege/components/navbar.py
protege/components/prompt_form.py
protege/learn.py
protege/protege.py
protege/teach.py
README.md
requirements.txt
rxconfig.py
sample.m4a
server/create.py
server/critique.py
server/transcribe.py
```

### Dependencies

- requirements.txt: absl-py@==2.1.0, aiodns@==3.2.0, aiohappyeyeballs@==2.3.5, aiohttp@==3.10.3, aiosignal@==1.3.1, alembic@==1.13.2, alpaca-py@==0.28.1, alpaca-trade-api@==3.2.0, alpha_vantage@==3.0.0, aniso8601@==9.0.1, annotated-types@==0.7.0, anyio@==4.4.0, appdirs@==1.4.4, appnope@==0.1.4, APScheduler@==3.10.4, argon2-cffi@==23.1.0, argon2-cffi-bindings@==21.2.0, arrow@==1.3.0, asttokens@==2.4.1, astunparse@==1.6.3, async-lru@==2.0.4, attrs@==23.2.0, Babel@==2.15.0, bcrypt@==4.2.0, beautifulsoup4@==4.12.3, bidict@==0.23.1, bleach@==6.1.0, blinker@==1.8.2, blis@==0.7.11, bokeh@==3.5.0, build@==1.2.2.post1, cachetools@==5.3.3, catalogue@==2.0.10, catboost@==1.2.5, category-encoders@==2.6.3, ccxt@==4.3.79, certifi@==2024.7.4, cffi@==1.16.0, charset-normalizer@==3.3.2, click@==8.1.7, cloudpathlib@==0.18.1, cloudpickle@==3.0.0, comm@==0.2.2, confection@==0.1.5, contourpy@==1.2.1, cryptography@==43.0.0, cycler@==0.12.1, cymem@==2.0.8, Cython@==3.0.10, dash@==2.17.1, dash-core-components@==2.0.0, dash-html-components@==2.0.0, dash-table@==5.0.0, DateTime@==5.5, debugpy@==1.8.2, decorator@==5.1.1, defusedxml@==0.7.1, Deprecated@==1.2.14, deprecation@==2.1.0, distro@==1.9.0, dnspython@==2.6.1, docker@==7.1.0, docutils@==0.21.2, duckdb@==1.0.0, email_validator@==2.2.0, entrypoints@==0.4, exchange_calendars@==4.5.5, executing@==2.0.1, fastapi@==0.115.2, fastjsonschema@==2.20.0, filelock@==3.15.4, Flask@==3.0.3, Flask-Login@==0.6.3, flask-marshmallow@==1.2.1, Flask-Principal@==0.4.0, Flask-Security@==5.5.2, Flask-SocketIO@==5.3.6, Flask-SQLAlchemy@==3.1.1, Flask-WTF@==1.2.1, flatbuffers@==24.3.25, fonttools@==4.53.1, fqdn@==1.5.1, frozendict@==2.4.4, frozenlist@==1.4.1, fsspec@==2024.6.1, gast@==0.6.0, gensim@==4.3.2, gitdb@==4.0.11, GitPython@==3.1.43, google-ai-generativelanguage@==0.6.10, google-api-core@==2.21.0, google-api-python-client@==2.149.0, google-auth@==2.35.0, google-auth-httplib2@==0.2.0, google-generativeai@==0.8.3, google-pasta@==0.2.0, googleapis-common-protos@==1.63.2, graphene@==3.3, graphql-core@==3.2.3, graphql-relay@==3.2.0, graphviz@==0.20.3, grpcio@==1.67.0, grpcio-status@==1.67.0, gunicorn@==22.0.0, h11@==0.14.0, h5py@==3.11.0, html5lib@==1.1, httpcore@==1.0.5, httplib2@==0.22.0, httpx@==0.27.0, huggingface-hub@==0.23.4, ibapi@==9.81.1.post1, idna@==3.7, imbalanced-learn@==0.12.3, importlib_metadata@==7.1.0, importlib_resources@==6.4.0, inflection@==0.5.1, iniconfig@==2.0.0, ipykernel@==6.29.5, ipython@==8.26.0, ipywidgets@==8.1.3, isoduration@==20.11.0, itsdangerous@==2.2.0, jaraco.classes@==3.4.0, jaraco.context@==6.0.1, jaraco.functools@==4.1.0, jedi@==0.19.1, Jinja2@==3.1.4, jiter@==0.5.0, joblib@==1.3.2, json5@==0.9.25, jsonpickle@==3.2.2, jsonpointer@==3.0.0, jsonschema@==4.23.0, jsonschema-specifications@==2023.12.1, jupyter_client@==8.6.2, jupyter_core@==5.7.2, jupyter_server@==2.14.1, jupyter_server_terminals@==0.5.3, jupyter-events@==0.10.0, jupyter-lsp@==2.2.5, jupyterlab@==4.2.3, jupyterlab_pygments@==0.3.0, jupyterlab_server@==2.27.2, jupyterlab_widgets@==3.0.11, kaleido@==0.2.1, keras@==3.4.1, keyring@==25.4.1, kiwisolver@==1.4.5, korean-lunar-calendar@==0.3.1, langcodes@==3.4.0, language_data@==1.2.0, lazy_loader@==0.4, libclang@==18.1.1, lightgbm@==4.4.0, llvmlite@==0.43.0, lumibot@==3.6.4, lumiwealth-tradier@==0.1.8, lxml@==5.3.0, lz4@==4.3.3, Mako@==1.3.5, marisa-trie@==1.2.0, Markdown@==3.6, markdown-it-py@==3.0.0, MarkupSafe@==2.1.5, marshmallow@==3.21.3, marshmallow-sqlalchemy@==1.0.0, matplotlib@==3.7.5, matplotlib-inline@==0.1.7, mdurl@==0.1.2, mistune@==3.0.2, ml-dtypes@==0.3.2, mlflow@==2.14.2, more-itertools@==10.4.0, mpmath@==1.3.0, msgpack@==1.0.3, multidict@==6.0.5, multitasking@==0.0.11, murmurhash@==1.0.10, namex@==0.0.8, nbclient@==0.10.0, nbconvert@==7.16.4, nbformat@==5.10.4, nest-asyncio@==1.6.0, networkx@==3.3, nh3@==0.2.18, nltk@==3.8.1, notebook@==7.2.1, notebook_shim@==0.2.4, numba@==0.60.0, numpy@==1.26.4, openai@==1.42.0, opencv-python@==4.10.0.84, opentelemetry-api@==1.25.0, opentelemetry-sdk@==1.25.0, opentelemetry-semantic-conventions@==0.46b0, opt-einsum@==3.3.0, optree@==0.12.1, orjson@==3.10.6, overrides@==7.7.0, packaging@==24.1, pandas@==2.1.1, pandas_market_calendars@==4.4.1, pandas-datareader@==0.10.0, pandocfilters@==1.5.1, parso@==0.8.4, passlib@==1.7.4, patsy@==0.5.6, peewee@==3.17.6, pexpect@==4.9.0, pillow@==10.4.0, pinecone-client@==5.0.1, pinecone-plugin-inference@==1.0.3, pinecone-plugin-interface@==0.0.7, pipdeptree@==2.16.2, pkginfo@==1.10.0, platformdirs@==4.2.2, plotly@==5.22.0, plotly-resampler@==0.10.0, pluggy@==1.5.0, pmdarima@==2.0.4, polygon-api-client@==1.14.2, preshed@==3.0.9, prometheus_client@==0.20.0, prompt_toolkit@==3.0.47, proto-plus@==1.24.0, protobuf@==5.28.2, protoc-gen-openapiv2@==0.0.1, psutil@==6.0.0, psycopg2-binary@==2.9.9, ptyprocess@==0.7.0, pure-eval@==0.2.2, pyarrow@==15.0.2, pyasn1@==0.6.1, pyasn1_modules@==0.4.1, pycares@==4.4.0, pycaret@==3.3.2, pycparser@==2.22, pydantic@==2.8.2, pydantic_core@==2.20.1, Pygments@==2.18.0, pyluach@==2.2.0, pyod@==2.0.1, pyparsing@==3.1.2, pyproject_hooks@==1.2.0, pytest@==8.3.2, python-dateutil@==2.9.0.post0, python-dotenv@==1.0.1, python-engineio@==4.9.1, python-json-logger@==2.0.7, python-multipart@==0.0.12, python-socketio@==5.11.3, pytz@==2024.1, PyYAML@==6.0.1, pyzmq@==26.0.3, Quandl@==3.7.0, quantstats-lumi@==0.3.3, querystring-parser@==1.2.4, readme_renderer@==44.0, redis@==5.1.1, referencing@==0.35.1, reflex@==0.6.3, reflex-chakra@==0.6.2, reflex-hosting-cli@==0.1.13, regex@==2024.5.15, requests@==2.32.3, requests-toolbelt@==1.0.0, retrying@==1.3.4, rfc3339-validator@==0.1.4, rfc3986@==2.0.0, rfc3986-validator@==0.1.1, rich@==13.7.1, rpds-py@==0.19.0, rsa@==4.9, safetensors@==0.4.3, schemdraw@==0.15, scikit-base@==0.7.8, scikit-learn@==1.4.2, scikit-plot@==0.3.7, scipy@==1.11.4, seaborn@==0.13.2, Send2Trash@==1.8.3, setuptools@==75.2.0, shellingham@==1.5.4, simple-websocket@==1.0.0, six@==1.16.0, sktime@==0.26.0, smart-open@==7.0.4, smmap@==5.0.1, sniffio@==1.3.1, soupsieve@==2.5, spacy@==3.7.5, spacy-legacy@==3.0.12, spacy-loggers@==1.0.5, SQLAlchemy@==2.0.31, sqlmodel@==0.0.22, sqlparse@==0.5.0, srsly@==2.4.8, sseclient-py@==1.8.0, stack-data@==0.6.3, starlette@==0.40.0, starlette-admin@==0.14.1, statsmodels@==0.14.2, sympy@==1.13.0, tabulate@==0.9.0, tbats@==1.1.3, tenacity@==8.5.0, tensorboard@==2.16.2, tensorboard-data-server@==0.7.2, tensorflow@==2.16.2, termcolor@==2.4.0, terminado@==0.18.1, thinc@==8.2.5, threadpoolctl@==3.5.0, timedelta@==2020.12.3, tinycss2@==1.3.0, tokenizers@==0.19.1, tomlkit@==0.13.2, toolz@==0.12.1, torch@==2.4.0, torchaudio@==2.4.0, torchvision@==0.19.0, tornado@==6.4.1, tqdm@==4.66.4, traitlets@==5.14.3, transformers@==4.42.3, tsdownsample@==0.1.3, twine@==5.1.1, typer@==0.12.3, types-python-dateutil@==2.9.0.20240316, typing_extensions@==4.12.2, tzdata@==2024.1, tzlocal@==5.2, uri-template@==1.3.0, uritemplate@==4.1.1, urllib3@==1.26.19, uuid@==1.30, uvicorn@==0.32.0, wasabi@==1.1.3, wcwidth@==0.2.13, weasel@==0.4.1, webcolors@==24.6.0, webencodings@==0.5.1, websocket-client@==1.8.0, websockets@==10.4, Werkzeug@==3.0.3, wheel@==0.44.0, widgetsnbextension@==4.0.11, wrapt@==1.16.0, wsproto@==1.2.0, WTForms@==3.1.2, wurlitzer@==3.1.1, xgboost@==2.1.0, xxhash@==3.4.1, xyzservices@==2024.6.0, yarl@==1.9.4, yellowbrick@==1.5, yfinance@==0.2.41, zipp@==3.19.2, zope.interface@==7.0.1

### Recent commits (newest first)

- transcribe ui
- deepgram implmentation
- ui basics
- initialize reflex
- removed upload icon + display feedback
- refactoring for deployment
- Update README.md
- refactoring for deployment
- ui updates
- revised prompt for create lesson plan function
- updated requirements
- backend, create lesson plan function
- Initial commit

## Key source files (fetched from GitHub, selected and truncated for size)

### requirements.txt

```
absl-py==2.1.0
aiodns==3.2.0
aiohappyeyeballs==2.3.5
aiohttp==3.10.3
aiosignal==1.3.1
alembic==1.13.2
alpaca-py==0.28.1
alpaca-trade-api==3.2.0
alpha_vantage==3.0.0
aniso8601==9.0.1
annotated-types==0.7.0
anyio==4.4.0
appdirs==1.4.4
appnope==0.1.4
APScheduler==3.10.4
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==2.4.1
astunparse==1.6.3
async-lru==2.0.4
attrs==23.2.0
Babel==2.15.0
bcrypt==4.2.0
beautifulsoup4==4.12.3
bidict==0.23.1
bleach==6.1.0
blinker==1.8.2
blis==0.7.11
bokeh==3.5.0
build==1.2.2.post1
cachetools==5.3.3
catalogue==2.0.10
catboost==1.2.5
category-encoders==2.6.3
ccxt==4.3.79
certifi==2024.7.4
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cloudpathlib==0.18.1
cloudpickle==3.0.0
comm==0.2.2
confection==0.1.5
contourpy==1.2.1
cryptography==43.0.0
cycler==0.12.1
cymem==2.0.8
Cython==3.0.10
dash==2.17.1
dash-core-components==2.0.0
dash-html-components==2.0.0
dash-table==5.0.0
DateTime==5.5
debugpy==1.8.2
decorator==5.1.1
defusedxml==0.7.1
Deprecated==1.2.14
deprecation==2.1.0
distro==1.9.0
dnspython==2.6.1
docker==7.1.0
docutils==0.21.2
duckdb==1.0.0
email_validator==2.2.0
entrypoints==0.4
exchange_calendars==4.5.5
executing==2.0.1
fastapi==0.115.2
fastjsonschema==2.20.0
filelock==3.15.4
Flask==3.0.3
Flask-Login==0.6.3
flask-marshmallow==1.2.1
Flask-Principal==0.4.0
Flask-Security==5.5.2
Flask-SocketIO==5.3.6
Flask-SQLAlchemy==3.1.1
Flask-WTF==1.2.1
flatbuffers==24.3.25
fonttools==4.53.1
fqdn==1.5.1
frozendict==2.4.4
frozenlist==1.4.1
fsspec==2024.6.1
gast==0.6.0
gensim==4.3.2
gitdb==4.0.11
GitPython==3.1.43
google-ai-generativelanguage==0.6.10
google-api-core==2.21.0
google-api-python-client==2.149.0
google-auth==2.35.0
google-auth-httplib2==0.2.0
google-generativeai==0.8.3
google-pasta==0.2.0
googleapis-common-protos==1.63.2
graphene==3.3
graphql-core==3.2.3
graphql-relay==3.2.0
graphviz==0.20.3
grpcio==1.67.0
grpcio-status==1.67.0
gunicorn==22.0.0
h11==0.14.0
h5py==3.11.0
html5lib==1.1
httpcore==1.0.5
httplib2==0.22.0
httpx==0.27.0
huggingface-hub==0.23.4
ibapi==9.81.1.post1
idna==3.7
imbalanced-learn==0.12.3
importlib_metadata==7.1.0
importlib_resources==6.4.0
inflection==0.5.1
iniconfig==2.0.0
ipykernel==6.29.5
ipython==8.26.0
ipywidgets==8.1.3
isoduration==20.11.0
itsdangerous==2.2.0
jaraco.classes==3.4.0
jaraco.context==6.0.1
jaraco.functools==4.1.0
jedi==0.19.1
Jinja2==3.1.4
jiter==0.5.0
joblib==1.3.2
json5==0.9.25
jsonpickle==3.2.2
jsonpointer==3.0.0
jsonschema==4.23.0
jsonschema-specifications==2023.12.1
jupyter-events==0.10.0
jupyter-lsp==2.2.5
jupyter_client==8.6.2
jupyter_core==5.7.2
jupyter_server==2.14.1
jupyter_server_terminals==0.5.3
jupyterlab==4.2.3
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.2
jupyterlab_widgets==3.0.11
kaleido==0.2.1
keras==3.4.1
keyring==25.4.1
kiwisolver==1.4.5
korean-lunar-calendar==0.3.1
langcodes==3.4.0
language_data==1.2.0
lazy_loader==0.4
libclang==18.1.1
lightgbm==4.4.0
llvmlite==0.43.0
lumibot==3.6.4
lumiwealth-tradier==0.1.8
lxml==5.3.0
lz4==4.3.3
Mako==1.3.5
marisa-trie==1.2.0
Markdown==3.6
markdown-it-py==3.0.0
MarkupSafe==2.1.5
marshmallow==3.21.3
marshmallow-sqlalchemy==1.0.0
matplotlib==3.7.5
matplotlib-inline==0.1.7
mdurl==0.1.2
mistune==3.0.2
ml-dtypes==0.3.2
mlflow==2.14.2
more-itertools==10.4.0
mpmath==1.3.0
msgpack==1.0.3
multidict==6.0.5
multitasking==0.0.11
murmurhash==1.0.10
namex==0.0.8
nbclient==0.10.0
nbconvert==7.16.4
nbformat==5.10.4
nest-asyncio==1.6.0
networkx==3.3
nh3==0.2.18
nltk==3.8.1
notebook==7.2.1
notebook_shim==0.2.4
numba==0.60.0
numpy==1.26.4
openai==1.42.0
opencv-python==4.10.0.84
opentelemetry-api==1.25.0
opentelemetry-sdk==1.25.0
opentelemetry-semantic-conventions==0.46b0
opt-einsum==3.3.0
optree==0.12.1
orjson==3.10.6
overrides==7.7.0
packaging==24.1
pandas==2.1.1
pandas-datareader==0.10.0
pandas_market_calendars==4.4.1
pandocfilters==1.5.1
parso==0.8.4
passlib==1.7.4
patsy==0.5.6
peewee==3.17.6
pexpect==4.9.0
pillow==10.4.0
pinecone-client==5.0.1
pinecone-plugin-inference==1.0.3
pinecone-plugin-interface==0.0.7
pipdeptree==2.16.2
pkginfo==1.10.0
platformdirs==4.2.2
plotly==5.22.0
plotly-resampler==0.10.0
pluggy==1.5.0
pmdarima==2.0.4
polygon-api-client==1.14.2
preshed==3.0.9
prometheus_client==0.20.0
prompt_toolkit==3.0.47
proto-plus==1.24.0
protobuf==5.28.2
protoc-gen-openapiv2==0.0.1
psutil==6.0.0
psycopg2-binary==2.9.9
ptyprocess==0.7.0
pure-eval==0.2.2
pyarrow==15.0.2
pyasn1==0.6.1
pyasn1_modules==0.4.1
pycares==4.4.0
pycaret==3.3.2
pycparser==2.22
pydantic==2.8.2
pydantic_core==2.20.1
Pygments==2.18.0
pyluach==2.2.0
pyod==2.0.1
pyparsing==3.1.2
pyproject_hooks==1.2.0
pytest==8.3.2
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
python-engineio==4.9.1
python-json-logger==2.0.7
python-multipart==0.0.12
python-socketio==5.11.3
pytz==2024.1
PyYAML==6.0.1
pyzmq==26.0.3
Quandl==3.7.0
quantstats-lumi==0.3.3
querystring-parser==1.2.4
readme_renderer==44.0
redis==5.1.1
referencing==0.35.1
reflex==0.6.3
reflex-chakra==0.6.2
reflex-hosting-cli==0.1.13
regex==2024.5.15
requests==2.32.3
requests-toolbelt==1.0.0
retrying==1.3.4
rfc3339-validator==0.1.4
rfc3986==2.0.0
rfc3986-validator==0.1.1
rich==13.7.1
rpds-py==0.19.0
rsa==4.9
safetensors==0.4.3
schemdraw==0.15
scikit-base==0.7.8
scikit-learn==1.4.2
scikit-plot==0.3.7
scipy==1.11.4
seaborn==0.13.2
Send2Trash==1.8.3
setuptools==75.2.0
shellingham==1.5.4
simple-websocket==1.0.0
six==1.16.0
sktime==0.26.0
smart-open==7.0.4
smmap==5.0.1
sniffio==1.3.1
soupsieve==2.5
spacy==3.7.5
spacy-legacy==3.0.12
spacy-loggers==1.0.5
SQLAlchemy==2.0.31
sqlmodel==0.0.22
sqlparse==0.5.0
srsly==2.4.8
sseclient-py==1.8.0
stack-data==0.6.3
starlette==0.40.0
starlette-admin==0.14.1
statsmodels==0.14.2
sympy==1.13.0
tabulate==0.9.0
tbats==1.1.3
tenacity==8.5.0
tensorboard==2.16.2
tensorboard-data-server==0.7.2
tensorflow==2.16.2
termcolor==2.4.0
terminado==0.18.1
thinc==8.2.5
threadpoolctl==3.5.0
timedelta==2020.12.3
tinycss2==1.3.0
tokenizers==0.19.1
tomlkit==0.13.2
toolz==0.12.1
torch==2.4.0
torchaudio==2.4.0
torchvision==0.19.0
tor
[truncated — 659 more characters]
```

### rxconfig.py

```python
import reflex as rx

config = rx.Config(
    app_name="protege",
)
```

### protege/learn.py

```python
import reflex as rx

from rxconfig import config
from .components.navbar import *
from .components.prompt_form import *
from .components.learn_schedule import *

# sample file
import json
with open('ex.json', 'r') as file:
    data = json.load(file)

class State(rx.State):
    show: bool = False
    prompt_data = FormInputState.prompt_data
    def toggle_visibility(self):
        self.show = not self.show
# lesson plan generation page
def learn() -> rx.Component:
    return rx.fragment(
        navbar_user(), # navbar
        rx.color_mode.button(position="bottom-left"),
        rx.vstack( 
            rx.heading("what do you want to learn?", size="9", align="center"),
            form_input1(),

            # styling
            spacing="5",
            justify="center",
            align_items="center",
            display="flex",
            flex_direction="column",
            min_height="85vh",
            padding_bottom="220px",
            padding_top="240px",
        ),
        learn_schedule(data)
        
        # rx.cond(
        #     State.show,
        #     learn_schedule(FormInputState.res),
        #     learn_schedule(data)
        # )
    )
```

### server/transcribe.py

```python
from deepgram import DeepgramClient, PrerecordedOptions
import os
import json
from .critique import *

# Example of a custom class
class CustomResponse:
    def __init__(self, data):
        self.data = data

    def to_dict(self):
        return self.data  # Convert the object to a dictionary
    
    curr_feedback=""

DEEPGRAM_API_KEY = os.getenv("DEEPGRAM_API_KEY")
AUDIO_FILE = "sample.m4a"

def process():
    deepgram = DeepgramClient(DEEPGRAM_API_KEY)
    with open(AUDIO_FILE, 'rb') as buffer_data:
        payload = {'buffer': buffer_data}

        options = PrerecordedOptions(
            smart_format=True, model="base", language="en-US"
        )

        # Make the API call
        response = deepgram.listen.prerecorded.v('1').transcribe_file(payload, options)

        # Function to handle serialization of non-serializable types
        def custom_serializer(obj):
            if hasattr(obj, 'to_dict'):
                return obj.to_dict()  # Call to_dict method if it exists
            raise TypeError(f'Object of type {type(obj)} is not JSON serializable')

        # Convert response to JSON string
        json_string = json.dumps(response, default=custom_serializer)

        # Convert JSON string back to a Python dictionary
        response_dict = json.loads(json_string)

        # Now you can access the values using keys
        transcript = response_dict["results"]["channels"][0]["alternatives"][0]["transcript"]

        # Print the transcript
        CustomResponse.curr_feedback = generate_pointers(transcript)

def get_feedback():
    return CustomResponse.curr_feedback
```

### server/critique.py

```python
import os
import google.generativeai as genai
from dotenv import load_dotenv

# load environment variables
load_dotenv()

# configure the Generative AI API
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))

# function to create a lesson plan
def generate_pointers(transcript):
    # set up generation configuration
    generation_config = {
        "temperature": 0.5,
        "top_p": 0.95,
        "top_k": 64,
        "max_output_tokens": 8192,
        "response_mime_type": "application/json",
    }

    # create the generative model
    model = genai.GenerativeModel(
        model_name="gemini-1.5-flash",
        generation_config=generation_config,
        system_instruction="You are an AI designed to help users enhance their learning by allowing them to teach you a subject. After the user explains a concept, create a table with the columns as positive feedback, negative feedback, and which topics they should review more. Your goal is to help the user solidify their understanding through reflection. Adapt your feedback table based on their explanations, focusing on areas where you sense uncertainty or opportunity for more learning. Be empathetic and understand their learning needs. Do not be condescending.",
    )

    # construct the user prompt
    user_prompt = transcript

    # initialize history
    history = []

    # start a chat session
    chat_session = model.start_chat(history=history)

    # send the message and get a response from the model
    response = chat_session.send_message(user_prompt)

    # get the model's response
    model_response = response.text

    # append the user input and model response to the history (optional for tracking)
    history.append({"role": "user", "parts": [user_prompt]})
    history.append({"role": "model", "parts": [model_response]})

    return model_response  # return the lesson plan generated by the model
```

### server/create.py

```python
# pip install google-generativeai
# pip install python-dotenv

import os
import google.generativeai as genai
from dotenv import load_dotenv

# load environment variables
load_dotenv()

# configure the Generative AI API
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))

# function to create a lesson plan
def create_lesson_plan(topic, weeks_to_learn, hours_per_day):
    # set up generation configuration
    generation_config = {
        "temperature": 0.5,
        "top_p": 0.95,
        "top_k": 64,
        "max_output_tokens": 8192,
        "response_mime_type": "application/json",
    }

    # create the generative model
    model = genai.GenerativeModel(
        model_name="gemini-1.5-flash",
        generation_config=generation_config,
        system_instruction="You are an AI designed to generate customized lesson plans for students based on their available time and learning goals. Given a topic, number of weeks left to learn the topic, and number of hours the student can commit to learning per day, your task is to create a lesson plan in table format that fits within the student’s schedule, dividing topics into manageable sections for efficient learning. The columns in the lesson plan table should be week number, day number, duration, topic name, description, and resources to study the topic.",
    )

    # construct the user prompt
    user_prompt = f"topic: {topic}. number of weeks: {weeks_to_learn}. number of hours per day: {hours_per_day}"

    # initialize history
    history = []

    # start a chat session
    chat_session = model.start_chat(history=history)

    # send the message and get a response from the model
    response = chat_session.send_message(user_prompt)

    # get the model's response
    model_response = response.text

    # append the user input and model response to the history (optional for tracking)
    history.append({"role": "user", "parts": [user_prompt]})
    history.append({"role": "model", "parts": [model_response]})

    return model_response  # return the lesson plan generated by the model
```

### protege/protege.py

```python
import reflex as rx
from assets.styles import styles

from rxconfig import config
from .components.navbar import *
from .teach import *
from .learn import *

class State(rx.State):
    """The app state."""

    ...

def index() -> rx.Component:
    # Welcome Page (Index)
    return rx.fragment(
        navbar_user(),
        rx.color_mode.button(position="bottom-left"),
        rx.vstack(
            rx.heading(
                "let's learn!",
                size="9", 
                align="center", 
                font_family="Baloo Tamma 2", 
                weight="bold"
                ),
            
            spacing="5",
            padding_top="300px",
            justify="center",
            align_items="center",
            display="flex",
            flex_direction="column",
            #min_height="85vh",
            padding_bottom="25px",
        ),
        rx.hstack(
            rx.link(
                rx.button("learn",
                width="150px",
                height="45px",
                font_size="27px",
                ),
                href="/learn",
            ),
            rx.link(
                rx.button("teach",
                width="150px",
                height="45px",
                font_size="27px",
                ),
                href="/teach",
            ),
            spacing="5",
            justify="center",
            display="flex",
            flex_direction="row",
            #min_height="85vh",
        ),
        spacing="0",
        # rx.logo() # reflex logo
    )

# style = {
#     font-family: "Poppins",
#     font_size: "16px",
# }

app = rx.App(
    # style=style,
    stylesheets=[
        "https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&family=IBM+Plex+Mono:ital,wght@0,500;0,600;1,600&display=swap",
    ],
    theme=rx.theme(
        appearance="light",
        has_background=True,
        radius="large",
        accent_color="indigo",
        panel_background="translucent"
    )
)
app.add_page(index, route="/")
app.add_page(teach, route="/teach")
app.add_page(learn, route="/learn")

```

### protege/teach.py

```python
import reflex as rx
from rxconfig import config
from .components.navbar import *
from server.transcribe import *
import io
from server.critique import *

import json
with open('feedback.json', 'r') as file:
    data = json.load(file)

curr_feedback = data

class State(rx.State):
    # Example of how you might process the file bytes before passing
    def handle_upload(self, files):
        if files:
            # The uploaded files come in as a list, handle the first one
            uploaded_file = files[0]
            # Extract the file name and content
            file_name = uploaded_file["name"]
            file_content = uploaded_file["content"]  # Content will be in bytes
            
            # You can now process the content, e.g., transcribe or save the file
            self.process_audio(file_content, file_name)
    
    def process_audio(self, file_content, file_name):
        # Assume process is a function that handles the audio content
        # file_content is in bytes, so you may need to use an audio processing library
        # For example, saving it to a temporary file and processing it:
        
        # Example: save file to a temp directory, use pydub or wave to process the audio
        audio_file = io.BytesIO(file_content)  # Convert bytes into a file-like object
        
        # Pass the audio to some transcription function
        # For example: transcribe(audio_file)
        process(audio_file, file_name)  # Call your processing/transcribing function

def teach() -> rx.Component:
    return rx.fragment(
        navbar_user(),  # navbar
        rx.color_mode.button(position="bottom-left"),
        rx.vstack(
            rx.heading("become a protégé.", size="9", align="center"),
            rx.upload(
                rx.text("Drag and drop files here or click to select files", size="10px"),
                accept={"audio/*": [".mp3", ".wav", ".m4a"]},
                border="1px dotted rgb(107,99,246)",
                padding="5em",
                id="audio_upload",  # assign an ID to reference later
                align="center"
            ),
            rx.button(
                "Submit", 
                on_click=process()
            ),
            rx.card(curr_feedback),
            # organize_feedback(curr_feedback['feedback']),
            # pro_con_chart(),

            # styling
            spacing="5",
            justify="center",
            align_items="center",
            display="flex",
            flex_direction="column",
            min_height="85vh",
            padding_bottom="220px",
            padding_top="240px",
            
        ),
    )

def organize_feedback(response):
    feedback = {
        'positive': [],
        'negative': [],
        'review': [],
    }

    for i in response: # dictionary {pos,neg,rev}
        feedback['positive'].append(i['positive'])
        feedback['negative'].append(i['negative'])
        for j in i['review']:
            feedback['review'].append(j)
        
    curr_feedback = feedback

def create_feedback(f: str) -> rx.Component:
    return rx.card(f)

def create_feedback_type(feedback_type: dict) -> rx.Component:
    return rx.vstack(
        rx.foreach(
            feedback_type[1], 
            create_feedback
        ),
        width="100%"
    )

def pro_con_chart() -> rx.Component:
    return rx.hstack(
        rx.foreach(
            curr_feedback, 
            create_feedback_type
        ),
        width="100%"
    )
    

```

### assets/styles/fonts.py

```python
font_weights = {
    "bold": "800",
    "heading": "700",
    "subheading": "600",
    "section": "600",
}
```

### assets/styles/styles.py

```python
import reflex as rx
from .fonts import font_weights as fw

STYLESHEETS = [
    "https://fonts.googleapis.com/css2?family=Baloo+Tamma+2:wght@400..800;800&display=swap",
]
```

[3 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]