cochar package

cochar.cochar module

Cochar - main module

cochar.cochar.calc_build(strength: int, size: int) int

Return build based on sum od strength and size.

f: X -> Y

X: {64, 84, 124, 164, 204, 283, 364, 444, 524} Y: {-2, -1, 0, 1, 2, 3, 4, 5, 6}

TODO: Increase bonus damage for +1K6 for every 80 points above 524

Parameters:
  • strength (int) – character’s strength

  • size (int) – character’s size

Returns:

character’s build

Return type:

int

cochar.cochar.calc_combat_characteristics(strength: int, size: int, dexterity: int, damage_bonus: str = '', build: int = 0, dodge: int = 0) Tuple[str, int, int]

Based on strength, size and dexterity, return combat characteristics such as: dame bonus, build, dodge

Parameters:
  • strength (int) – strength points

  • size (int) – size points

  • dexterity (int) – dexterity points

Returns:

(damage bonus, build, dodge)

Return type:

Tuple(str, int, int)

cochar.cochar.calc_damage_bonus(strength: int, size: int) str

Return damage bonus, based on sum of strength and size.

f: X -> Y

X: {64, 84, 124, 164, 204, 283, 364, 444, 524} Y: {“-2”, “-1”, “0”, “+1K4”, “+1K6”, “+2K6”, “+3K6”, “+4K6”, “+5K6”,}

TODO: Increase bonus damage for +1K6 for every 80 points above 524

Parameters:
  • strength (int) – character’s strength

  • size (int) – character’s size

Returns:

character’s damage bonus

Return type:

str

cochar.cochar.calc_derived_attributes(power: int, size: int, condition: int, sanity_points: int = 0, magic_points: int = 0, hit_points: int = 0) Tuple[int, int, int]

Based on power, size and condition, return sanity, magic and hit points

Parameters:
  • power (int) – power points

  • size (int) – size points

  • condition (int) – condition points

  • sanity_points (int, optional) – sanity points, defaults to 0

  • magic_points (int, optional) – magic points, defaults to 0

  • hit_points (int, optional) – hit points, defaults to 0

Returns:

(sanity points, magic points, hit points)

Return type:

tuple

cochar.cochar.calc_dodge(dexterity: int) int

Return dodge based on dexterity:

dodge = dexterity // 2

Parameters:

dexterity (int) – character’s dexterity

Returns:

character’s dodge

Return type:

int

cochar.cochar.calc_hit_points(size: int, condition: int) int

Return hit points based on size and condition.

Parameters:
  • size (int) – size value

  • condition (int) – condition value

Returns:

hit points

Return type:

int

cochar.cochar.calc_magic_points(power: int) int

Return magic points based on power

Parameters:

power (int) – power value

Returns:

magic points

Return type:

int

cochar.cochar.calc_move_rate(strength: int, dexterity: int, size: int) int

Return move rate base on relations between strength, dexterity and size

if both dexterity and strength are smaller than size, return 7 if both strength and size are higher or equal than size, return 9 else return 8

Parameters:
  • strength (int) – character’s strength

  • dexterity (int) – characters dexterity

  • size (int) – character’s size

Returns:

move rate

Return type:

int

cochar.cochar.calc_sanity_points(power: int) int

Return sanity points based on power

Parameters:

power (int) – power value

Returns:

sanity points

Return type:

int

cochar.cochar.characteristic_test(tested_value: int, repetition: int = 1) int

Perform characteristic test.

Roll number between 1 to 100, If that number is higher than tested value, than increase tested value with random number, between 1 to 10. Repeat repetition times. If result would be higher than 99, return 99

Parameters:
  • tested_value (int) – tested value

  • repetition (int) – how many test to perform

Returns:

unchanged or increased tested value, but not higher than 99

Return type:

int

