3
\$\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()
asked Apr 30, 2015 at 20:37
\$\endgroup\$
4
  • 5
    \$\begingroup\$ What you may and may not do after receiving answers \$\endgroup\$ Commented May 1, 2015 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\$ Commented May 1, 2015 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\$ Commented May 1, 2015 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\$ Commented May 2, 2015 at 7:52

2 Answers 2

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.

Quill
12k5 gold badges41 silver badges93 bronze badges
answered Apr 30, 2015 at 21:39
\$\endgroup\$
0
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.

Quill
12k5 gold badges41 silver badges93 bronze badges
answered May 1, 2015 at 14:55
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.