#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
The cat module allows to create a Cat or a group of Cats (i.e. a Clowder)
"""
from ..utils import noises
import difflib
[docs]
class Cat:
"""
Represents a virtual cat with attributes like name, age, color, mood, hunger, energy, and health.
Parameters
----------
name : str
The name of the cat.
age : int, optional
The age of the cat in years. Default is None.
color : str, optional
Coat color of the cat. Acceptable values are:
'tabby', 'black', 'orange', 'tortoiseshell', and 'tuxedo'.
Fuzzy matching is used to interpret close inputs. Default is None.
mood : int, optional
Mood level on a scale from -10 (grumpy) to 10 (ecstatic). Default is 0.
hunger_level : int, optional
Hunger level of the cat. Higher values indicate greater hunger. Default is 0.
energy : int, optional
Energy level of the cat. Default is 0.
health : int, optional
Health level of the cat. Default is 0.
Attributes
----------
name : str
The name of the cat.
age : int or None
The age of the cat.
color : str or None
The interpreted or validated color of the cat.
mood : int
The cat's mood.
hunger_level : int
The cat's hunger level.
energy : int
The cat's energy level.
health : int
The cat's health level.
Examples
--------
.. jupyter-execute::
import pyCatSim as cats
nutmeg = cats.Cat(name='Nutmeg', age = 3, color = 'tortoiseshell')
"""
def __init__(self, name, age=None, color=None, mood=0, hunger_level=0,
energy=0, health=0):
self.name = name
self.age = age
possible_colors = ['tabby', 'black', 'orange', 'tortoiseshell', 'tuxedo']
if color:
color_normalized = color.lower().strip()
match = difflib.get_close_matches(color_normalized, possible_colors, n=1, cutoff=0.6)
if match:
self.color = match[0]
print(f"Color '{color}' interpreted as '{self.color}'.")
else:
print(f"Invalid color '{color}'. Valid options are: {', '.join(possible_colors)}.")
self.color = None
self.mood = mood
self.hunger_level = hunger_level
self.energy = energy
self.health = health
[docs]
def make_noise(self, noise='meow', play=False):
"""
Parameters
----------
noise : string, optional
The sound the cat makes. Valid options include "meow", "purr". The default is 'meow'.
play : bool, optional
Whether to play the sound (True) or print out the sound (False). The default is False.
Raises
------
ValueError
Raises an error if the sound is not valid
Returns
-------
str
The sound
See also
--------
pyCatSim.utils.noises.meow: Simulates a cat meow
pyCatSim.utils.noises.purr: Simulates a cat purr
Examples
--------
.. jupyter-execute::
import pyCatSim as cats
nutmeg = cats.Cat(name='Nutmeg', age = 3, color = 'tortoiseshell')
nutmeg.make_noise()
"""
noise_func ={
'meow':noises.meow,
'purr':noises.purr}
if noise in noise_func.keys():
return noise_func[noise](play=play)
else:
raise ValueError(f"Invalid noise '{noise}'. Valid options: {', '.join(noise_func.keys())}")
[docs]
def play(self, mood_boost=1, hunger_boost=1, energy_boost=-1):
"""
Simulates playtime with the cat.
Parameters
----------
mood_boost : int, optional
How much mood improves from play. Must be an integer. Default is 1.
hunger_boost : int, optional
How much hunger increases from play. Must be a positive integer. Default is 1.
energy_boost : int, optional
How much energy decreases from play. Must be a negative integer. Default is -1.
Raises
------
TypeError
If any of the arguments are not integers.
ValueError
If hunger_boost is not positive or energy_boost is not negative.
Examples
--------
.. jupyter-execute::
import pyCatSim as cats
nutmeg = cats.Cat(name='Nutmeg', age = 3, color = 'tortoiseshell')
nutmeg.play()
"""
for arg_name, arg_value in {
"mood_boost": mood_boost,
"hunger_boost": hunger_boost,
"energy_boost": energy_boost
}.items():
if not isinstance(arg_value, int):
raise TypeError(f"{arg_name} must be an integer.")
if hunger_boost <= 0:
raise ValueError("Cats always get hungry when playing! hunger_boost must be positive.")
if energy_boost >= 0:
raise ValueError("Cats always get tired when playing! energy_boost must be negative.")
self.mood += mood_boost
self.hunger_level += hunger_boost
self.energy += energy_boost