cochar.cochar.create_character(year: int, country: str, first_name: ~typing.Optional[str] = None, last_name: ~typing.Optional[str] = None, age: ~typing.Optional[int] = None, sex: ~typing.Optional[str] = None, random_mode: bool = False, occupation: ~typing.Optional[str] = None, skills: ~cochar.skill.SkillsDict = {}, occup_type: ~typing.Optional[str] = None, era: ~typing.Optional[str] = None, tags: ~typing.Optional[~typing.List[str]] = None, skills_generator: ~cochar.skill.SkillsGenerator = <cochar.skill.SkillsGenerator object>) Character

Main function for creating Character. Use this function instead of instantiating Character class.

Parameters:
  • year (int) – year of the game

  • country (str) – country of character’s origin

  • first_name (str, optional) – character’s first name, defaults to “”

  • last_name (str, optional) – character’s last name, defaults to “”

  • age (int, optional) – character’s age, defaults to False

  • sex (str, optional) – character’s sex, defaults to False

  • random_mode (bool, optional) – choose occupation completely randomly, regardless the character’s statistics, defaults to “False”

  • occupation (str, optional) – character’s occupation return provided occupation as character’s occupation if it exists, defaults to “None”

  • skills (Skills, optional) – character’s skills, defaults to {}

  • occup_type (str, optional) – occupation type, defaults to None

  • era (str, optional) – occupation era, defaults to None

  • tags (List[str], optional) – occupation tags, defaults to None

Raises:

ValueError – raise if sex is incorrect

Returns:

generated character

Return type:

Character

cochar.cochar.generate_age(year: int, sex: str, age: int = False) int

Generate characters age, based on year and sex. Return age if age is provided.

Parameters:
  • year (int) – year of the game

  • sex (str) – character’s sex

  • age (int, optional) – character’s age, defaults to False

Returns:

character’s age

Return type:

int

cochar.cochar.generate_base_characteristics(age, strength: int = 0, condition: int = 0, size: int = 0, dexterity: int = 0, appearance: int = 0, education: int = 0, intelligence: int = 0, power: int = 0, luck: int = 0, move_rate: int = 0) tuple

Return base characteristics based on age as a tuple.

Base characteristics: 1. strength 2. condition 3. size 4. dexterity 5. appearance 6. education 7. intelligence 8. power 9. luck 10. move rate

Parameters:
  • age (int) – character’s age

  • strength (int, optional) – strength, defaults to 0

  • condition (int, optional) – condition, defaults to 0

  • size (int, optional) – size, defaults to 0

  • dexterity (int, optional) – dexterity, defaults to 0

  • appearance (int, optional) – appearance, defaults to 0

  • education (int, optional) – education, defaults to 0

  • intelligence (int, optional) – intelligence, defaults to 0

  • power (int, optional) – power, defaults to 0

  • move_rate (int, optional) – move rate, defaults to 0

  • luck (int, optional) – luck, defaults to 0

Returns:

(strength, condition, size, dexterity, appearance, education, intelligence, power, luck, move_rate)

Return type:

tuple

cochar.cochar.generate_first_name(year: int, sex: str, country: str, weights: bool) str

Return random first name based on given parameters.

Parameters:
  • year (int) – year of the data set with names (if data set not available use a closes available data set)

  • sex (str) – name gender, available options [‘M’, ‘F’, ‘N’, None]

  • country (str) – name country

  • weights (bool) – if true, take under account popularity of names. [default: True]

Returns:

first name

Return type:

str

cochar.cochar.generate_last_name(year: int, sex: str, country: str, weights: bool) str

Return random last name based on the given parameters

Parameters:
  • year (int) – year of the data set with names (if data set not available use a closes available data set)

  • sex (str) – name gender, available options [‘M’, ‘F’, ‘N’, None]

  • country (str) – name country

  • weights (bool) – If true, take under account popularity of names. [default: True]

Returns:

last name

Return type:

str

cochar.cochar.generate_sex(sex: Optional[Union[str, bool]] = None) str

Generate character’s sex

Parameters:

sex (Union[str, bool]) – Character’s sex, if provided return that value

Raises:

ValueError – If provided sex is not in {“M”, “F”, None}, raise this error

Returns:

Character’s sex as “M” or “F”

