How can I improve this Python code to be more efficient? - python-2.7

I've just started to learn Python (my first dabble in coding) and this is my first time posting... I hope I'm not abusing the forum by asking this question (I'm essentially asking an expert to help me learn). Please let me know if this is frowned upon in the community.
For this assignment from a Michigan open course, I've been instructed to ask a user for input until the user enters "done", at which point the code should calculate the largest, smallest, sum, and average. In all my test-runs, it's worked fine. But I feel like there's probably a much simpler way to write this code. Can anyone offer suggestions for improvement?
largest = None
smallest = None
count = 0
sum = 0
while True:
try:
num = raw_input("Enter a number: ")
if num == "done" : break
num = float(num)
count = count + 1
sum = sum + num
avg = sum/count
if largest is None:
largest = num
if smallest is None:
smallest = num
if num < smallest:
smallest = num
elif num > largest:
largest = num
continue
except: print 'Invalid input'
print "Maximum is", int(largest)
print "Minimum is", int(smallest)
print "Count:", int(count)
print "Sum:", int(sum)
print "Average:", avg

Well there are a few things here:
you can drop the continue statement since it is the end of the loop anyway;
you can compress the if statements into if largest is None or num > largest: this will shortcircuit and make the loop smaller;
you can use x += y instead of x = x + y; and
you do not have to calculate the average inside the loop; calculating it once when the loop finishes, is enough.
So:
largest = None
smallest = None
count = 0
sum = 0
while True:
try:
num = raw_input("Enter a number: ")
if num == "done" : break
num = float(num)
count += 1
sum += num
if largest is None or num > largest:
largest = num
if smallest is None or num < smallest:
smallest = num
except: print 'Invalid input'
print "Maximum is", int(largest)
print "Minimum is", int(smallest)
print "Count:", int(count)
print "Sum:", int(sum)
print "Average:", sum/count
But in terms of big oh, you cannot improve much: calculating the sum, etc. simply require O(n) and it also costs O(n) to read the input anyway.
Furthermore some software engineering advice: don't use the blanket exception, always specify the exception you expect so:
largest = None
smallest = None
count = 0
sum = 0
while True:
try:
num = raw_input("Enter a number: ")
if num == "done" : break
num = float(num)
count += 1
sum += num
if largest is None or num > largest:
largest = num
if smallest is None or num < smallest:
smallest = num
except ValueError: print 'Invalid input'
print "Maximum is", int(largest)
print "Minimum is", int(smallest)
print "Count:", int(count)
print "Sum:", int(sum)
print "Average:", sum/count

An alternative approach to accomplish this is to store all of the inputs in a list, and then use the built-ins min(),max(),len() and sum() to find values:
num=raw_input("Enter a number: ")
nums=[]
while num!="done": #check if user has finished entering inputs
try:
nums.append(int(num)) #append the input as an integer to a list
num=raw_input("Enter a number: ") #get another input
except ValueError:
print "Invalid input"
print "Maximum is",max(nums)
print "Minimum is",min(nums)
print "Count:",len(nums)
print "Sum: ",sum(nums)
print "Average: ",sum(nums)/len(nums)
Output:
Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 4
Enter a number: 5
Enter a number: 6
Enter a number: done
Maximum is 6
Minimum is 1
Count: 6
Sum: 21
Average: 3.5

Related

Why is the elif statement taking priority over my if statement?

So I've got a number guessing game, all my previous code works fine, and you can probably see that I have the randomly generated number printed on the screen. But when I guess the number correctly I still get told I am wrong?
num = randrange(0, 100)
if num > 0 and num < 50:
print("The number is greater than 0 but smaller than 50")
elif num > 50 and num < 100:
print("The number is smaller than 100 but greater than 50")
print(num)
print('Start Guessing')
a = input()
a = input()
if a == num:
print ("You got the correct number, woohoo")
elif num > 0 and num < 20:
print ("Hint: The number is bigger than 0 but smaller than 20")
elif num > 20 and num < 40:
print ('Hint: The number is bigger than 20 but smaller than 40')
elif num > 40 and num < 60:
print ('Hint: The number is bigger than 40 but smaller than 60')
elif num > 60 and num < 80:
print ('Hint: The number is bigger than 60 but smaller than 80')
elif num > 80 and num < 100:
print ('Hint: The number is bigger than 80 but smaller than 100')
Sorry for the weird looking code, I've never used this site before.
Your code appears to be Python. You should indicate that in a tag. Also, since Python if statements rely on indentation you should post your code with proper indentation.
In the code:
a = input()
if a == num:
You are comparing a string to a number. You should cast a to an int.
if int(a) == num:

Program determines how many numbers are positive, negative, or zeros

(Edit: Using python 2.7) I’m trying to get the user to input 10 numbers and the program needs to count and determine how many are negative, positive, or zeros.
However, everytime I run the program, it doesn’t give me the right number of negative or positive (or zero) numbers
i =[]
for i in range(10)
i = input('Enter Next Number: ')
n = 0
p = 0
z = 0
if (i > 0):
p = p+1
elif (i < 0):
n = n+1
elif (i == 0):
z = z+1
print "The number of negative numbers is",n
print "The number of positive numbers is",p
print "The number of zeros is",z
As Johnny Mopp suggested in his comment, you need to declare your counters outside of the loop. If you declare them inside, they are reset at every iteration and you are only counting the last number input by the user
n = 0
p = 0
z = 0
for i in range(10):
i = input('Enter Next Number:')
if (i > 0):
p = p+1
elif (i < 0):
n = n+1
else:
z = z+1
print "The number of negative numbers is",n
print "The number of positive numbers is",p
print "The number of zeros is",z
You will also want to convert the inputs to integers. If you really wish to add them to the list you will then need to iterate through the list after gathering all of the inputs. If retaining the values in a list is not needed #Bentaye answer will work just fine.
i =[]
n = 0
p = 0
z = 0
for num in range(10):
x = int(input('Enter Next Number: '))
i.append(x)
for y in range(len(i)):
if (i[y] > 0):
p = p+1
elif (i[y] < 0):
n = n+1
elif (i[y] == 0):
z = z+1
print ("The number of negative numbers is",n)
print ("The number of positive numbers is",p)
print ("The number of zeros is",z)

Testing integer error in while loop

I have ran into some problems while trying to combine while loop and ValueError.
Initially I wanted my program to add numbers together. When the sum of numbers has exceeded X, I would like my program to continue to else statement. At first I didn't focus on the fact that input could also be (for example) string.
number = 1
while number < 10:
add = int(raw_input("Enter a number to add: "))
number += add
print number
else:
print "Number is greater than 10"
I tried combining the first code with try/except and ValueError to accept integers as the only inputs. Second code will not continue to else statement when sum of numbers exceeds X. Could someone please explain why this is not working?
number = 1
while number < 10:
while True:
try:
add = int(raw_input("Enter a number: "))
number += add
print number
except ValueError:
print "Please enter a number"
else:
print "Number is greater than 10"
Thank You.
there's an extra while True: loop resulting in an infinte loop.
Remove it and your code will work fine.
Another example where while(condition) (with condition not True) leads to mistakes: you have to ensure that the loop will be entered once, sometimes by initalizing your condition artificially. I would write that instead
number = 1
while True:
try:
add = int(raw_input("Enter a number: "))
number += add
print number
if number>10:
break
except ValueError:
print "Please enter a number"
print "Number is greater than 10"

Multiplying the list of numbers without multiply

I am trying to multiply the elements in the list so that they give me their total but with only using addition and subtraction. For example, a list of [1,3,6,8] will have the output 144. The code I have so far is:
numbers = [1,3,6,8]
def no_sign(numbers):
total = 0
answer = 0
for i in range(len(numbers)):
first_number = numbers[i]
print str(first_number) + ' pop'
for j in range(first_number):
#print first_number
answer = first_number + answer
print str(first_number) + ' firstnum'
print str(answer)+ " answeer "
total = total + answer
print str(total) + " total"
return total
print no_sign(numbers)
This only gives me 110, which isn't enough. Any suggestions?
Your code takes the square of each element and adds them up. Hence you are getting 1 + 9 + 36 + 64 = 110
Since you want to do same thing couple times, writing your multiplication(num1, num2) function yourself with only addition and using that when multiplying would be much better choice.
Multiplication of two numbers, as you know, is adding firstNumber to itself secondNumber of times. S you can write multiplication function like below and use it on a list.
def multiplication(num1, num2):
answer = 0
for i in range(num2):
answer += num1
return answer
numbers = [1,3,6,8]
def no_sign(numbers):
total = 1
for number in numbers:
total = multiplication(total, number)
return total
print no_sign(numbers)

Condition for Armstrong number

Can anybody tell me what is wrong with my code for checking whether a number is an Armstrong number?
n=input('Enter the number=')
m=n
s=0
while n>0:
d=n%10
s=s+d**3
n=n*10
if m==s:
print'The number is an Armstrong number'
else:
print'The number is not an Armstrong number'
I got the program to work eventually. Turns out I had kept typing the statement n=n/10 as n=n*10. Mistakes do happen sometimes:)
n = input('Enter the number=')
m = n
s = 0
while n>0:
d = n%10
s += d**3
n /= 10
if m==s:
print'The number is an Armstrong number'
else:
print'The number is not an Armstrong number'
sum = 0
no = int(raw_input("Enter the the number to check it is armstrong on or not :"))
pow_no = len(str(no))
check = no
print "#################Method -I Result##############"
while 0<no:
sum = sum +((no%10)**pow_no)
no = no / 10
if check == sum:
print "%s is Armstrong"%check
else:
print "%s is not Armstrong"%check
print "################Method -II Result#############"
for i in str(no):
sum = sum + (int(i)**pow_no)
if check == sum:
print "%s is Armstrong"%check
else:
print "%s is not Armstrong"%check