I am fairly new to Python and programming. I created this simple calculator inspired by my physics class. However, I feel this code could have been done more efficiently. Is there any advice for efficiency?

import math

#calculates vector x component
#x = side length y = angle

def fxcomponent(x, y):
  number = x
  y = math.cos(math.radians(y))
  result = number * y
  return result

#calculates vector y component
def fycomponent(x, angle):
  number = x 
  angle = math.sin(math.radians(angle))
  result = number * angle
  return result

prompt = 'Welcome to my Python vector components calculator!'
prompt += '\nPlease select what you wish to find: \n-type x for x-component             
prompt += '\n-type y for y-component'\n-type quit to end program'

flag = True 

while flag == True:
  number = input(prompt + '\n>')

  #ends program when quit
  if number.lower() == 'quit':
    flag = False 

#calculates x component and continues with y component if desired 
  elif number.lower() == 'x':
    print ('Please tell me the x and the angle:')
    x, angle = [int(x) for x in input('>').split()]
    result = fxcomponent(x, angle)
    print('The x component of %d at %d° is: %d' % (x, angle, result))

    answer = input('Now do you wish to find the y component? \nType Y/N\n>')

    if answer.lower() == 'y':
      print ('Please tell me the y and the angle:')
      y, angle = [int(x) for x in input('>').split()]
      result = fycomponent(y, angle)
      print('The y component of %d at %d° is: %d' % (y, angle, result))

    elif answer.lower() == 'n':
      print('Thanks for using my program! See you later!')
      flag = False 

    elif answer.lower() != 'y' or 'n':
      print('Invalid command! try again')

#calculates y component and continues with x component if desired 
 elif number.lower() == 'y':
  print ('Please tell me the y and the angle:')
  y, angle = [int(x) for x in input('>').split()]
  result = fycomponent(y, angle)
  print('The y component of %d at %d° is: %d' % (y, angle, result))

  answer = input('Now do you wish to find the x component? \nType Y/N\n>')

  if answer.lower() == 'y':
     print ('Please tell me the y and the angle:')
     y, angle = [int(x) for x in input('>').split()]
     result = fycomponent(y, angle)
     print('The x component of %d at %d° is: %d' % (x, angle, result))

  elif answer.lower() == 'n':
     print('Thanks for using my program! See you later!')
     flag = False  

  elif answer.lower() != 'y' or 'n':
     print('Invalid command! try again')

  else: 
    print ('Invalid command; try again!')
    continue
share|improve this question

closed as unclear what you're asking by 200_success Mar 4 at 7:43

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

    
Your prompt strings are malformed, and one of your elif indentations doesn't line up. Please ensure that your code has been posted correctly as intended. The easiest way to post code is to paste it into the question editor, highlight it, and press Ctrl-K to mark it as a code block. – 200_success Mar 4 at 7:40
up vote 2 down vote accepted
  • Simplify your components functions:
def fxcomponent(x, angle):
    return x * math.cos(math.radians(angle))

def fycomponent(y, angle):
    return y * math.sin(math.radians(angle))
  • Instead of using number.lower() in every IF statement, convert it once putting number = number.lower() after get the value from input.'

  • Focusing on readability and maintainability you should extract the copy+paste code of calculating x and y and create a generic function that encapsulates that. So, your code will look like this:

def calculate_fcomponent(component):
    print ('Please tell me the %c and the angle:' % (component))
    value, angle = [int(x) for x in input('>').split()]
    result = fxcomponent(value, angle) if component == 'x' else fycomponent(value, angle)
    print ('The %c component of %d at %d° is: %d' % (component, value, angle, result))
    print()

def run():
    print('Welcome to my Python vector components calculator!')
    print()

    prompt = ('Please select what you wish to find:'
              '\n-type x for x-component'
              '\n-type y for y-component'
              '\n-type quit to end program')

    flag = True 

    while flag:
        cmd = input(prompt + '\n>')
        cmd = cmd.lower()

        if cmd == 'quit':
            flag = False

        elif cmd in ('x', 'y'):
            calculate_fcomponent(cmd)

        else:
            print ('Invalid command; try again!')

if __name__ == "__main__":
    run()
share|improve this answer
    
You could use a multi-line string for prompt and avoid the costly string addition – Graipher Mar 4 at 11:30
    
Also, cmd == 'x' or 'y' will always evaluate to True, because non-empty strings are truthy. You want cmd in ('x', 'y'). – Graipher Mar 4 at 11:39
    
And lastly, continue as the last statement in a while loop body is a no-op, it will continue anyway – Graipher Mar 4 at 11:40

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