"""DuckieDai Molarity prototype for TI-84 Plus CE Python.

Standalone source. Not yet verified on a physical calculator.
"""


def duckiedai_intro(program_name, wait=True):
    """Show the same small opening as the Rectangle Area program."""
    title = program_name[:16]
    empty = 16 - len(title)
    left = empty // 2
    right = empty - left
    print("+----------------------+")
    print("|   " + " " * left + title + " " * right + "   |")
    print("|                      |")
    print("|       __             |")
    print("|   ___(o )>  quack!   |")
    print("|   \\ <_. )           |")
    print("|    `---'             |")
    print("|     by DuckieDai     |")
    print("+----------------------+")
    print("Loading...")
    if wait:
        input("Press enter to start ")
        print("\n" * 6)


def is_nonnegative_finite(value):
    return value >= 0 and value < 1e100


def nonnegative_number(prompt):
    """Zero moles is valid; negative amount is not."""
    while True:
        try:
            value = float(input(prompt))
            if is_nonnegative_finite(value):
                return value
        except ValueError:
            pass
        print("Enter 0 or above.")


def positive_number(prompt):
    """Solution volume in liters must be greater than zero."""
    while True:
        try:
            value = float(input(prompt))
            if value > 0 and value < 1e100:
                return value
        except ValueError:
            pass
        print("Enter a number above 0.")


def molarity(moles, liters):
    """Return amount of solute divided by total solution volume."""
    if not is_nonnegative_finite(moles):
        raise ValueError("moles must be nonnegative and finite")
    if not liters > 0 or not liters < 1e100:
        raise ValueError("liters must be positive and finite")
    result = moles / liters
    if not is_nonnegative_finite(result):
        raise ValueError("molarity is too large")
    return result


def main():
    duckiedai_intro("MOLARITY")
    print("MOLARITY")
    print("Formula: M = mol / L")
    print("Use solution volume, not")
    print("solvent volume.")
    print()
    moles = nonnegative_number("Moles solute: ")
    liters = positive_number("Solution L: ")
    result = molarity(moles, liters)
    print()
    print("M = " + str(moles) + " / " + str(liters))
    print("Molarity =")
    print(str(result) + " mol/L")
    print()
    print("DuckieDai says: done!")


# TI-Python imports a selected AppVar instead of setting __name__ to main.
main()
