import meanings from typing import List from colorama import Fore, Style, init init(autoreset=True) MASTER_NUMS = [11, 22, 33] def reduce(n: int, context: str = "") -> int: """Reduces a number to a single digit or returns a master number with context.""" if n in MASTER_NUMS: if context: print(f'{Fore.YELLOW}Master number found in {context}: {n}') return n total = sum(int(digit) for digit in str(n)) return total if total < 10 else reduce(total, context) def name_num(name: str) -> int: """Converts a name to a number by reducing each character to its numerical value.""" return sum( (ord(char) - 96 if ord(char) - 96 < 10 else sum(int(digit) for digit in str(ord(char) - 96))) for char in name ) def master_check(total: int, context: str = "") -> int: """Checks for master number and reduces further if necessary, with context.""" if total in MASTER_NUMS: if context: print(f'{Fore.YELLOW}Master number found in {context}: {total}') return total total = sum(int(digit) for digit in str(total)) return total if total < 10 else sum(int(digit) for digit in str(total)) def pull_vowels(name: str) -> List[str]: """Extracts vowels from a given name.""" return [letter for letter in name if letter in 'aeiou'] def get_user_input(prompt: str) -> str: """Gets input from the user with a prompt, ensuring it is not blank.""" user_input = input(prompt).strip() while not user_input: print('Error: Input cannot be blank.') user_input = input(prompt).strip() return user_input def validate_name(name: str) -> str: """Validates the user's name input.""" while not name or name.isnumeric(): print('Error: Please enter a valid name (letters only).') name = get_user_input("Please enter the person's Full Name: \n") return name.lower() def validate_birthdate(birthdate: str) -> str: """Validates the user's birthdate input.""" while not birthdate: print('Error: Birth date cannot be blank.') birthdate = get_user_input('What is your full Date of Birth? (mm/dd/yyyy) [eg. 5/13/1982] \n') return birthdate def split_name(name: str) -> List[str]: """Splits the name into subnames and ensures at least first and last name are provided.""" name_split = name.split() while len(name_split) < 2: print('Error: More information needed. Please use at least your First and Last name.') name = get_user_input("Please enter the person's Full Name [First, Middle, Last]: \n").lower() name_split = name.split() return name_split def calculate_numbers(name_split: List[str], birth_raw: str): """Calculates Life Path, Expression, Soul Urge, and Birthday numbers.""" pieces = birth_raw.split('/') month = reduce(int(pieces[0]), context="Month") day = reduce(int(pieces[1]), context="Day") year = reduce(int(pieces[2]), context="Year") birth_date = month + day + year life_path = reduce(birth_date, context="Life Path") birthday = reduce(day, context="Birthday") subname_value = [] if len(name_split) > 4: subname_value.append(reduce(master_check(name_num(name_split[0]), context="First Name"), context="First Name")) subname_value.append(reduce(master_check(name_num(name_split[-1]), context="Last Name"), context="Last Name")) else: for subname in name_split: subname_value.append(reduce(master_check(name_num(subname), context=f"Subname: {subname}"), context=f"Subname: {subname}")) expression = master_check(reduce(sum(subname_value)), context="Expression") subname_vowels = [] for subname in name_split: subname_vowels.append(master_check(name_num(pull_vowels(subname)), context=f"Vowels in {subname}")) soul_urge = master_check(reduce(sum(subname_vowels)), context="Soul Urge") return life_path, expression, soul_urge, birthday def print_core_output(name_raw: str, life_path: int, expression: int, soul_urge: int, birthday: int): """Prints the core numerology output.""" print(f'\n{Fore.CYAN}Core for {name_raw}\n') print(f'{Fore.GREEN}1: Life Path: {Fore.RESET}{life_path}') print(f'{Fore.GREEN}2: Expression: {Fore.RESET}{expression}') print(f'{Fore.GREEN}3: Soul Urge: {Fore.RESET}{soul_urge}') print(f'{Fore.GREEN}4: Birthday: {Fore.RESET}{birthday}') def print_detailed_output(life_path: int, expression: int, soul_urge: int, birthday: int): """Prints detailed numerology meanings.""" print('\nDetailed Meanings:\n') print(f'{Fore.BLUE}Life Path {life_path}:\n{Style.RESET_ALL}{meanings.life_path[life_path]}\n') print(f'{Fore.BLUE}Expression {expression}:\n{Style.RESET_ALL}{meanings.expression[expression]}\n') print(f'{Fore.BLUE}Soul Urge {soul_urge}:\n{Style.RESET_ALL}{meanings.soul_urge[soul_urge]}\n') print(f'{Fore.BLUE}Birthday {birthday}:\n{Style.RESET_ALL}{meanings.birthday[birthday]}\n') def main(): name_raw = get_user_input("Please enter the person's Full Name: \n") name = validate_name(name_raw) name_split = split_name(name) birth_raw = validate_birthdate(get_user_input('What is your full Date of Birth? (mm/dd/yyyy) [eg. 5/13/1982] \n')) print() # Add a blank line for better readability life_path, expression, soul_urge, birthday = calculate_numbers(name_split, birth_raw) print_core_output(name_raw, life_path, expression, soul_urge, birthday) print_detailed_output(life_path, expression, soul_urge, birthday) if __name__ == "__main__": main()