Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c74a5c3
complete basic project setup
JunHaoChen16 Nov 2, 2025
4651edb
update ci.yml
JunHaoChen16 Nov 2, 2025
aa2c019
Fix CI Python version mismatch
JunHaoChen16 Nov 2, 2025
6615e11
Fix CI Python version mismatch #2
JunHaoChen16 Nov 2, 2025
526ca9d
Fix CI Python version mismatch #3
JunHaoChen16 Nov 2, 2025
0232030
Fix CI Python version mismatch #4
JunHaoChen16 Nov 2, 2025
4d73409
added basic datamanagement function
JunHaoChen16 Nov 2, 2025
6096930
update pytest file for dataManagement file
JunHaoChen16 Nov 2, 2025
85ed34a
Merge pull request #2 from swe-students-fall2025/feature_dataManagement
JunHaoChen16 Nov 2, 2025
8b160c8
added core logic of leveling and store time data
JunHaoChen16 Nov 3, 2025
899a627
Merge pull request #3 from swe-students-fall2025/feature_petModule_co…
JunHaoChen16 Nov 3, 2025
d78bb98
export functions in init.py
JunHaoChen16 Nov 3, 2025
b787f7c
export functions in init.py and update newest version
JunHaoChen16 Nov 3, 2025
dc4cff3
Merge pull request #4 from swe-students-fall2025/feature_petModule_co…
JunHaoChen16 Nov 3, 2025
dc69edd
Add StudyPet interaction system and core updates
JunHaoChen16 Nov 3, 2025
f217779
Merge pull request #5 from swe-students-fall2025/feature_petModule_in…
JunHaoChen16 Nov 3, 2025
09f0d11
add additional cases for pet's actions
catherineyu2014 Nov 3, 2025
e56e78d
Merge pull request #6 from swe-students-fall2025/unit_tests
catherineyu2014 Nov 3, 2025
bc44beb
added unit tests for main
catherineyu2014 Nov 3, 2025
5e4fdc1
Merge pull request #7 from swe-students-fall2025/unit_tests
catherineyu2014 Nov 3, 2025
80cdd86
readme update
LeoFYH Nov 3, 2025
b2d2627
Merge branch 'swe-students-fall2025:pipfile-experiment' into pipfile-…
LeoFYH Nov 3, 2025
7fa3dd7
Merge pull request #8 from LeoFYH/pipfile-experiment
Zeba-Shafi Nov 3, 2025
82482f0
Readme edits
Zeba-Shafi Nov 3, 2025
d24cdd9
Readme edits
Zeba-Shafi Nov 3, 2025
56b4bb9
renamePet parameter supported
LeoFYH Nov 3, 2025
7038f5e
feedPet parameter supported
LeoFYH Nov 3, 2025
6d503da
Merge pull request #9 from LeoFYH/pipfile-experiment
LeoFYH Nov 3, 2025
dfbf7f7
Revert "Merge pull request #9 from LeoFYH/pipfile-experiment"
LeoFYH Nov 3, 2025
5fa7aa1
Merge pull request #10 from LeoFYH/pipfile-experiment
Zeba-Shafi Nov 3, 2025
81fbea2
test
Zeba-Shafi Nov 3, 2025
1353dc0
Merge pull request #11 from swe-students-fall2025/temp-branch
Zeba-Shafi Nov 3, 2025
9dc7f2b
Refactor README to remove team section
catherineyu2014 Nov 3, 2025
c4f3576
Update repository URL in installation instructions
catherineyu2014 Nov 3, 2025
4e94bef
rename&feed
LeoFYH Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
push:
branches: ["main", "pipfile-experiment"]
pull_request:
branches: ["main", "pipfile-experiment"]

jobs:
test:
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pipenv
pipenv install --dev --skip-lock --python $(which python)

- name: Run tests
run: |
pipenv run pytest --maxfail=1 --disable-warnings -q
14 changes: 14 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]
build = "*"
twine = "*"
pytest = "*"

[requires]
python_version = "3.13"
391 changes: 391 additions & 0 deletions Pipfile.lock

Large diffs are not rendered by default.

