class Education: """Education base class.""" SCHOOL_START_DATE = 6 BACHELOR_START_DATE = 18 MASTER_START_DATE = 24 DOCTOR_START_DATE = 26 SCHOOL_NUM_OF_YEARS = (12, 12) BACHELOR_NUM_OF_YEARS = (4, 4) MASTER_NUM_OF_YEARS = (2, 2) DOCTOR_NUM_OF_YEARS = (6, 10) YEARS_TO_COMPLETE = [0, SCHOOL_NUM_OF_YEARS, BACHELOR_NUM_OF_YEARS, MASTER_NUM_OF_YEARS, DOCTOR_NUM_OF_YEARS] FAILING_CLASS_MAX = 3 # Degrees UNEDUCATED = 0 SCHOOL = 1 BACHELOR = 2 MASTER = 3 DOCTOR = 4 LITERAL_DEGREES = ['Uneducated', 'High School Diploma', 'Bachelor Degree', 'Master Degree', 'Doctoral Degree'] # External Factor. Value range from 0 to 1 DRUG_ADDICTION_EFFECT = 0.25 ALCOHOL_ADDICTION_EFFECT = 0.25 CHANCE_OF_BAD_DECISION = 0.02 def __init__(self): self.available_degree = self.SCHOOL self.acquired_degree = [self.UNEDUCATED] self.in_study = False self.current_year = 0 self.years_to_complete_degree = 0 self.total_fail = 0 self.randomizer = Randomizer() def __str__(self): return self.LITERAL_DEGREES[self.acquired_degree[-1]] @property def current_degree(self): """Returns person's current degree level.""" return self.acquired_degree[-1] def start_degree(self, degree): """Starts new degree.""" start = self.YEARS_TO_COMPLETE[degree][0] end = self.YEARS_TO_COMPLETE[degree][1] self.years_to_complete_degree = self.randomizer.get_random_number(start, end) self.in_study = True self.total_fail = 0 self.current_year = 0 def advance_degree(self, is_drug_addict=False, is_alcohol_addict=False): """Advance degree.""" chance_to_fail = self.DRUG_ADDICTION_EFFECT * is_drug_addict + self.ALCOHOL_ADDICTION_EFFECT * is_alcohol_addict + self.CHANCE_OF_BAD_DECISION chance_to_success = 100 - (chance_to_fail * 100) if self.randomizer.get_random_number(0, 100) <= chance_to_success: if self.current_year != self.years_to_complete_degree: self.current_year += 1 else: self.acquire_degree() if self.current_degree + 1 != self.DOCTOR: self.available_degree = self.current_degree + 1 else: if self.current_degree + 1 == self.DOCTOR: return self.total_fail += 1 if self.total_fail > self.FAILING_CLASS_MAX: self.fail_out() def acquire_degree(self): """Append new obtained degree and finish studies.""" self.current_year = 0 self.in_study = False self.total_fail = 0 self.acquired_degree.append(self.current_degree + 1) def fail_out(self): """Fail out of current degree.""" self.in_study = False self.total_fail = 0 self.current_year = 0 def init_degree(self, person): """Initialize education for non-natural born persons.""" if person.age < self.SCHOOL_START_DATE: return False elif person.age < self.BACHELOR_START_DATE: self.start_degree(self.SCHOOL) self.years_to_complete_degree = self.SCHOOL_NUM_OF_YEARS[0] - (person.age - 6) elif person.age >= self.DOCTOR_START_DATE and person.will_do_doctor: self.acquired_degree.append(self.MASTER) self.start_degree(self.DOCTOR) self.years_to_complete_degree -= self.randomizer.get_random_number(1, person.age - 25) elif person.age >= self.MASTER_START_DATE and person.will_do_master: self.acquired_degree.append(self.BACHELOR) self.start_degree(self.MASTER) self.years_to_complete_degree -= self.randomizer.get_random_number(0, 1) elif person.will_do_bachelor: self.acquired_degree.append(self.SCHOOL) self.start_degree(self.SCHOOL) self.years_to_complete_degree -= self.randomizer.get_random_number(0, 3) else: self.acquired_degree.append(self.SCHOOL) self.in_study = False self.years_to_complete_degree = 0
class Job: """Job base class.""" BACHELOR_JOB_LIST = 'BACHELOR' FAMOUS_JOB_LIST = 'FAMOUS' LOW_JOB_LIST = 'LOW' PART_TIMER = -0.5 # half salary INTERN = 0 FRESHGRADUATE = 1 JUNIOR = 2 SENIOR = 3 LEAD = 4 MANAGER = 5 EXECUTIVE = 6 GOOD_PERFORMANCE = 1 BAD_PERFORMANCE = -1 FLAT_PERFORMANCE = 0 PERFORMANCE_LIST = [ GOOD_PERFORMANCE, BAD_PERFORMANCE, FLAT_PERFORMANCE, FLAT_PERFORMANCE ] SALARY_MIN_STANDARD = 20000 # per year SALARY_MAX_STANDARD = 30000 # per year MAXIMUM_SALARY_CHANGE = 30 # in percentages def __init__(self, level=0, salary=0, employment=Traits.UNEMPLOYED): self.level = level self.salary = salary # per year self.employment = employment self.unemployed_year = 0 self.title = None self.current_performance = 0 self.randomizer = Randomizer() self.setup = Setup() def __str__(self): ret_val = { 'title': self.title, 'level': self.level, 'salary': self.salary, 'employment': self.employment } return str(ret_val) def progress_job(self): """Auto progress job performance""" self.current_performance += self.randomizer.get_random_item( self.PERFORMANCE_LIST) self.change_salary_rate = self.randomizer.get_random_number(0, 30) / 100 if self.current_performance > 2: self.promotion(self.change_salary_rate) elif self.current_performance > 1: self.promotion(self.change_salary_rate, job_increase=True) elif self.current_performance < -3: self.termination() elif self.current_performance < -2: self.demotion(self.change_salary_rate, job_decrease=True) elif self.current_performance < -1: self.demotion(self.change_salary_rate) def get_job(self, person): """Set occupation and job level.""" job_chance = [self.LOW_JOB_LIST, self.FAMOUS_JOB_LIST] if person.education.current_degree >= Education.BACHELOR: job_chance.append(self.BACHELOR_JOB_LIST) if person.is_female: self.change_to_female_titles() self.set_job_level(person) self.title = self.randomizer.get_random_item(self.setup.PROFESSIONS[ self.randomizer.get_random_item(job_chance)]) self.set_salary() self.employment = Traits.EMPLOYED def change_to_female_titles(self): """Change male only job titles to female titles.""" if self.title == "Waiter": self.title = "Waitress" if self.title == "Actor": self.title = "Actress" def set_job_level(self, person): """Set job level based on person's achieved education.""" if person.education == Education.UNEDUCATED: self.level = self.PART_TIMER if person.education == Education.SCHOOL: self.level = self.INTERN elif person.education == Education.BACHELOR: self.level = self.FRESHGRADUATE elif person.education == Education.MASTER: self.level = self.SENIOR elif person.education == Education.DOCTOR: self.level = self.EXECUTIVE def set_salary(self): """Determines random job salary.""" self.salary = self.randomizer.get_random_number( self.SALARY_MIN_STANDARD, self.SALARY_MAX_STANDARD) * (self.level + 1) def promotion(self, salary_increment, job_increase=False): """Job promotion.""" if job_increase and self.level < self.EXECUTIVE: self.level += 1 self.current_performance = self.FLAT_PERFORMANCE self.salary = self.salary * (1 + salary_increment) def demotion(self, salary_decrease, job_decrease=False): """Job demotion.""" if job_decrease and self.level > 0: self.level -= 1 self.current_performance = self.FLAT_PERFORMANCE self.salary = 0 if 1 - salary_decrease < 0 else self.salary * ( 1 - salary_decrease) def termination(self): """Job termination""" self.salary = 0 self.level = 0 self.employment = Traits.UNEMPLOYED self.title = "ex-" + self.title self.current_performance = self.FLAT_PERFORMANCE