2
\$\begingroup\$

This is a follow up to the questions: PyDOS shell simulation and PyDOS: Version 2.0

Introducing PyDOS 3.0! With brand new features and improved code, this will blow your mind!

New Features (This list will be updated with PyWrite soon)

  • Dialogs are now in a window like design.

  • New start-screen, easier to use.

  • Create your own name and change it!

  • New Commands Dictionary

  • PyCALC is now called SimpleCalc

If you have any ideas for improvements, don't hesitate to post them!

Source Code:

#PyDOS Version 3.0 - Written by Mrfunny744
import time
import os
import sys
import random

def ChangeName():
    os.system('cls' if os.name == 'nt' else 'clear')
    print ("----------------------------------------------")
    name  = input ("Type in your new username: ")
    print()
    print ("This can be changed again if you wish.")
    print ("----------------------------------------------")
    time.sleep(2.5)


def shutdown():
    print ("------------------------")
    print ("|                      |")
    print ("| Thank you for using  |")
    print ("|        PyDOS         |")
    print ("|                      |")
    print ("|                      |")
    print ("|                      |")
    print ("|   Shutting Down...   |")
    print ("|                      |")
    print ("------------------------")
    sys.exit(0)

def end():
    print ("------------------------------------")
    print ("|                                  |")
    print ("|   Thanks for using SimpleCalc!   |")
    print ("|                                  |")
    print ("------------------------------------")
    time.sleep(2)

def calc_a():
    print ("----------------------------------")
    num1 = int(input("Enter a number: "))
    num2 = int(input("Enter a number: "))
    print ("----------------------------------")
    answer = num1+num2
    print ("Your answer is:" ,answer)
    print ("----------------------------------")
    time.sleep(3)
    end()



def calc_m():
    print ("----------------------------------")
    num1 = int(input("Enter a number: "))
    num2 = int(input("Enter a number: "))
    print ("----------------------------------")
    answer = num1*num2
    print ("Your answer is:" ,answer)
    print ("----------------------------------")
    time.sleep(3)
    end()


def calc_s():
    print ("----------------------------------")
    num1 = int(input("Enter a number: "))
    num2 = int(input("Enter a number: "))
    print ("----------------------------------")
    answer = num1-num2
    print ("Your answer is:" ,answer)
    print ("----------------------------------")
    time.sleep(3)
    end()

def calc_d():
    print ("----------------------------------")
    num1 = int(input("Enter a number: "))
    num2 = int(input("Enter a number: "))
    print ("----------------------------------")
    answer = num1/num2
    print ("Your answer is:" ,answer)
    print ("----------------------------------")
    time.sleep(3)
    end()



def simplecalc():
    print ("--------------------------")
    print ("|                        |")
    print ("| Welcome to SimpleCalc  |")
    print ("|                        |")
    print ("| A = Add                |")
    print ("| M = Multiply           |")
    print ("| S = Subtract           |")
    print ("| D = Divide             |")
    print ("| Q = Quit               |")
    print ("|                        |")
    print ("--------------------------")
    print ("|                        |")
    choice = input ("| Choice:                |")
    print ("|                        |")
    print ("--------------------------")
    if choice == 'a':
        calc_a()
    elif choice == 'm':
        calc_m()
    elif choice == 's':
        calc_s()
    elif choice == 'd':
        calc_d()
    elif choice == 'q':
        end()
    else:
        print ("Invalid specifacation.")


def error_message():
    os.system('cls' if os.name == 'nt' else 'clear')
    print ("----------------------")
    print ("|      Whoops!       |")
    print ("|                    |")
    print ("|                    |")
    print ("|   It dosent look   |")
    print ("|    like the app    |")
    print ("|      exists.       |")
    print ("|                    |")
    print ("|Check and try again.|")
    print ("----------------------")
    time.sleep(3)


os.system('cls' if os.name == 'nt' else 'clear')
print ("---------------------------")
print ("|                         |")
print ("|                         |")
print ("|    Welcome to PyDOS!    |")
print ("|                         |")
print ("|                         |")
print ("|                         |")
print ("|                         |")
print ("|                         |")
print ("|      Version 3.0        |")
print ("|     Alpha Edition       |")
print ("|                         |")
print ("|                         |")
print ("---------------------------")
time.sleep(3)
print ()
print ("-----------------------------------------------")
name = input ("Enter a name: ")
print ("-----------------------------------------------")
print ("Information has been saved.")
print ()
print ("This data will be used in some applications.")
print ("-----------------------------------------------")
time.sleep(3)
while True:
    os.system('cls' if os.name == 'nt' else 'clear')
    print ("-------------------------")
    print ("|                       |")
    print ("|                       |")
    print ("|     Loading Home      |")
    print ("|        Screen         |")
    print ("|                       |")
    print ("|                       |")
    print ("|                       |")
    print ("|                       |")
    print ("|                       |")
    print ("-------------------------")
    time.sleep(1.5)
    os.system('cls' if os.name == 'nt' else 'clear')
    print ("-------------------------------------------------------------------------------")
    print ("| Username:",name,"                                                           |")
    print ("-------------------------------------------------------------------------------")
    print ("|                                                                             |")
    print ("|               PyDOS Home Screen - Type in an app below.                     |")
    print ("|                                                                             |")
    print ("|       Apps:                                                                 |")
    print ("|                                                                             |")
    print ("|       ChangeName                                                            |")
    print ("|       Shutdown                                                              |")
    print ("|       SimpleCalc                                                            |")
    print ("|       PyWrite                                                               |")
    print ("|       About                                                                 |")
    print ("|                                                                             |")
    print ("|                                                                             |")
    print ("|                                                                             |")
    print ("|   PyDOS Version 3.0 Alpha (Alpha 1.2                                        |")
    print ("-------------------------------------------------------------------------------")
    selection = input("Select An App: ")
    command_actions = {
    'ChangeName' : ChangeName,
    'SimpleCalc' : simplecalc,
    'Shutdown' : shutdown
    }
    if selection in command_actions:
        action = command_actions[selection]
        action()
    else:
        error_message()
