more cool stuff
chess, woah
This commit is contained in:
43
book_stuff/student.py
Normal file
43
book_stuff/student.py
Normal file
@@ -0,0 +1,43 @@
|
||||
class Student:
|
||||
def __init__(self, name: str, gNumber: int, gpa: float):
|
||||
self.set_name(name)
|
||||
self.set_gNumber(gNumber)
|
||||
self.set_gpa(gpa)
|
||||
|
||||
# --- Name ---
|
||||
def get_name(self) -> str:
|
||||
return self._name
|
||||
|
||||
def set_name(self, value: str) -> None:
|
||||
if not isinstance(value, str):
|
||||
raise TypeError("Name must be a string")
|
||||
if not value.isalpha():
|
||||
raise ValueError("Name must contain only alphabetic characters")
|
||||
if not (1 <= len(value) <= 255):
|
||||
raise ValueError("Name must be between 1 and 255 characters")
|
||||
self._name = value
|
||||
|
||||
# --- gNumber ---
|
||||
def get_gNumber(self) -> int:
|
||||
return self._gNumber
|
||||
|
||||
def set_gNumber(self, value: int) -> None:
|
||||
if not isinstance(value, int):
|
||||
raise TypeError("gNumber must be an integer")
|
||||
if not (100000 <= value <= 999999):
|
||||
raise ValueError("gNumber must be a 6-digit number between 100000 and 999999")
|
||||
self._gNumber = value
|
||||
|
||||
# --- GPA ---
|
||||
def get_gpa(self) -> float:
|
||||
return self._gpa
|
||||
|
||||
def set_gpa(self, value: float) -> None:
|
||||
if not isinstance(value, (int, float)):
|
||||
raise TypeError("GPA must be a number")
|
||||
if not (0.0 <= value <= 6.0):
|
||||
raise ValueError("GPA must be between 0.0 and 6.0")
|
||||
self._gpa = float(value)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Student(Name: {self._name}, gNumber: {self._gNumber}, GPA: {self._gpa:.2f})"
|
||||
90
book_stuff/test_student.py
Normal file
90
book_stuff/test_student.py
Normal file
@@ -0,0 +1,90 @@
|
||||
import pytest
|
||||
from student import Student # assumes Student class is in student.py
|
||||
|
||||
|
||||
# ---------- FIXTURES ----------
|
||||
@pytest.fixture
|
||||
def valid_student():
|
||||
"""Fixture for a valid student object"""
|
||||
return Student("Alice", 123456, 4.0)
|
||||
|
||||
def test_create_valid_student(valid_student):
|
||||
assert valid_student.get_name() == "Alice"
|
||||
assert valid_student.get_gNumber() == 123456
|
||||
assert valid_student.get_gpa() == 4.0
|
||||
|
||||
|
||||
def test_update_name(valid_student):
|
||||
valid_student.set_name("Bob")
|
||||
assert valid_student.get_name() == "Bob"
|
||||
|
||||
|
||||
def test_update_gNumber(valid_student):
|
||||
valid_student.set_gNumber(654321)
|
||||
assert valid_student.get_gNumber() == 654321
|
||||
|
||||
|
||||
def test_update_gpa(valid_student):
|
||||
valid_student.set_gpa(5.5)
|
||||
assert valid_student.get_gpa() == 5.5
|
||||
|
||||
|
||||
# ---------- NAME VALIDATION ----------
|
||||
@pytest.mark.parametrize("invalid_name", [
|
||||
"", # empty string
|
||||
"A" * 256, # too long
|
||||
"Alice123", # contains digits
|
||||
"Alice!", # contains special character
|
||||
123, # not a string
|
||||
])
|
||||
def test_invalid_name_raises(invalid_name):
|
||||
with pytest.raises((ValueError, TypeError)):
|
||||
Student(invalid_name, 123456, 3.0)
|
||||
|
||||
|
||||
# ---------- gNumber VALIDATION ----------
|
||||
@pytest.mark.parametrize("invalid_gNumber", [
|
||||
99999, # too small
|
||||
1000000, # too large
|
||||
"123456", # not an int
|
||||
12.34, # float
|
||||
])
|
||||
def test_invalid_gNumber_raises(invalid_gNumber):
|
||||
with pytest.raises((ValueError, TypeError)):
|
||||
Student("Charlie", invalid_gNumber, 3.5)
|
||||
|
||||
|
||||
def test_boundary_gNumber_valid():
|
||||
s1 = Student("David", 100000, 2.0)
|
||||
s2 = Student("Eve", 999999, 3.0)
|
||||
assert s1.get_gNumber() == 100000
|
||||
assert s2.get_gNumber() == 999999
|
||||
|
||||
|
||||
# ---------- GPA VALIDATION ----------
|
||||
@pytest.mark.parametrize("invalid_gpa", [
|
||||
-0.1, # below range
|
||||
6.1, # above range
|
||||
"4.0", # string instead of number
|
||||
None, # NoneType
|
||||
])
|
||||
def test_invalid_gpa_raises(invalid_gpa):
|
||||
with pytest.raises((ValueError, TypeError)):
|
||||
Student("Frank", 222222, invalid_gpa)
|
||||
|
||||
|
||||
def test_boundary_gpa_valid():
|
||||
s1 = Student("Grace", 333333, 0.0)
|
||||
s2 = Student("Heidi", 444444, 6.0)
|
||||
assert s1.get_gpa() == 0.0
|
||||
assert s2.get_gpa() == 6.0
|
||||
|
||||
|
||||
# ---------- STRING REPRESENTATION ----------
|
||||
def test_str_representation(valid_student):
|
||||
s = str(valid_student)
|
||||
assert "Alice" in s
|
||||
assert "123456" in s
|
||||
assert "4.00" in s
|
||||
|
||||
|
||||
Reference in New Issue
Block a user