Return type:

str

cochar.cochar.subtract_points_from_characteristic(characteristic_points: int, subtract_points: int) int

Subtract points from characteristic points, but if result would be zero or below, than return 1.

Parameters:
  • characteristic_points (int) – _description_

  • subtract_points (int) – _description_

Returns:

_description_

Return type:

int

>>> education = 50
>>> points_to_subtract = 10
>>> subtract_points_from_characteristic(education, points_to_subtract)
40
>>> points_to_subtract = 60
>>> subtract_points_from_characteristic(education, points_to_subtract)
1
cochar.cochar.subtract_points_from_str_con_dex(strength: int, condition: int, dexterity: int, subtract_points: int) Tuple[int, int, int]

Subtract certain amount of points from strength, condition and dexterity, but prevent each of the characteristics to be lower than 1.

Parameters:
  • strength (int) – character’s strength

  • condition (int) – character’s condition

  • dexterity (int) – character’s dexterity

  • subtract_points (int) – amount of points to subtract

Returns:

(strength, condition, dexterity)

Return type:

Tuple[int, int, int]

cochar.character module

“This module contains classes related with Character object itself.

class cochar.character.Age(min_age: int, max_age: int)

Bases: Validator

Character’s age.

Parameters:
  • min_age (int) – minimal character’s age

  • max_age (int) – maximal character’s age

validate(new_age: int) None

Validate character’s age.

Parameters:

new_age (int) – character’s new age

Raises:
class cochar.character.Build

Bases: Validator

Character’s build.

correct_values = [-2, -1, 0, 1, 2, 3, 4, 5, 6]

TODO: increase range. +1 for each 80 point above STR+SIZ.

validate(new_build: int) None

Validate character’s build.

Parameters:

new_build (int) – character’s new build

Raises:

InvalidBuildValue – Invalid build. {new_build} not in {correct_values}

class cochar.character.Character(year: int = 0, country: str = '', first_name: str = '', last_name: str = '', age: int = 0, sex: str = '', occupation: str = '', strength: int = 0, condition: int = 0, size: int = 0, dexterity: int = 0, appearance: int = 0, education: int = 0, intelligence: int = 0, power: int = 0, luck: int = 0, move_rate: int = 0, damage_bonus: str = 0, build: int = 0, dodge: int = 0, skills: SkillsDict = {}, sanity_points: int = 0, magic_points: int = 0, hit_points: int = 0)

Bases: object

Container for character.

age

Character’s age.

Parameters:
  • min_age (int) – minimal character’s age

  • max_age (int) – maximal character’s age

appearance

Base characteristic for character class

build

Character’s build.

correct_values = [-2, -1, 0, 1, 2, 3, 4, 5, 6]

TODO: increase range. +1 for each 80 point above STR+SIZ.

condition

Base characteristic for character class

country

Character’s country.

Country depends on available data. By default database from external randname package is taken. Country also defines what dataset will be used for generating character’s name.

See randname.available_countries().

damage_bonus

Character damage bonus.

correct_values = ['-2', '-1', '0', '+1K4', '+1K6', '+2K6', '+3K6', '+4K6', '+5K6']

dexterity

Base characteristic for character class

dodge

Base characteristic for character class

education

Base characteristic for character class

first_name

Character’s name

get_json_format() dict

Return character’s full characteristics as a dictionary.

Returns:

full characteristics

Return type:

dict

hit_points

Base characteristic for character class

intelligence

Base characteristic for character class

last_name

Character’s name

luck

Base characteristic for character class

magic_points

Base characteristic for character class

move_rate

Base characteristic for character class

occupation

Character’s occupation.

Available occupations are defined in occupation database.

power

Base characteristic for character class

sanity_points

Base characteristic for character class

sex

Character’s sex.

Available sex options: - M: male - F: female - None: for non binary

As there are not any data for non binary names. When None is selected sex will be randomly drawn from M or F

>>> c = Character(year=1925, country="US", sex="F")
>>> c.sex
'F'
size

Base characteristic for character class

