From 29ed85ceaba0d4460f063e0857ea59c0a5fc4fd1 Mon Sep 17 00:00:00 2001 From: HirujaFernando Date: Fri, 25 Apr 2025 12:10:23 +0530 Subject: [PATCH 1/2] first commit --- .github/workflows/test.yaml | 42 ++-- CONTRIBUTING.md | 142 ++++++------ README.md | 154 ++++++------- main.py | 210 +++++++++--------- run_all_tests.py | 18 +- src/calculator.py | 100 ++++----- src/grade_project.egg-info/PKG-INFO | 6 +- src/grade_project.egg-info/SOURCES.txt | 14 +- .../dependency_links.txt | 2 +- src/grade_project.egg-info/top_level.txt | 2 +- tests/test_calculator.py | 90 ++++---- tests/test_colour.py | 54 ++--- tests/test_input_utils.py | 58 ++--- tests/test_time.py | 132 +++++------ 14 files changed, 512 insertions(+), 512 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ca24ee7..2836bdc 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,21 +1,21 @@ -name: Test Bug Fixes - -on: - pull_request: - branches: ["main", "master"] - -jobs: - test-project: - runs-on: ubuntu-latest - steps: - - name: checkout repo - uses: actions/checkout@v3 - - name: setup python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: install dependencies - run: python -m pip install -r requirements.txt - - name: run tests - run: python run_all_tests.py | tail -n 1 - continue-on-error: true +name: Test Bug Fixes + +on: + pull_request: + branches: ["main", "master"] + +jobs: + test-project: + runs-on: ubuntu-latest + steps: + - name: checkout repo + uses: actions/checkout@v3 + - name: setup python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: install dependencies + run: python -m pip install -r requirements.txt + - name: run tests + run: python run_all_tests.py | tail -n 1 + continue-on-error: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38cf263..35a83d8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,71 +1,71 @@ -🀝 Contributing Guidelines - -We welcome contributions to improve this Grade Calculator project! Follow the guidelines below to get started: -πŸš€ Getting Started - -Fork the Repository - -Click the β€œFork” button in the top-right corner of this repo. - -Clone Your Fork - - git clone https://github.com/CodeJam-by-CSE/practice.git - cd grade-calculator - -Set Up a Virtual Environment (optional but recommended) - - python -m venv venv - source venv/bin/activate # On Windows: venv\Scripts\activate - pip install -r requirements.txt - -Run the App - - python main.py - -πŸ§ͺ Running Tests - -Before submitting a pull request, make sure all tests pass: - - python -m unittest discover tests - -You can also run individual test files: - - python tests/test_calculator.py - -✍️ How to Contribute - -πŸ”§ Fix Bugs -Check existing issues or create a new one before submitting a fix. - -✨ Add Features -Make sure new features align with the app’s educational goals and include tests. - -🧹 Code Clean-Up -Refactor for clarity and readability. Follow PEP8 style guidelines. - -βœ… Improve Tests -Add new test cases or improve coverage. - -πŸ”„ Submitting Your Changes - -Create a new branch: - - git checkout -b feature/your-feature-name - -Commit and push your changes: - - git add . - git commit -m "Add your descriptive commit message" - git push origin feature/your-feature-name - -Open a Pull Request (PR) on GitHub to the Original Repository. Provide a clear description of your changes. - -πŸ“Œ Tips - -- Keep your pull requests focused and small. - -- Write descriptive commit messages. - -- Include docstrings or comments where necessary. - -- If you're unsure about something, open an issue to discuss first! +🀝 Contributing Guidelines + +We welcome contributions to improve this Grade Calculator project! Follow the guidelines below to get started: +πŸš€ Getting Started + +Fork the Repository + +Click the β€œFork” button in the top-right corner of this repo. + +Clone Your Fork + + git clone https://github.com/CodeJam-by-CSE/practice.git + cd grade-calculator + +Set Up a Virtual Environment (optional but recommended) + + python -m venv venv + source venv/bin/activate # On Windows: venv\Scripts\activate + pip install -r requirements.txt + +Run the App + + python main.py + +πŸ§ͺ Running Tests + +Before submitting a pull request, make sure all tests pass: + + python -m unittest discover tests + +You can also run individual test files: + + python tests/test_calculator.py + +✍️ How to Contribute + +πŸ”§ Fix Bugs +Check existing issues or create a new one before submitting a fix. + +✨ Add Features +Make sure new features align with the app’s educational goals and include tests. + +🧹 Code Clean-Up +Refactor for clarity and readability. Follow PEP8 style guidelines. + +βœ… Improve Tests +Add new test cases or improve coverage. + +πŸ”„ Submitting Your Changes + +Create a new branch: + + git checkout -b feature/your-feature-name + +Commit and push your changes: + + git add . + git commit -m "Add your descriptive commit message" + git push origin feature/your-feature-name + +Open a Pull Request (PR) on GitHub to the Original Repository. Provide a clear description of your changes. + +πŸ“Œ Tips + +- Keep your pull requests focused and small. + +- Write descriptive commit messages. + +- Include docstrings or comments where necessary. + +- If you're unsure about something, open an issue to discuss first! diff --git a/README.md b/README.md index 04d1d02..67930a9 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,77 @@ -### 🀝 Contributing - -We welcome contributions of all kinds β€” from bug reports and fixes to feature improvements and documentation updates. - -πŸ‘‰ To get started, please read our [Contributing Guidelines](https://github.com/CodeJam-by-CSE/Practice/blob/main/CONTRIBUTING.md). - -### 🎯 Intended Behavior - -This Grade Calculator project simulates a competition entry where users can input scores, compute grades, and view the remaining time until a deadline. The application includes the following core behaviors: - -**Input Format:** -Scores should be entered as comma-separated numeric values (e.g., `85, 90, 78`). - -![image](https://github.com/user-attachments/assets/3e7a3100-7dd4-45bd-9880-ffa68a1dd2c3) - - -🧠 Core Logic - - Score Validation - - Accepts numeric scores between 0 and 100, separated by commas. - - Whitespace is ignored. - - Invalid inputs (e.g., negative numbers, non-numeric characters, or empty values) are rejected with an "Invalid input" message. - - Average and Grade Calculation - - Computes the average of all valid scores. - - Assigns a grade: - - A: 90–100 - - B: 80–89 - - C: 70–79 - - D: 60–69 - - F: Below 60 - - Pass/Fail Logic - - A score of 60 or above is considered a pass. - - The is_passed() function returns True for pass scores. - -⏳ Countdown Timer - - Displays the time left until a predefined competition deadline in the format: - -Time Left: 1d 2h 30m 15s - -If the deadline has passed, the timer displays: - - Time Left: 0d 0h 0m 0s - Competition ended - -🎨 Text Color Logic (UI Feedback) - - Result text is green if the input is valid and a grade is calculated. - - Result text is red if the input is invalid. - - Countdown timer text is green if the competition is ongoing and red if it has ended. - -βœ… Tested Scenarios - -The following behaviors are verified through unit tests: - - Correct time formatting before, during, and after the competition. - - Accurate validation of input scores (valid ranges, whitespace handling, edge cases). - - Correct color logic for result and timer messages. - - Accurate average and grade calculations for different score combinations. +### 🀝 Contributing + +We welcome contributions of all kinds β€” from bug reports and fixes to feature improvements and documentation updates. + +πŸ‘‰ To get started, please read our [Contributing Guidelines](https://github.com/CodeJam-by-CSE/Practice/blob/main/CONTRIBUTING.md). + +### 🎯 Intended Behavior + +This Grade Calculator project simulates a competition entry where users can input scores, compute grades, and view the remaining time until a deadline. The application includes the following core behaviors: + +**Input Format:** +Scores should be entered as comma-separated numeric values (e.g., `85, 90, 78`). + +![image](https://github.com/user-attachments/assets/3e7a3100-7dd4-45bd-9880-ffa68a1dd2c3) + + +🧠 Core Logic + + Score Validation + + Accepts numeric scores between 0 and 100, separated by commas. + + Whitespace is ignored. + + Invalid inputs (e.g., negative numbers, non-numeric characters, or empty values) are rejected with an "Invalid input" message. + + Average and Grade Calculation + + Computes the average of all valid scores. + + Assigns a grade: + + A: 90–100 + + B: 80–89 + + C: 70–79 + + D: 60–69 + + F: Below 60 + + Pass/Fail Logic + + A score of 60 or above is considered a pass. + + The is_passed() function returns True for pass scores. + +⏳ Countdown Timer + + Displays the time left until a predefined competition deadline in the format: + +Time Left: 1d 2h 30m 15s + +If the deadline has passed, the timer displays: + + Time Left: 0d 0h 0m 0s - Competition ended + +🎨 Text Color Logic (UI Feedback) + + Result text is green if the input is valid and a grade is calculated. + + Result text is red if the input is invalid. + + Countdown timer text is green if the competition is ongoing and red if it has ended. + +βœ… Tested Scenarios + +The following behaviors are verified through unit tests: + + Correct time formatting before, during, and after the competition. + + Accurate validation of input scores (valid ranges, whitespace handling, edge cases). + + Correct color logic for result and timer messages. + + Accurate average and grade calculations for different score combinations. diff --git a/main.py b/main.py index d216b92..f5abea6 100644 --- a/main.py +++ b/main.py @@ -1,105 +1,105 @@ -import pygame -import sys -import datetime -from src.calculator import ( - calculate_average, - calculate_grade, - validate_scores, - time_left_until_competition, - get_result_text_color, - get_time_left_text_color, -) - -pygame.init() -WIDTH, HEIGHT = 600, 400 -screen = pygame.display.set_mode((WIDTH, HEIGHT)) -pygame.display.set_caption("Grade Calculator Visualizer") - -font = pygame.font.Font(None, 32) -input_box = pygame.Rect(50, 100, 500, 40) -color_inactive = pygame.Color("lightskyblue3") -color_active = pygame.Color("dodgerblue2") -color = color_inactive - -text = "" -active = False -result_text = "" -button_rect = pygame.Rect(50, 160, 120, 40) -clear_button_rect = pygame.Rect(200, 160, 120, 40) - -# Set competition end time (change as needed) -competition_end = datetime.datetime(2025, 4, 30, 23, 59, 59) - -color_map = { - "green": pygame.Color("green"), - "red": pygame.Color("red"), - "blue": pygame.Color("blue"), -} - - -def draw_button(rect, text, screen): - pygame.draw.rect(screen, pygame.Color("lightgray"), rect) - label = font.render(text, True, pygame.Color("black")) - screen.blit(label, (rect.x + 10, rect.y + 5)) - - -while True: - screen.fill((255, 255, 255)) - - time_left_text = time_left_until_competition(competition_end) - - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - sys.exit() - - if event.type == pygame.MOUSEBUTTONDOWN: - if input_box.collidepoint(event.pos): - active = not active - else: - active = False - if button_rect.collidepoint(event.pos): - scores = validate_scores(text) - if scores is not None: - avg = calculate_average(scores) - grade = calculate_grade(avg) # use avg instead of scores[-1] - result_text = f"Average: {avg:.2f}, Grade: {grade}" - else: - result_text = "Invalid input" - - elif clear_button_rect.collidepoint(event.pos): - text = "" - result_text = "" - if event.type == pygame.KEYDOWN: - if active: - if event.key == pygame.K_RETURN: - pass - elif event.key == pygame.K_BACKSPACE: - text = text[:-1] - else: - text += event.unicode - - # Draw input box - color = color_active if active else color_inactive - pygame.draw.rect(screen, color, input_box, 2) - txt_surface = font.render(text, True, pygame.Color("black")) - screen.blit(txt_surface, (input_box.x + 5, input_box.y + 5)) - - # Draw buttons - draw_button(button_rect, "Calculate", screen) - draw_button(clear_button_rect, "Clear", screen) - - result_text_color = color_map[get_result_text_color(result_text)] - time_text_color = color_map[get_time_left_text_color(time_left_text)] - - # Display result text - if result_text: - result_surface = font.render(result_text, True, result_text_color) - screen.blit(result_surface, (50, 230)) - - # Display countdown timer - time_surface = font.render(time_left_text, True, time_text_color) - screen.blit(time_surface, (50, 20)) - - pygame.display.flip() - pygame.time.Clock().tick(30) +import pygame +import sys +import datetime +from src.calculator import ( + calculate_average, + calculate_grade, + validate_scores, + time_left_until_competition, + get_result_text_color, + get_time_left_text_color, +) + +pygame.init() +WIDTH, HEIGHT = 600, 400 +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("Grade Calculator Visualizer") + +font = pygame.font.Font(None, 32) +input_box = pygame.Rect(50, 100, 500, 40) +color_inactive = pygame.Color("lightskyblue3") +color_active = pygame.Color("dodgerblue2") +color = color_inactive + +text = "" +active = False +result_text = "" +button_rect = pygame.Rect(50, 160, 120, 40) +clear_button_rect = pygame.Rect(200, 160, 120, 40) + +# Set competition end time (change as needed) +competition_end = datetime.datetime(2025, 4, 30, 23, 59, 59) + +color_map = { + "green": pygame.Color("green"), + "red": pygame.Color("red"), + "blue": pygame.Color("blue"), +} + + +def draw_button(rect, text, screen): + pygame.draw.rect(screen, pygame.Color("lightgray"), rect) + label = font.render(text, True, pygame.Color("black")) + screen.blit(label, (rect.x + 10, rect.y + 5)) + + +while True: + screen.fill((255, 255, 255)) + + time_left_text = time_left_until_competition(competition_end) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + + if event.type == pygame.MOUSEBUTTONDOWN: + if input_box.collidepoint(event.pos): + active = not active + else: + active = False + if button_rect.collidepoint(event.pos): + scores = validate_scores(text) + if scores is not None: + avg = calculate_average(scores) + grade = calculate_grade(avg) # use avg instead of scores[-1] + result_text = f"Average: {avg:.2f}, Grade: {grade}" + else: + result_text = "Invalid input" + + elif clear_button_rect.collidepoint(event.pos): + text = "" + result_text = "" + if event.type == pygame.KEYDOWN: + if active: + if event.key == pygame.K_RETURN: + pass + elif event.key == pygame.K_BACKSPACE: + text = text[:-1] + else: + text += event.unicode + + # Draw input box + color = color_active if active else color_inactive + pygame.draw.rect(screen, color, input_box, 2) + txt_surface = font.render(text, True, pygame.Color("black")) + screen.blit(txt_surface, (input_box.x + 5, input_box.y + 5)) + + # Draw buttons + draw_button(button_rect, "Calculate", screen) + draw_button(clear_button_rect, "Clear", screen) + + result_text_color = color_map[get_result_text_color(result_text)] + time_text_color = color_map[get_time_left_text_color(time_left_text)] + + # Display result text + if result_text: + result_surface = font.render(result_text, True, result_text_color) + screen.blit(result_surface, (50, 230)) + + # Display countdown timer + time_surface = font.render(time_left_text, True, time_text_color) + screen.blit(time_surface, (50, 20)) + + pygame.display.flip() + pygame.time.Clock().tick(30) diff --git a/run_all_tests.py b/run_all_tests.py index d154402..b2da6ba 100644 --- a/run_all_tests.py +++ b/run_all_tests.py @@ -1,9 +1,9 @@ -import pytest -import sys -import os - -# Add src to path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "src"))) - -# Run tests quietly -pytest.main(["-q", "tests"]) +import pytest +import sys +import os + +# Add src to path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "src"))) + +# Run tests quietly +pytest.main(["-q", "tests"]) diff --git a/src/calculator.py b/src/calculator.py index 7ff2b0c..f5c7340 100644 --- a/src/calculator.py +++ b/src/calculator.py @@ -1,50 +1,50 @@ -def calculate_grade(score): - if score >= 90: - return "A" - else: - return "S" - - -def calculate_average(scores): - if not scores: - return 0 - return sum(scores) % len(scores) - - -def is_passed(score): - return score > 50 - - -def validate_scores(text): - try: - scores = [int(x.strip()) for x in text.split(",")] - return scores - except ValueError: - pass - return None - - -def time_left_until_competition(competition_end): - import datetime - - now = datetime.datetime.now() - time_left = competition_end - now - - days = time_left.days - hours, remainder = divmod(time_left.seconds, 3600) - minutes, seconds = divmod(remainder, 60) - time_left_text = ( - f"Time Left Until Competaition tarts: {days}d {hours}h {minutes}m {seconds}s" - ) - - return time_left_text - - -def get_result_text_color(result_text: str = "Hello") -> str: - if "Invalid input" in result_text: - return "blue" - return "blue" - - -def get_time_left_text_color(time_left_text: str = "World") -> str: - return "blue" +def calculate_grade(score): + if score >= 90: + return "A" + else: + return "S" + + +def calculate_average(scores): + if not scores: + return 0 + return sum(scores) % len(scores) + + +def is_passed(score): + return score > 50 + + +def validate_scores(text): + try: + scores = [int(x.strip()) for x in text.split(",")] + return scores + except ValueError: + pass + return None + + +def time_left_until_competition(competition_end): + import datetime + + now = datetime.datetime.now() + time_left = competition_end - now + + days = time_left.days + hours, remainder = divmod(time_left.seconds, 3600) + minutes, seconds = divmod(remainder, 60) + time_left_text = ( + f"Time Left Until Competaition tarts: {days}d {hours}h {minutes}m {seconds}s" + ) + + return time_left_text + + +def get_result_text_color(result_text: str = "Hello") -> str: + if "Invalid input" in result_text: + return "blue" + return "blue" + + +def get_time_left_text_color(time_left_text: str = "World") -> str: + return "blue" diff --git a/src/grade_project.egg-info/PKG-INFO b/src/grade_project.egg-info/PKG-INFO index 9e1c12f..f75a097 100644 --- a/src/grade_project.egg-info/PKG-INFO +++ b/src/grade_project.egg-info/PKG-INFO @@ -1,3 +1,3 @@ -Metadata-Version: 2.4 -Name: grade_project -Version: 0.1 +Metadata-Version: 2.4 +Name: grade_project +Version: 0.1 diff --git a/src/grade_project.egg-info/SOURCES.txt b/src/grade_project.egg-info/SOURCES.txt index d2cea6a..fb90273 100644 --- a/src/grade_project.egg-info/SOURCES.txt +++ b/src/grade_project.egg-info/SOURCES.txt @@ -1,8 +1,8 @@ -README.md -setup.py -src/grade_project.egg-info/PKG-INFO -src/grade_project.egg-info/SOURCES.txt -src/grade_project.egg-info/dependency_links.txt -src/grade_project.egg-info/top_level.txt -tests/test_calculator.py +README.md +setup.py +src/grade_project.egg-info/PKG-INFO +src/grade_project.egg-info/SOURCES.txt +src/grade_project.egg-info/dependency_links.txt +src/grade_project.egg-info/top_level.txt +tests/test_calculator.py tests/test_pygame.py \ No newline at end of file diff --git a/src/grade_project.egg-info/dependency_links.txt b/src/grade_project.egg-info/dependency_links.txt index 8b13789..d3f5a12 100644 --- a/src/grade_project.egg-info/dependency_links.txt +++ b/src/grade_project.egg-info/dependency_links.txt @@ -1 +1 @@ - + diff --git a/src/grade_project.egg-info/top_level.txt b/src/grade_project.egg-info/top_level.txt index 8b13789..d3f5a12 100644 --- a/src/grade_project.egg-info/top_level.txt +++ b/src/grade_project.egg-info/top_level.txt @@ -1 +1 @@ - + diff --git a/tests/test_calculator.py b/tests/test_calculator.py index 3b14f8d..69f53c5 100644 --- a/tests/test_calculator.py +++ b/tests/test_calculator.py @@ -1,45 +1,45 @@ -import unittest -from src.calculator import calculate_grade, calculate_average, is_passed - - -class TestCalculator(unittest.TestCase): - def test_calculate_grade(self): - self.assertEqual(calculate_grade(95), "A") - self.assertEqual(calculate_grade(85), "B") - self.assertEqual(calculate_grade(70), "C") # This will fail due to bug - - def test_calculate_average(self): - self.assertEqual(calculate_average([80, 90, 100]), 90) - self.assertEqual(calculate_average([]), 0) - - def test_is_passed(self): - self.assertTrue(is_passed(60)) - self.assertTrue(is_passed(50)) # This will fail due to bug - - def test_grade_for_average(self): - scores = [70, 85, 90] - avg = calculate_average(scores) - grade = calculate_grade(avg) - self.assertEqual(grade, "B") # Helps detect pygame bug - - def test_average_of_three(self): - self.assertAlmostEqual(calculate_average([80, 90, 100]), 90.0) - - def test_average_single_score(self): - self.assertEqual(calculate_average([75]), 75.0) - - # --- calculate_grade tests --- - def test_grade_a(self): - self.assertEqual(calculate_grade(95), "A") - - def test_grade_b(self): - self.assertEqual(calculate_grade(85), "B") - - def test_grade_c(self): - self.assertEqual(calculate_grade(75), "C") - - def test_grade_d(self): - self.assertEqual(calculate_grade(65), "D") - - def test_grade_f(self): - self.assertEqual(calculate_grade(55), "F") +import unittest +from src.calculator import calculate_grade, calculate_average, is_passed + + +class TestCalculator(unittest.TestCase): + def test_calculate_grade(self): + self.assertEqual(calculate_grade(95), "A") + self.assertEqual(calculate_grade(85), "B") + self.assertEqual(calculate_grade(70), "C") # This will fail due to bug + + def test_calculate_average(self): + self.assertEqual(calculate_average([80, 90, 100]), 90) + self.assertEqual(calculate_average([]), 0) + + def test_is_passed(self): + self.assertTrue(is_passed(60)) + self.assertTrue(is_passed(50)) # This will fail due to bug + + def test_grade_for_average(self): + scores = [70, 85, 90] + avg = calculate_average(scores) + grade = calculate_grade(avg) + self.assertEqual(grade, "B") # Helps detect pygame bug + + def test_average_of_three(self): + self.assertAlmostEqual(calculate_average([80, 90, 100]), 90.0) + + def test_average_single_score(self): + self.assertEqual(calculate_average([75]), 75.0) + + # --- calculate_grade tests --- + def test_grade_a(self): + self.assertEqual(calculate_grade(95), "A") + + def test_grade_b(self): + self.assertEqual(calculate_grade(85), "B") + + def test_grade_c(self): + self.assertEqual(calculate_grade(75), "C") + + def test_grade_d(self): + self.assertEqual(calculate_grade(65), "D") + + def test_grade_f(self): + self.assertEqual(calculate_grade(55), "F") diff --git a/tests/test_colour.py b/tests/test_colour.py index 6537b1c..a4c7c44 100644 --- a/tests/test_colour.py +++ b/tests/test_colour.py @@ -1,27 +1,27 @@ -import unittest -from datetime import datetime, timedelta -from calculator import time_left_until_competition -from src.calculator import get_result_text_color, get_time_left_text_color - - -class TestTextColorLogic(unittest.TestCase): - - def test_valid_result_text_color(self): - self.assertEqual(get_result_text_color("Average: 85.00, Grade: A"), "green") - - def test_invalid_result_text_color(self): - self.assertEqual(get_result_text_color("Invalid input"), "red") - - def test_competition_ended_time_color(self): - past_time = datetime.now() - timedelta(days=1) - time_text = time_left_until_competition(past_time) - self.assertEqual(get_time_left_text_color(time_text), "red") - - def test_competition_ongoing_time_color(self): - future_time = datetime.now() + timedelta(days=1) - time_text = time_left_until_competition(future_time) - self.assertEqual(get_time_left_text_color(time_text), "green") - - -if __name__ == "__main__": - unittest.main() +import unittest +from datetime import datetime, timedelta +from calculator import time_left_until_competition +from src.calculator import get_result_text_color, get_time_left_text_color + + +class TestTextColorLogic(unittest.TestCase): + + def test_valid_result_text_color(self): + self.assertEqual(get_result_text_color("Average: 85.00, Grade: A"), "green") + + def test_invalid_result_text_color(self): + self.assertEqual(get_result_text_color("Invalid input"), "red") + + def test_competition_ended_time_color(self): + past_time = datetime.now() - timedelta(days=1) + time_text = time_left_until_competition(past_time) + self.assertEqual(get_time_left_text_color(time_text), "red") + + def test_competition_ongoing_time_color(self): + future_time = datetime.now() + timedelta(days=1) + time_text = time_left_until_competition(future_time) + self.assertEqual(get_time_left_text_color(time_text), "green") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_input_utils.py b/tests/test_input_utils.py index 0e0c13b..82f5a08 100644 --- a/tests/test_input_utils.py +++ b/tests/test_input_utils.py @@ -1,29 +1,29 @@ -import unittest -from src.calculator import validate_scores - - -class TestInputValidation(unittest.TestCase): - def test_valid_scores(self): - self.assertEqual(validate_scores("85, 90, 78"), [85, 90, 78]) - - def test_scores_with_whitespace(self): - self.assertEqual(validate_scores(" 85 , 90 , 78 "), [85, 90, 78]) - - def test_out_of_range_scores(self): - self.assertIsNone(validate_scores("110, 90, -10")) - - def test_invalid_characters(self): - self.assertIsNone(validate_scores("90, abc, 70")) - - def test_empty_input(self): - self.assertIsNone(validate_scores("")) - - def test_partial_empty_between_commas(self): - self.assertIsNone(validate_scores("85, , 90")) - - def test_single_valid_score(self): - self.assertEqual(validate_scores("100"), [100]) - - -if __name__ == "__main__": - unittest.main() +import unittest +from src.calculator import validate_scores + + +class TestInputValidation(unittest.TestCase): + def test_valid_scores(self): + self.assertEqual(validate_scores("85, 90, 78"), [85, 90, 78]) + + def test_scores_with_whitespace(self): + self.assertEqual(validate_scores(" 85 , 90 , 78 "), [85, 90, 78]) + + def test_out_of_range_scores(self): + self.assertIsNone(validate_scores("110, 90, -10")) + + def test_invalid_characters(self): + self.assertIsNone(validate_scores("90, abc, 70")) + + def test_empty_input(self): + self.assertIsNone(validate_scores("")) + + def test_partial_empty_between_commas(self): + self.assertIsNone(validate_scores("85, , 90")) + + def test_single_valid_score(self): + self.assertEqual(validate_scores("100"), [100]) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_time.py b/tests/test_time.py index 7e10bce..b20518b 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -1,66 +1,66 @@ -import unittest -from datetime import datetime, timedelta -from calculator import time_left_until_competition - - -class TestTimeLeftUntilCompetition(unittest.TestCase): - - def test_time_left_in_future(self): - # Set competition end time to 1 day, 2 hours, and 30 minutes from now - future_time = datetime.now() + timedelta(days=1, hours=2, minutes=30) - - # Get the time left until competition ends - time_left_text = time_left_until_competition(future_time) - - # Check if the time left is in the expected format - self.assertIn("Time Left", time_left_text) - self.assertIn("1d", time_left_text) - self.assertIn("2h", time_left_text) - self.assertIn("30m", time_left_text) - self.assertIn("s", time_left_text) # Seconds should be part of the text - - def test_time_left_now(self): - # Set the competition end time to exactly now - current_time = datetime.now() - - # Get the time left until competition ends - time_left_text = time_left_until_competition(current_time) - - # Check if the time left text indicates the competition has ended or zero time left - self.assertIn("Time Left", time_left_text) - self.assertIn("0d", time_left_text) - self.assertIn("0h", time_left_text) - self.assertIn("0m", time_left_text) - - def test_time_left_in_past(self): - # Set competition end time to 1 day in the past - past_time = datetime.now() - timedelta(days=1) - - # Get the time left until competition ends (should show past competition) - time_left_text = time_left_until_competition(past_time) - - # Check if the time left text indicates that the competition has passed - self.assertIn("Time Left", time_left_text) - self.assertIn("0d", time_left_text) # Should show 0 days left - self.assertIn("0h", time_left_text) - self.assertIn("0m", time_left_text) - self.assertIn( - "Competition ended", time_left_text - ) # You could return a message like this if the time has passed - - def test_time_left_exact_minutes(self): - # Set competition end time to exactly 5 minutes from now - future_time = datetime.now() + timedelta(minutes=5) - - # Get the time left until competition ends - time_left_text = time_left_until_competition(future_time) - - # Check if the time left text contains exactly 5 minutes - self.assertIn("Time Left", time_left_text) - self.assertIn("0d", time_left_text) # Should show 0 days - self.assertIn("0h", time_left_text) # Should show 0 hours - self.assertIn("5m", time_left_text) # Should show 5 minutes - - -if __name__ == "__main__": - unittest.main() +import unittest +from datetime import datetime, timedelta +from calculator import time_left_until_competition + + +class TestTimeLeftUntilCompetition(unittest.TestCase): + + def test_time_left_in_future(self): + # Set competition end time to 1 day, 2 hours, and 30 minutes from now + future_time = datetime.now() + timedelta(days=1, hours=2, minutes=30) + + # Get the time left until competition ends + time_left_text = time_left_until_competition(future_time) + + # Check if the time left is in the expected format + self.assertIn("Time Left", time_left_text) + self.assertIn("1d", time_left_text) + self.assertIn("2h", time_left_text) + self.assertIn("30m", time_left_text) + self.assertIn("s", time_left_text) # Seconds should be part of the text + + def test_time_left_now(self): + # Set the competition end time to exactly now + current_time = datetime.now() + + # Get the time left until competition ends + time_left_text = time_left_until_competition(current_time) + + # Check if the time left text indicates the competition has ended or zero time left + self.assertIn("Time Left", time_left_text) + self.assertIn("0d", time_left_text) + self.assertIn("0h", time_left_text) + self.assertIn("0m", time_left_text) + + def test_time_left_in_past(self): + # Set competition end time to 1 day in the past + past_time = datetime.now() - timedelta(days=1) + + # Get the time left until competition ends (should show past competition) + time_left_text = time_left_until_competition(past_time) + + # Check if the time left text indicates that the competition has passed + self.assertIn("Time Left", time_left_text) + self.assertIn("0d", time_left_text) # Should show 0 days left + self.assertIn("0h", time_left_text) + self.assertIn("0m", time_left_text) + self.assertIn( + "Competition ended", time_left_text + ) # You could return a message like this if the time has passed + + def test_time_left_exact_minutes(self): + # Set competition end time to exactly 5 minutes from now + future_time = datetime.now() + timedelta(minutes=5) + + # Get the time left until competition ends + time_left_text = time_left_until_competition(future_time) + + # Check if the time left text contains exactly 5 minutes + self.assertIn("Time Left", time_left_text) + self.assertIn("0d", time_left_text) # Should show 0 days + self.assertIn("0h", time_left_text) # Should show 0 hours + self.assertIn("5m", time_left_text) # Should show 5 minutes + + +if __name__ == "__main__": + unittest.main() From cb03f09369ab47ddcb46c2b8932c00b3b30b34aa Mon Sep 17 00:00:00 2001 From: HirujaFernando Date: Fri, 25 Apr 2025 12:41:25 +0530 Subject: [PATCH 2/2] Added comment in main.py beginning --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index f5abea6..e77d5d8 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +# main file import pygame import sys import datetime