'None' keeps appearing in the output - How to remove it?

:joy: here goes then:

## Send the user to printMenu, now known as options.
def main():
    options = printMenu()
    print(options)

## Display the menu for the user.
def printMenu():
    print("\nBond Yield to Maturity (YTM) Calculator")
    print("A: Calculate Approximate YTM")
    print("B: Formulas Used For The Calculation")
    print("X: Exit")
    answer = input("Enter A, B or X to proceed: ")
    if answer == 'a':
        option_A()
    elif answer == 'b':
        option_B()
    elif answer == 'x':
        option_X()

## User inputs and calculation for the YTM.
def option_A():
    fBondValue = float(input("\nEnter face value of bond: "))
    fIntr = float(input("Enter coupon interest rate: "))
    fCurrentMarketPrice = float(input("Enter current market price: "))
    iMaturity = int(input("Enter years until maturity: "))
    Intr = fIntr * 1000
    a = (fBondValue - fCurrentMarketPrice) / iMaturity
    b = (fBondValue + fCurrentMarketPrice) / 2
    YTM = (Intr + (a)) / (b)
    percentYTM = YTM * 100
    txt = "Approximate YTM: {:.2f}%"
    print(txt.format(percentYTM))

## Display formulas, go back to menu or quit
def option_B():
    print("\nFormula for Yield to Maturity (YTM):")
    print("YTM = (intr + a) / b\n")
    print("a = (face value - current market price) / years until maturity\n")
    print("b = (face value + current market price) / 2\n")
    answer = input("Press 'm' to go back to the menu, or 'x' to quit: ")
    if answer == 'm':
        main()
    elif answer == 'x':
        option_X()
    else:
        print("Please enter valid command.")
        option_B()
    
## Kills the code.
def option_X():
    print("Goodbye.")
    sys.exit()

main()

How about this:

# User inputs and calculation for the YTM.

def option_A():
    fBondValue = float(input("\nEnter face value of bond: "))
    fIntr = float(input("Enter coupon interest rate: "))
    fCurrentMarketPrice = float(input("Enter current market price: "))
    iMaturity = int(input("Enter years until maturity: "))
    Intr = fIntr * 1000
    a = (fBondValue - fCurrentMarketPrice) / iMaturity
    b = (fBondValue + fCurrentMarketPrice) / 2
    YTM = (Intr + (a)) / (b)
    percentYTM = YTM * 100
    txt = "Approximate YTM: {:.2f}%"
    print(txt.format(percentYTM))

# Display formulas, go back to menu or quit

def option_B():
    print("\nFormula for Yield to Maturity (YTM):")
    print("YTM = (intr + a) / b\n")
    print("a = (face value - current market price) / years until maturity\n")
    print("b = (face value + current market price) / 2\n")
    answer = input("Press 'm' to go back to the menu, or 'x' to quit: ")
    if answer == 'm':
        main()
    elif answer == 'x':
        option_X()
    else:
        print("Please enter valid command.")
        option_B()

# Kills the code.


def option_X():
    print("Goodbye.")
    sys.exit()


while True:
    print("\nBond Yield to Maturity (YTM) Calculator")
    print("A: Calculate Approximate YTM")
    print("B: Formulas Used For The Calculation")
    print("X: Exit")
    answer = input("Enter A, B or X to proceed: ")
    if answer == 'a':
        option_A()
    elif answer == 'b':
        option_B()
    elif answer == 'x':
        option_X()

I’ve not altered your comment lines. Also, do you know anything about ‘docstrings’?

Btw: the None was coming from print(options), because the printMenu() function does not return a value.

1 Like

Ohhh I understand, thank you so much! This has been a huge help!

I’ve never used docstrings before, but isn’t it some sort of comment?

No worries; you’re welcome.

One improvement: if you use answer = input("Enter A, B or X to proceed: ").lower(), then it matters not how the user enters an option; they can use uppercase or lowercase.

It’s a little off-topic, but yes, you can (and should) use docstrings to annotate your functions.

As an example:

def isdigit(*c):
    """
Takes a single character input and returns a Boolean answer.
True:  if the input is a digit
False: if the input is not a digit or the length of the input != 1
    """
    if not c or len(str(c[0])) != 1:
        return False
    else:
        c = str(c[0])
    if ord(c) < 48 or ord(c) > 57:
        return False
    else:
        return True

Now, if you enter help(isdigit), you get the ‘docstring’ as a return. Useful if you have some functions that you import into other apps, as I do.

Note: I coded that some years ago and looking at it now, maybe it could be improved upon :slight_smile:

1 Like

Ohh that is very helpful. I hadn’t though of it in that sense.
Thank you for your suggestion. I will definitely be using it!

1 Like

Relevant reference material on Stack Overflow:

In general, it will not be enough to show the function and ask for help. You will need to understand the underlying concepts, think about the specific situation, and apply the appropriate changes.

Rob hasn’t explained, but specificly:
if the first expression in the function is a string, that string is kept
as the “docstring”. The help() builtin function will print this if
present. So we usually use them.

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

Since you are learning python, here is how you can use the print function sep argument to print a new line, and add a tab (\t), to indent all the options:

def printMenu():
    # 4 print statements -> a single one:
    print("\nBond Yield to Maturity (YTM) Calculator",
    "\tA: Calculate Approximate YTM",
    "\tB: Formulas Used For The Calculation",
    "\tX: Exit", sep="\n")

    answer = input("Enter A, B or X to proceed: ").strip().lower()
   # test to do: what if user user enters something other than a, b or x?
    if answer == 'a':
        option_A()
    elif answer == 'b':
        option_B()
    elif answer == 'x':
        option_X()

@Catalyx

Although a little off-topic: when coding a menu, I prefer to do something like this:

def printMenu():
    print("Bond Yield to Maturity (YTM) Calculator")
    menu = [
        "Calculate Approximate YTM",
        "Formulas Used For The Calculation",
        "Exit"
    ]
    for option, item in enumerate(menu, 1):
        print(f"\t{option}: {item}")

… which is a lower maintenance, should the menu need amending in some way.