property skills: SkillsDict

Character’s skills.

Returns:

character’s skills

Return type:

cochar.skill.Skills

strength

Base characteristic for character class

year

Year in game.

Technically any integer is a valid year. But practically that depends on database with names used to generate names.

Besides name, also character’s age depends on the year. Probability of generating certain year is related with the population age pyramid at the certain year.

Lowest and highest year in the data defines effective range for year. Years below or above are treated the same as in the lowest or highest years in data. That means for example if data for names ends on the year 2010, than setting higher year will give same results as 2010.

class cochar.character.Characteristic(min_value=None)

Bases: Validator

Base characteristic for character class

validate(value: int)

Check if characteristic is a valid number and is not below min_value

Parameters:

value (int) – value to validate

Raises:
class cochar.character.Country

Bases: Validator

Character’s country.

Country depends on available data. By default database from external randname package is taken. Country also defines what dataset will be used for generating character’s name.

See randname.available_countries().

validate(new_country: str) None

Validate character’s country.

Parameters:

new_country (str) – character’s new country

Raises:

InvalidCountryValue – “Country not available: {new_country} -> {randname.available_countries()}

class cochar.character.DamageBonus

Bases: Validator

Character damage bonus.

correct_values = ['-2', '-1', '0', '+1K4', '+1K6', '+2K6', '+3K6', '+4K6', '+5K6']

validate(new_damage_bonus: str) None

Validate character’s damage bonus.

Parameters:

new_damage_bonus (str) – character’s new damage bonus

Raises:

InvalidDamageBonusValue – Invalid damage bonus. {new_damage_bonus} not in {correct_values}

class cochar.character.Name

Bases: Validator

Character’s name

validate(new_name: str)

Check if name is a valid name.

Parameters:

new_name (str) – new character name

Raises:

cochar.error.EmptyName – raise if new_name is empty

class cochar.character.Occupation(available_occupations)

Bases: Validator

Character’s occupation.

Available occupations are defined in occupation database.

validate(new_occupation: str) None

Validate character’s occupation.

Parameters:

new_occupation (str) – character’s new occupation

Raises:

InvalidOccupationValue – raise when new_occupation is not in OCCUPATION_LIST

class cochar.character.Sex

Bases: Validator

Character’s sex.

Available sex options: - M: male - F: female - None: for non binary

As there are not any data for non binary names. When None is selected sex will be randomly drawn from M or F

>>> c = Character(year=1925, country="US", sex="F")
>>> c.sex
'F'
validate(new_sex: Optional[str]) None

Validate character’s sex.

Parameters:

new_sex (str | None) – character’s new sex

Raises:

InvalidSexValue – Incorrect sex value: sex -> [‘M’, ‘F’, None’]

class cochar.character.Validator

Bases: ABC

It’s a parent class for all other descriptors.

Defines validate method, that needs to be implemented by all children.

Parameters:

ABC (ABCMeta) – abstract base class

abstract validate(value)
class cochar.character.Year

Bases: Validator

Year in game.

Technically any integer is a valid year. But practically that depends on database with names used to generate names.

Besides name, also character’s age depends on the year. Probability of generating certain year is related with the population age pyramid at the certain year.

Lowest and highest year in the data defines effective range for year. Years below or above are treated the same as in the lowest or highest years in data. That means for example if data for names ends on the year 2010, than setting higher year will give same results as 2010.

validate(new_year: int) None

Validate if year is an integer.

Parameters:

new_year (int) – new year of the game

Raises:

cochar.error.InvalidYearValue – raise when new_year is not an integer

>>> character = create_character()
>>> character.year = 1800

cochar.occupations module

Occupations Occupations is a module that contains functions related with occupations

cochar.occup.calc_hobby_points(intelligence: int, hobby_points: Optional[int] = None) int

Return hobby points, based on intelligence.

occupation points = 2 * intelligence

If hobby_points provided, return hobby_points

Parameters:
  • intelligence (int) – intelligence points

  • hobby_points (int, optional) – hobby_points, defaults to None

