Efficency help for a Calculator Program

Discussion in 'Python' started by JonDoe297, Oct 2, 2013.

  1. JonDoe297

    JonDoe297 Guest

    You may remember me from this :

    https://groups.google.com/forum/#!topic/comp.lang.python/PIkUno3avkw



    I need help to increase the efficiency of this code :


    global repeat
    repeat=1
    def main():
    c=int(raw_input("How many numbers do you want to work? (Min. 2 Max. 3) "))
    if c==2:
    x=int(raw_input("Enter the first number to be worked "))
    y=int(raw_input("Enter the second number to be worked "))
    elif c==3:
    x=int(raw_input("Enter the first number to be worked "))
    y=int(raw_input("Enter the second number to be worked "))
    z=int(raw_input("Enter the third number to be worked "))
    else:
    print "Invalid input.";raw_input("Press <enter> to close this window");exit()
    p=int(raw_input("Do you want to divide, subtract, add or multiply these numbers? (1=divide, 2=subtract, 3=add, 4=multiply) "))
    if p==1 and c==2:
    print "The result is : ",x/y
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    elif p==1 and c==3:
    print "The result is : ",x/y/z
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    elif p==2 and c==2:
    print "The result is : ",x-y
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    elif p==2 and c==3:
    print "The result is : ",x-y-z
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    elif p==3 and c==2:
    print "The result is : ",x+y
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    elif p==3 and c==3:
    print "The result is : ",x+y+z
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    elif p==4 and c==2:
    print "The result is : ",x*y
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    elif p==4 and c==3:
    print "The result is : "+str(x*y*z)
    repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    if repeat==1:
    main()
    else:
    repeat=int(raw_input("Invalid Input. Please read instructions properly. Would you like to try again? Yes=1 No=2 "))
    if repeat==1:
    main()
    else:
    exit()
    main()



    Is there any way to make it smaller? It does it's job, but I want it to look smaller, more efficient.
    JonDoe297, Oct 2, 2013
    #1
    1. Advertising

  2. On Wed, Oct 2, 2013 at 8:44 PM, JonDoe297 <> wrote:
    > Is there any way to make it smaller? It does it's job, but I want it to look smaller, more efficient.


    Yes, it is, but let me first clarify something: "Smaller" and "more
    efficient" are two quite different concepts. Efficiency doesn't matter
    to your code here, so what you're looking for is smaller, clearer
    code. Which is a good thing to be doing :)

    At top level, the 'global' declaration doesn't do anything. You may as
    well not bother with it.

    If you change your recursive main() function into a while loop, you'll
    be able to combine all your common code very easily. I won't do the
    whole job for you, but consider this structure:

    repeat=1
    while repeat==1:
    # get inputs
    # calculate and produce output
    repeat=int(raw_input("Do you want to do more? "))

    And if you need your error state to have a different prompt, you can
    use 'continue' to skip the bottom of the loop.

    Hope that helps!

    ChrisA
    Chris Angelico, Oct 2, 2013
    #2
    1. Advertising

  3. JonDoe297

    JonDoe297 Guest

    On Wednesday, October 2, 2013 4:31:03 PM UTC+5:30, Chris Angelico wrote:
    > On Wed, Oct 2, 2013 at 8:44 PM, JonDoe297 wrote:
    >
    > > Is there any way to make it smaller? It does it's job, but I want it to look smaller, more efficient.

    >
    >
    >
    > Yes, it is, but let me first clarify something: "Smaller" and "more
    >
    > efficient" are two quite different concepts. Efficiency doesn't matter
    >
    > to your code here, so what you're looking for is smaller, clearer
    >
    > code. Which is a good thing to be doing :)
    >
    >
    >
    > At top level, the 'global' declaration doesn't do anything. You may as
    >
    > well not bother with it.
    >
    >
    >
    > If you change your recursive main() function into a while loop, you'll
    >
    > be able to combine all your common code very easily. I won't do the
    >
    > whole job for you, but consider this structure:
    >
    >
    >
    > repeat=1
    >
    > while repeat==1:
    >
    > # get inputs
    >
    > # calculate and produce output
    >
    > repeat=int(raw_input("Do you want to do more? "))
    >
    >
    >
    > And if you need your error state to have a different prompt, you can
    >
    > use 'continue' to skip the bottom of the loop.
    >
    >
    >
    > Hope that helps!
    >
    >
    >
    > ChrisA


    Thanks a lot again Chris! You understood what I couldn't convey, perfectly! I'll use your suggestions ;)
    JonDoe297, Oct 2, 2013
    #3
  4. On Wed, 2 Oct 2013 03:44:24 -0700 (PDT), JonDoe297
    <> declaimed the following:

    >
    >global repeat


    This does nothing at the top level of a module

    >repeat=1
    >def main():
    > c=int(raw_input("How many numbers do you want to work? (Min. 2 Max. 3) "))


    You don't handle the case where someone enter a non-integer item

    > if c==2:
    > x=int(raw_input("Enter the first number to be worked "))
    > y=int(raw_input("Enter the second number to be worked "))
    > elif c==3:
    > x=int(raw_input("Enter the first number to be worked "))
    > y=int(raw_input("Enter the second number to be worked "))
    > z=int(raw_input("Enter the third number to be worked "))


    You duplicate the first two inputs -- yet by your definition, two is
    the minimum. And since 3 is the maximum...

    x = int(....)
    y = int(....)
    if c == 3:
    z = int(....)


    > else:
    > print "Invalid input.";raw_input("Press <enter> to close this window");exit()
    > p=int(raw_input("Do you want to divide, subtract, add or multiply these numbers? (1=divide, 2=subtract, 3=add, 4=multiply) "))
    > if p==1 and c==2:
    > print "The result is : ",x/y
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > elif p==1 and c==3:
    > print "The result is : ",x/y/z
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > elif p==2 and c==2:
    > print "The result is : ",x-y
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > elif p==2 and c==3:
    > print "The result is : ",x-y-z
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > elif p==3 and c==2:
    > print "The result is : ",x+y
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > elif p==3 and c==3:
    > print "The result is : ",x+y+z
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > elif p==4 and c==2:
    > print "The result is : ",x*y
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > elif p==4 and c==3:
    > print "The result is : "+str(x*y*z)
    > repeat=int(raw_input("Do you want to calculate for more numbers? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > else:
    > repeat=int(raw_input("Invalid Input. Please read instructions properly. Would you like to try again? Yes=1 No=2 "))
    > if repeat==1:
    > main()
    > else:
    > exit()
    >main()
    >

    Ack! way too many conditionals... Condense out the logic -- since you
    apply the same operator to all data you just need a way to pass the
    operator to a function that applies it to all the data.



    -=-=-=-=-=-
    import sys

    while True:
    try:
    numItems = int(raw_input("\n\nHow many values? "))
    except: #naked exception is not really good programming
    print "Invalid input, exiting..."
    sys.exit(1)

    print numItems

    items = []
    while len(items) < numItems:
    try:
    item = int(raw_input("Enter item #%s> " % (len(items) + 1)))
    items.append(item)
    except: #see previous comment
    print "Invalid input, try again"

    oper = None
    while oper is None:
    oper = raw_input("Enter operation [+, -, *, /]> ")
    if oper[0] in "+-*/":
    oper = oper[0]
    else:
    oper = None

    #note -- I'm too lazy to look up the operator module, but the
    #above could have used a dictionary look-up to assign the
    #actual function to oper, and then the following if-block
    #becomes a simple
    # cumulative = oper(cumulative, item)

    cumulative = items[0]
    for item in items[1:]:
    if oper == "+":
    cumulative += item
    elif oper == "-":
    cumulative -= item
    elif oper == "*":
    cumulative *= item
    elif oper == "/":
    cumulative /= item
    else:
    print "Programming Error -- operator is invalid after passing
    check"

    print "Cumulative result is %s" % cumulative


    -=-=-=-=-=-=-
    C:\Users\Wulfraed\Documents>oper.py


    How many values? 3
    3
    Enter item #1> 21
    Enter item #2> 32
    Enter item #3> 43
    Enter operation [+, -, *, /]> +
    Cumulative result is 96


    How many values? 4
    4
    Enter item #1> 999
    Enter item #2> 321
    Enter item #3> 123
    Enter item #4> 42
    Enter operation [+, -, *, /]> -
    Cumulative result is 513


    How many values? 2
    2
    Enter item #1> 4737
    Enter item #2> 121
    Enter operation [+, -, *, /]> *
    Cumulative result is 573177


    How many values?
    Invalid input, exiting...

    C:\Users\Wulfraed\Documents>
    --
    Wulfraed Dennis Lee Bieber AF6VN
    HTTP://wlfraed.home.netcom.com/
    Dennis Lee Bieber, Oct 3, 2013
    #4
  5. On Thu, Oct 3, 2013 at 9:47 AM, Dennis Lee Bieber <> wrote:
    > try:
    > numItems = int(raw_input("\n\nHow many values? "))
    > except: #naked exception is not really good programming
    > print "Invalid input, exiting..."
    > sys.exit(1)


    Please don't _ever_ advocate this programming style! Wrapping
    something in a try/except that emits a generic message and terminates
    is a bad idea - the default behaviour, if you simply let the exception
    happen, is to emit a very useful message and terminate. Never test for
    any error condition you're not prepared to handle, as the BOFH advised
    his boss.

    ChrisA
    Chris Angelico, Oct 3, 2013
    #5
  6. On Thu, 3 Oct 2013 10:25:47 +1000, Chris Angelico <>
    declaimed the following:

    >On Thu, Oct 3, 2013 at 9:47 AM, Dennis Lee Bieber <> wrote:
    >> try:
    >> numItems = int(raw_input("\n\nHow many values? "))
    >> except: #naked exception is not really good programming
    >> print "Invalid input, exiting..."
    >> sys.exit(1)

    >
    >Please don't _ever_ advocate this programming style! Wrapping
    >something in a try/except that emits a generic message and terminates
    >is a bad idea - the default behaviour, if you simply let the exception
    >happen, is to emit a very useful message and terminate. Never test for
    >any error condition you're not prepared to handle, as the BOFH advised
    >his boss.
    >

    Note: I DID include a comment that this was NOT good style.
    --
    Wulfraed Dennis Lee Bieber AF6VN
    HTTP://wlfraed.home.netcom.com/
    Dennis Lee Bieber, Oct 4, 2013
    #6
  7. On Fri, Oct 4, 2013 at 9:15 AM, Dennis Lee Bieber <> wrote:
    > On Thu, 3 Oct 2013 10:25:47 +1000, Chris Angelico <>
    > declaimed the following:
    >
    >>On Thu, Oct 3, 2013 at 9:47 AM, Dennis Lee Bieber <> wrote:
    >>> try:
    >>> numItems = int(raw_input("\n\nHow many values? "))
    >>> except: #naked exception is not really good programming
    >>> print "Invalid input, exiting..."
    >>> sys.exit(1)

    >>
    >>Please don't _ever_ advocate this programming style! Wrapping
    >>something in a try/except that emits a generic message and terminates
    >>is a bad idea - the default behaviour, if you simply let the exception
    >>happen, is to emit a very useful message and terminate. Never test for
    >>any error condition you're not prepared to handle, as the BOFH advised
    >>his boss.
    >>

    > Note: I DID include a comment that this was NOT good style.


    You mentioned that bare except is a problem; I'm more looking at the
    fact that the except clause simply writes a message and terminates.
    They're two separate issues, both bad style.

    I know _you_ know it's bad style; but someone reading over this needs
    to be aware that this shouldn't normally be done.

    ChrisA
    Chris Angelico, Oct 4, 2013
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Earl Teigrob
    Replies:
    1
    Views:
    327
    Scott Allen
    Jul 9, 2004
  2. Daniel

    String comparision efficency

    Daniel, Feb 14, 2005, in forum: Java
    Replies:
    14
    Views:
    1,804
    Daniel
    Feb 16, 2005
  3. Daniel T.
    Replies:
    2
    Views:
    322
    Daniel T.
    Oct 19, 2004
  4. Gernot Frisch
    Replies:
    3
    Views:
    299
    Efrat Regev
    Jan 24, 2005
  5. Replies:
    1
    Views:
    253
    Farshid Lashkari
    Nov 10, 2004
Loading...

Share This Page