\$\endgroup\$
  • 5
    \$\begingroup\$ What you may and may not do after receiving answers \$\endgroup\$ – rolfl May 1 '15 at 15:59
  • 4
    \$\begingroup\$ I still don't understand why you think the sleep is necessary at all. It objectively makes for a worse user experience. \$\endgroup\$ – Snowbody May 1 '15 at 16:17
  • \$\begingroup\$ That's a whole boatload of print statements. Why not have a echo() function that accepts a list instead, and each element of that list is a line to print? Something like this: gist.github.com/jsanc623/ad1319b4a5bf6db34469 but that also handles padding and alignment, so you don't have to pass in padding. \$\endgroup\$ – jsanc623 May 1 '15 at 17:43
  • \$\begingroup\$ The reason why there is sleep is because I am moving away from the 'DOS' thing now. See my answer for details. \$\endgroup\$ – VirtualHat May 2 '15 at 7:52
11
\$\begingroup\$
time.sleep(2.5)

Again, don't sleep your program, it makes it unnecessarily slow, and it doesn't even act like an old machine would because when it does run, it runs quite fast.


--------------------------
|                        |
| Welcome to SimpleCalc  |
|                        |
| A = Add                |
| M = Multiply           |
| S = Subtract           |
| D = Divide             |
| Q = Quit               |
|                        |
--------------------------

You prompt for a capital "A", but only accept a lowercase "a":

if choice == 'a':
    calc_a()

You can easily change this to accept both like this:

choice = input ("| Choice:                |").lower()

If you want to accept any input that starts with an "A" or "a", just append [0] to the line.

Your various calc_x() functions are extremely similar. You can reduce some of that similarity by either passing them an argument or using a function to input the values. Personally, if you are not going to accept entire equations and handle order of operations, I would use one function:

def calc(operation):
    print ("----------------------------------")
    num1 = int(input("Enter a number: "))
    num2 = int(input("Enter a number: "))
    print ("----------------------------------")

    if operation == 'a':
        answer = num1 + num2
    elif operation == 's':
        answer = num1 - num2
    elif operation == 'm':
        answer = num1 * num2
    elif operation == 'd':
        answer = num1 / num2

    print ("Your answer is:" ,answer)
    print ("----------------------------------")
    end()

Then, call this function from simplecalc like this:

if choice in "asmd":
    calc(choice)
else:
    print ("Invalid specifacation.")    // "specification"

Don't call end(), or any other functions, from your calc() function. Actually, you shouldn't even print from your calc() function - what if you want to calculate something and not print it? Also, inputting values is not part of the calculation. I would write this like this (extraneous output removed for simplicity):

def calc(operation, num1, num2):
    if operation == 'a':
        return num1 + num2
    elif operation == 's':
        return num1 - num2
    elif operation == 'm':
        return num1 * num2
    elif operation == 'd':
        if num2 == 0:
            raise ValueError('Divide by 0 expection')

        return num1 / num2
    else:
        raise ValueError('Unknown error')

def simplecalc():
    print ("Welcome to SimpleCalc! You have the following operators:")
    print ("A: Add")
    print ("S: Subtract")
    print ("M: Multiply")
    print ("D: Divide")
    print ("Q: Quit")

    choice = input ("Choice: ").lower()[0]

    if choice == 'q':
        end_simple_calc()
        return

    if choice not in "asmd":
        print ("Invalid specification.")
        end_simple_calc()
        return

    try:
        num1 = int(input("Enter a number: "))
        num2 = int(input("Enter a number: "))
        print ("Your answer is:", calc(choice, num1, num2))

    except ValueError as err:
        print(err.args)

    end_simple_calc()

This not only catches the invalid division by 0 operation, it also catches when you input an invalid number and prints an error message instead of the printing stack trace and crashing.


Right here, you only allow three apps; why are the other two in the prompt list?

command_actions = {
'ChangeName' : ChangeName,
'SimpleCalc' : simplecalc,
'Shutdown' : shutdown
}

You should be consistent in your naming:

def ChangeName():
def shutdown():

I believe the PEP8 standard states you should use snake_case names.

Also related to naming: def end(). What does end() do? It prints a conclusion to SimpleCalc, but does not show that in the name. What if I was looking through your code adding a new feature, and I saw that in SimpleCalc? I might add it to the end of my new feature and have a problem.

\$\endgroup\$
5
\$\begingroup\$

I think that the functions for SimpleCalc should be put in their own module or their own class - presumably you'll want to add more commands at some point, and a function called end is a bit generic as a name.

Your naming conventions in general could be improved - instead of calc_d, call it divide, for instance.

For the SimpleCalc main function, consider adding a loop until the user selects quit, so they can do more than one calculation.

Instead of having a static list of available commands, maybe loop through the keys of your command_actions dictionary.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.