Returns:

hobby points

Return type:

int

cochar.occup.calc_occupation_points(occupation: str, education: int, power: int, dexterity: int, appearance: int, strength: int, occupation_points: Optional[int] = None) int

Return occupation points based on occupation, education, power, dexterity, appearance and strength.

If occupation_points provided, return occupation_points

Parameters:
  • occupation (str) – occupation points

  • education (int) – education points

  • power (int) – power points

  • dexterity (int) – dexterity points

  • appearance (int) – appearance points

  • strength (int) – strength points

  • occupation_points (int, optional) – occupation points, if provided function returns that value instead of calculating it, defaults to None

Returns:

occupation points for provided occupation

Return type:

int

cochar.occup.generate_occupation(education: int = 1, power: int = 1, dexterity: int = 1, appearance: int = 1, strength: int = 1, random_mode: bool = False, occupation: Optional[str] = None, occup_type: Optional[str] = None, era: Optional[List[str]] = None, tags: Optional[List[str]] = None) str

Return occupation based on: education, power, dexterity, appearance and strength.

Parameters:
  • education (int, optional) – education points, defaults to 1

  • power (int, optional) – power points, defaults to 1

  • dexterity (int, optional) – dexterity points, defaults to 1

  • appearance (int, optional) – appearance points, defaults to 1

  • strength (int, optional) – strength points, defaults to 1

  • random_mode (bool, optional) – ignore edu, pow, dex and str points and return totally random occupation, defaults to False

  • occupation (str, optional) – return specified occupation, defaults to None

  • occup_type (str, optional) – specify type of occupation to return, defaults to None

  • era (str, optional) – specify era of occupation to return, defaults to None

  • tags (List[str], optional) – return occupation with defined tags, defaults to None

Raises:
Returns:

occupation name

Return type:

str

cochar.occup.get_occupation_list()

cochar.skills module

Skills Skills module contains all functions related with skills and Skills object, which is a container for skills

class cochar.skill.SkillsDict(dict=None, /, **kwargs)

Bases: UserDict

Dictionary like object to store character’s skills. Override __setitem__ to validate skills data.

Parameters:

UserDict (abc.ABCMeta) – UserDict from collections

get_json_format()

Return Skills as a dictionary

class cochar.skill.SkillsGenerator(interface: SkillsDataInterface)

Bases: object

generate_skills(occupation: str, occupation_points: int, hobby_points: int, dexterity: int, education: int, skills: Optional[SkillsDict] = None) SkillsDict

Return skills based on: occupation, occupation_points, hobby_points, dexterity and education

If skills provided, return skills

Each occupation has related skills, that are chosen randomly. Then each skill has randomly assigned skill level - number of points related with that skill.

Dexterity is required for dodge skill. Education is required for language(own) skill.

Parameters:
  • occupation (str) – occupation

  • occupation_points (int) – occupation_points

  • hobby_points (int) – hobby_points

  • dexterity (int) – dexterity

  • education (int) – education

  • skills (Skills, optional) – skills, defaults to None

Returns:

skills with assigned skill level

Return type:

Skills

set_interface(interface: SkillsDataInterface) None
cochar.skill.calc_skill_points(occupation: str, education: int, power: int, dexterity: int, appearance: int, strength: int) int

Return skill points based on: occupation, education, power, dexterity, appearance and strength.

Return maximum points for provided occupation.

Parameters:
  • occupation (str) – occupation name

  • education (int) – education points

  • power (int) – power points

  • dexterity (int) – dexterity points

  • appearance (int) – appearance points

  • strength (int) – strength points

Returns:

skill points

Return type:

int

cochar.skill.generate_credit_rating_points(occupation: str, occupation_points: int) int

For provided occupation, and it occupation points, return credit rating points.

Parameters:
  • occupation (str) – occupation

  • occupation_points (int) – occupation points

Returns:

credit rating points

Return type:

int

cochar.skill.skill_test(tested_value: int, repetition: int = 1) int

Perform skill test.