28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# Python Package Exercise
[![CI](https://github.com/swe-students-fall2025/3-python-package-team_cascade/actions/workflows/ci.yml/badge.svg?branch=pipfile-experiment)](https://github.com/swe-students-fall2025/3-python-package-team_cascade/actions/workflows/ci.yml)

An exercise to create a Python package, build it, test it, distribute it, and use it. See [instructions](./instructions.md) for details.
# StudyPet

## Team Members

- [Catherine Yu](https://github.com/catherineyu2014)
- [Leo Fu](https://github.com/LeoFYH)
- [JunHao Chen](https://github.com/JunHaoChen16)
- [Majo Salgado](https://github.com/mariajsalgadoq)
- [Zeba Shafi](https://github.com/Zeba-Shafi)

## Installation

Install from PyPI:

```bash
pip install study-pet
```

Or install from source:

```bash
git clone https://github.com/swe-students-fall2025/3-python-package-team_cascade.git
cd team_cascade
pipenv install --dev
```
11 changes: 11 additions & 0 deletions study_pet/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .tracker import start_session, end_session
from .pet.core import get_status
from .data_manager import reset_state as _reset_state

__all__ = ["start_session", "end_session", "get_status", "reset_pet"]


def reset_pet():
"""Resets all pet data and progress."""
_reset_state()
print("🐣 Your pet has been reborn! All progress reset.")
120 changes: 120 additions & 0 deletions study_pet/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from . import start_session, end_session, get_status, reset_pet
from .data_manager import load_state, save_state
from .pet import rename_pet, collect_money, feed_pet, check_daily_mood_decay
import argparse
import study_pet.tracker as tracker


def main():
parser = argparse.ArgumentParser(description="🐾 StudyPet CLI")
parser.add_argument(
"command",
nargs="?",
default="menu",
help="Available commands: start, end, status, feed, rename, menu",
)
parser.add_argument(
"arg",
nargs="?",
default=None,
help="Optional argument for feed (food name) or rename (new name)",
)
args = parser.parse_args()

check_daily_mood_decay()

if args.command == "start":
start_session()
elif args.command == "end":
end_session()
elif args.command == "status":
print(get_status())
elif args.command == "feed":
feed_pet(args.arg)
elif args.command == "rename":
rename_pet(args.arg)
elif args.command == "menu":
main_menu()
else:
print("Unknown command. Use: start | end | status | feed [food] | rename [name] | menu")


def actions_menu():
"""Submenu for all pet-related actions."""
while True:
print("\nActions Menu:")
print("1. Collect coins ")
print("2. Feed your pet")
print("3. Back")

choice = input("\nSelect an option (1–3): ").strip()

if choice == "1":
collect_money()
elif choice == "2":
feed_pet()
elif choice == "3":
break
else:
print("Invalid option. Try again.")


def settings_menu():
"""Submenu for settings and info."""
while True:
print("\nSettings Menu:")
print("1. Check pet status")
print("2. Rename your pet")
print("3. Reset all data")
print("4. Back")

choice = input("\nSelect an option (1–4): ").strip()

if choice == "1":
print(get_status())
elif choice == "2":
rename_pet()
elif choice == "3":
confirm = input(
"This will reset all progress. Type 'byebye' to confirm "
).lower()
if confirm == "byebye":
reset_pet()
elif choice == "4":
break
else:
print("Invalid option. Try again.")


def main_menu():
"""Main entry menu."""
while True:
print("\n🐾 Welcome to StudyPet!\n")
print("1. Start studying ")
print("2. End session")
print("3. Actions")
print("4. Settings")
print("5. Close Menu (return to terminal)")
print("6. Exit (Close StudyPet to terminal)")

choice = input("\nSelect an option (1–6): ").strip()
if choice == "1":
start_session()
elif choice == "2":
end_session()
elif choice == "3":
actions_menu()
elif choice == "4":
settings_menu()
elif choice == "5":
tracker.manual_close = True
break
elif choice == "6":
tracker.manual_close = False
break
else:
print("Invalid option. Try again.")


if __name__ == "__main__":
main()
55 changes: 55 additions & 0 deletions study_pet/data_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import json
import os

DATA_DIR = os.path.expanduser("~/.study_pet")
DATA_PATH = os.path.join(DATA_DIR, "data.json")

default_state = {
"name": "Guido",
"level": 1,
"experience": 0.0,
"total_study_time": 0.0,
"last_session_start": None,
"last_study_date": None,
"mood": 100,
"streak_days": 0,
"money": 0,
"last_collect_time": None,
"last_feed_date": None,
"last_open_date": None,
}


def ensure_data_dir():
if not os.path.exists(DATA_DIR):
os.makedirs(DATA_DIR, exist_ok=True)


def load_state():
""" """
ensure_data_dir()
if not os.path.exists(DATA_PATH):
save_state(default_state)
try:
with open(DATA_PATH, "r") as f:
return json.load(f)
except (json.JSONDecodeError, FileNotFoundError):
save_state(default_state)
return default_state.copy()


def save_state(state: dict):
ensure_data_dir()
with open(DATA_PATH, "w") as f:
json.dump(state, f, indent=4)


def reset_state():
save_state(default_state.copy())


if __name__ == "__main__":
print("📁 Checking data directory:", DATA_DIR)
reset_state()
print("✅ Pet data initialized at:", DATA_PATH)
print("📂 Current state:", load_state())
10 changes: 10 additions & 0 deletions study_pet/pet/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from .core import get_status, check_daily_mood_decay
from .actions import rename_pet, collect_money, feed_pet

__all__ = [
"get_status",
"rename_pet",
"collect_money",
"feed_pet",
"check_daily_mood_decay",
]
Loading
Loading