Works like improvement test. Roll number between 1 to 100, If that number is higher than tested value or higher, than 95, then increase tested value with random number, between 1 to 10.

Repeat repetition times.

Parameters:
  • tested_value (int) – tested value

  • repetition (int) – how many test to perform

Returns:

unchanged, or increased tested value

Return type:

int

cochar.utils module

Utilities for cochar module

param TRANSLATION_DICT:

dictionary with translations for skills

param AGE_RANGE:

tuple[int, int], contains ranges of possible ages.

param YEAR_RANGE:

tuple[int], available years for last names

legend:

  • a: art/craft

  • s: science

  • f: fighting

  • g: firearms

  • i: interpersonal

  • l: language

  • *: any

cochar.utils.is_skill_valid(skill_value: int) bool

Check if skill value is int type and it is not below 0.

Parameters:

skill_value (int) – skill value to test

Returns:

True if value is valid, else False

Return type:

bool

cochar.utils.narrowed_bisect(a: Sequence[int], x: int) int

Standard bisect_left from bisect module can return number that exceed len(a). narrowed_bisect returns number that is <= len(a).

It is to prevent IndexError, as many other variables relay on the index number returned.

Parameters:
  • a (Sequence) – sequence of numbers

  • x (int) – number to insert

Returns:

position of insertion

Return type:

int

cochar.errors module

Errors for cochar module

exception cochar.error.AgeNotInRange(age: int, min_age: int, max_age: int)

Bases: CocharError

Age must be within specified range, default 15 - 90

exception cochar.error.CharacteristicPointsBelowMinValue(skill_name: str, min_value=0)

Bases: CocharError

Characteristic points cannot be below defined minimal value

exception cochar.error.CharacteristicValueNotAnInt(skill_name: str, skill_value: Any)

Bases: CocharError

Characteristic value has to be an integer number

exception cochar.error.CocharError

Bases: Exception

exception cochar.error.EmptyName

Bases: CocharError

Name cannot be an empty string

exception cochar.error.IncorrectOccupation(occupation_name: str)

Bases: CocharError

Raise when occupation is not in OCCUPATIONS_LIST

exception cochar.error.InvalidAgeValue(age: int)

Bases: CocharError

Age must be an integer number

exception cochar.error.InvalidBuildValue(build: str, correct_build: list)

Bases: CocharError

Raise when occupation is not in occupation list

exception cochar.error.InvalidCountryValue(country: str, available_countries: list)

Bases: CocharError

Raise when country is not in available countries

exception cochar.error.InvalidDamageBonusValue(damage_bonus: str, correct_damage_bonus: list)

Bases: CocharError

Raise when occupation is not in occupation list

exception cochar.error.InvalidOccupationEra(era: str, correct_era: list)

Bases: CocharError

Raise when occupation era is not correct

exception cochar.error.InvalidOccupationTags(tags: str, correct_tags: list)

Bases: CocharError

Raise when tag is not among available tags

exception cochar.error.InvalidOccupationType(_type: str, correct_type: list)

Bases: CocharError

Raise when occupation type is not correct

exception cochar.error.InvalidOccupationValue(occupation: str, available_occupations: list)

Bases: CocharError

Raise when occupation is not in occupation list

exception cochar.error.InvalidSexValue(sex: str, available_sex: list)

Bases: CocharError

InvalidSexArgument.

Raise when selected sex is not it available for chosen country.

exception cochar.error.InvalidYearValue(year: int)

Bases: CocharError

Year must be an integer number

exception cochar.error.NoneOccupationMeetsCriteria

Bases: CocharError

Raise when searching criteria are not met by any occupation

exception cochar.error.OccupationPointsBelowZero

Bases: CocharError

Raise when provided occupation points are below 0

exception cochar.error.SkillPointsBelowZero(skill)

Bases: CocharError

Skill points cannot be below zero

exception cochar.error.SkillValueNotAnInt(skill)

Bases: CocharError

Skill value has to be an integer number

exception cochar.error.SkillsNotADict(skill)

Bases: CocharError

Skills must be a dictionary