I'm making this calculator using python 3, and this is what I have so far:
print("Welcome to Calculator!")
class Calculator:
def addition(self,x,y):
added = x + y
return added
def subtraction(self,x,y):
subtracted = x - y
return subtracted
def multiplication(self,x,y):
multiplied = x * y
return multiplied
def division(self,x,y):
divided = x / y
return divided
calculator = Calculator()
print("1 \tAddition")
print("2 \tSubtraction")
print("3 \tMultiplication")
print("4 \tDivision")
operations = int(input("What operation would you like to use?: "))
x = int(input("How many numbers would you like to use?: "))
if operations == 1:
a = 0
sum = 0
while a < x:
number = int(input("Please enter number here: "))
a += 1
sum = calculator.addition(number,sum)
print("The answer is", sum)
if operations == 2:
s = 0
diff = 0
while s < x:
number = int(input("Please enter number here: "))
s += 1
diff = calculator.subtraction(number,diff)
print("The answer is", diff)
if operations == 3:
m = 0
prod = 1
while m < x:
number = int(input("Please enter number here: "))
m += 1
prod = calculator.multiplication(number, prod)
print("The answer is", prod)
if operations == 4:
d = 0
quo = 1
while d < x:
number = int(input("Please enter number here: "))
d += 1
quo = calculator.division(number, quo)
print("The answer is", quo)
Addition and multiplication works just fine, subtraction and division are the problems here. One example for subtraction is if I tried using two numbers, 9 and 3, I would get -6... That is definitely incorrect. As for division, if I tried dividing two numbers, 10 and 2, I would get 0.2, which is also wrong. For division I've tried switching number and quo, and with the same problem (10 / 2), I would get 0.05... Also, I don't want to use any of the built-in functions for python, so just help me fix these errors the easiest way possible.
Your algorithm is wrong for subtraction and division. Let's look at subtraction:
s = 0
diff = 0
while s < x:
number = int(input("Please enter number here: "))
s += 1
diff = calculator.subtraction(number,diff)
Step through this in your head. If you're operating on two numbers (9 and 3), you will get diff = 9 - 0 = 9 on the first iteration and diff = 3 - 9 = (-6) on the next. That won't work.
Subtraction is addition if all the terms (but the first) are negated. If you think about it like that it's fairly simple:
terms = []
for _ in range(x): # this is a more idiomatic way to iterate `x` times
number = int(input("Please enter number here: "))
terms.append(number)
head, tail = terms[0], terms[1:]
result = head
for term in tail:
result -= tail
return result
You can certainly condense this further
terms = [int(input("Please enter number here: ")) for _ in range(x)]
terms[1:] = [x * (-1) for x in terms[1:]]
return sum(terms)
Similarly with division, step through in your head:
d = 0
quo = 1
while d < x:
number = int(input("Please enter number here: "))
d += 1
quo = calculator.division(number, quo)
print("The answer is", quo)
With 10 and 2, you get first quo = 10 / 1 = 10 then quo = 2 / 10 = 0.2. Like we can generalize subtraction to be tail-negated addition, we can generalize division to be tail-inverted multiplication.
24 / 2 / 3 / 4 == 24 * (1/2) * (1/3) * (1/4)
And we can write the algorithm similarly.
terms = [int(input("Please enter number here: ")) for _ in range(x)]
head, tail = terms[0], terms[1:]
result = head
for term in tail:
result /= term
Note that all of these can also be written with functools.reduce and one of the operator functions
terms = [int(input("Number please! ")) for _ in range(int(input("How many numbers? ")))]
sum_ = functools.reduce(operator.add, terms)
diff = functools.reduce(operator.sub, terms)
prod = functools.reduce(operator.mul, terms)
diff = functools.reduce(operator.truediv, terms)
Consider the subtraction option (with the test input you supplied in the question):
We say we give 2 numbers.
For the first number we give 9. So diff = number - diff = 9 - 0 = 0.
Now we enter the next number, 3, therefore diff = number - diff = 0 - 3 = -3, now if it were to work correctly, we need to switch around calculation of diff, so it should be diff = diff - number, and now if we run it it will give us -12, which is the technically the correct answer, as we are asking -9-3 = -12, now I'm assuming you actually want to find 9-3 = 6, the only "simple" fix to this, is to set diff as the first number, in this case 9, and then doing what I said above (giving the expected 9 - 3 = 6) The reason the division function does not work is the same as subtraction, and you can use similar logic as above to fix it.
In addition to this, making an addition, subtraction, multiplication and division method defeats the point of methods, that is to prevent using the same code several times, and having to write less, but in this case, running calculator.addition(a, b) is longer and less flexible than simply using a + b
Also python has an in-built calculator function, called eval, which will take a string and run it as python code, meaning it supports BIDMAS, several operators, mathematical functions (assuming you have imported them), etc.
Related
I've got an assignment which requires me to use a Python recursive function to output the factors of a user inputted number in the form of below:
Enter an integer: 6 <-- user input
The factors of 6 are:
1
2
3
6
I feel like a bit lost now and have tried doing everything myself for the past 2 hours but simply cannot get there. I'd rather be pushed in the right direction if possible than shown where my code needs to be changed as I'd like to learn
Below is my code:
def NumFactors(x):
for i in range(1, x + 1):
if x == 1:
return 1
if x % i == 0:
return i
return NumFactors(x-1)
x = int(input('Enter an integer: '))
print('The factors of', x, 'are: ', NumFactors(x))
In your code the problem is the for loop inside the method. The loop starts from one and goes to the first if condition and everything terminates there. That is why it only prints 1 as the output this is a slightly modified version of your own code. This should help. If you have any queries feel free to ask.
def factors(x):
if x == 1:
print(1 ,end =" ")
elif num % x == 0:
factors(x-1)
print(x, end =" ")
else:
factors(x-1)
x = num = int(input('Enter an integer: '))
print('The factors of', x, 'are: ',end =" ")
factors(x)
Since this question is almost 3 years old, I'll just give the answer rather than the requested push in the right direction:
def factors (x,c=1):
if c == x: return x
else:
if x%c == 0: print(c)
return factors(x,c+1)
Your recursion is passing down x-1 which will not give you the right value. For example: the number of factors in 6 cannot be obtained from the number of factors in 5.
I'm assuming that you are not looking for the number of prime factors but only the factors that correspond to the multiplication of two numbers.
This would not normally require recursion so you can decide on any F(n) = F(n-1) pattern. For example, you could use the current factor as a starting point for finding the next one:
def NumFactors(N,F=1):
count = 1 if N%F == 0 else 0
if F == N : return count
return count + NumFactors(N,F+1)
You could also optimize this to count two factors at a time up to the square root of N and greatly reduce the number of recursions:
def NumFactors(N,F=1):
count = 1 if N%F == 0 else 0
if N != F : count = count * 2
if F*F >= N : return count
return count + NumFactors(N,F+1)
I'm new to programming. While trying to solve this problem, I'm getting the wrong answer. I checked my code a number of times but was not able to figure out the mistake. Please, help me on this simple problem. The problem is as follows:
Given a positive integer N, calculate the sum of all prime numbers between 1 and N (inclusive). The first line of input contains an integer T denoting the number of test cases. T testcases follow. Each testcase contains one line of input containing N. For each testcase, in a new line, print the sum of all prime numbers between 1 and N.
And my code is:
from math import sqrt
sum = 0
test = int(input())
for i in range(test):
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(max)) + 1
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
print(sum)
For input 5 and 10, my code is giving output 6 and 48 respectively, while the correct answer is 10 and 17 respectively. Please, figure out the mistake in my code.
Here, I implemented simple program to find the sum of all prime numbers between 1 to n.
Consider primeAddition() as a function and ip as an input parameter. It may help you to solve your problem.Try it.
Code snippet:
def primeAddition(ip):
# list to store prime numbers...
prime = [True] * (ip + 1)
p = 2
while p * p <= ip:
# If prime[p] is not changed, then it is a prime...
if prime[p] == True:
# Update all multiples of p...
i = p * 2
while i <= ip:
prime[i] = False
i += p
p += 1
# Return sum of prime numbers...
sum = 0
for i in range (2, ip + 1):
if(prime[i]):
sum += i
return sum
#The program is ready... Now, time to call the primeAddition() function with any argument... Here I pass 5 as an argument...
#Function call...
print primeAddition(5)
This is the most broken part of your code, it's doing the opposite of what you want:
res = x%y
if res==0:
sum = sum + x
break
You only increment sum if you get through the entire loop without breaking. (And don't use sum as you're redefining a Python built-in.) This can be checked using the special case of else on a for loop, aka "no break". I've made that change below as well as corrected some inefficiencies:
from math import sqrt
T = int(input())
for _ in range(T):
N = int(input())
sum_of_primes = 0
if N < 2:
pass
elif N == 2:
sum_of_primes = 2
else:
sum_of_primes = 2
for number in range(3, N + 1, 2):
for odd in range(3, int(sqrt(number)) + 1, 2):
if (number % odd) == 0:
break
else: # no break
sum_of_primes += number
print(sum_of_primes)
OUTPUT
> python3 test.py
3
5
10
10
17
23
100
>
A slight modification to what you have:
from math import sqrt
sum = 0
test = int(input())
max = int(input())
for x in range(test,max+1):
if x == 1:
pass
else:
half = int(sqrt(x)) + 1
for y in range(2,half):
res = x%y
if res==0:
break
else:
sum = sum + x
print(sum)
Your biggest error was that you were doing the sum = sum + x before the break rather than outside in an else statement.
PS: (although you can) I'd recommend not using variable names like max and sum in your code. These are special functions that are now overridden.
Because your logic is not correct.
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
here you check for the factors and if there is a factor then adds to sum which is opposite of the Primes. So check for the numbers where there is no factors(except 1).
from math import sqrt
test = int(input())
for i in range(test):
sum = 0
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(x)) + 1
if all(x%y!=0 for y in range(2,half)):
sum = sum + x
print(sum)
First of all, declare sum to be zero at the beginning of the for i loop.
The problem lies in the if statement at almost the very end of the code, as you add x to the sum, if the res is equal to zero, meaning that the number is indeed not a prime number. You can see that this is the case, because you get an output of 6 when entering 5, as the only non-prime number in the range 1 to and including 5 is 4 and you add 2 to the sum at the beginning already.
Last but not least, you should change the
half = int(sqrt(max)) + 1
line to
half = int(sqrt(x)) + 1
Try to work with my information provided and fix the code yourself. You learn the most by not copying other people's code.
Happy coding!
I believe the mistake in your code might be coming from the following lines of code:
for x in range(3,max+1):
half = int(sqrt(max)) + 1
Since you are looping using x, you should change int(sqrt(max)) to int(sqrt(x)) like this:
for x in range(3,max+1):
half = int(sqrt(x)) + 1
Your code is trying to see if max is prime N times, where you should be seeing if every number from 1-N is prime instead.
This is my first time answering a question so if you need more help just let me know.
value = input("Enter the binary value to convert to a decimal number.")
prod = 0
power = 0
ans = 0
for i in range (int(value)):
prod = ((int(value[*right most digit here*])) * ((2**power)))
ans = prod + ans
prod = 0
power + 1
else:
print (ans)
I am trying to create a binary calculator.
I believe I have the power part of the equation working as it begins with 2 ^ 0, then 2 ^ 1 for the next digit and so on. But I am having trouble getting the first part of the equation, the right most digit of the value inputted.
So let's say, 0101 was inputted. I want 1 * ( 2 ^ 0 ) in the first loop, 0 * ( 2 ^ 1) in the second loop, and so on; right to left. So with how indexing works in Python, how can I reverse index it so [4] is in the first loop, then [3] in the second loop, and so on.
Thanks for help.
However there are better options available, i am assuming you are clearing your basics. Following can be the options:
Note : You should use len(value) instead of int(value) in the loop.
# 1. When starting the loop from 0 (i.e. i=0). you can use ( len(value) - i )th index.'
for i in range (len(value)):
prod = ((int(value[len(value) - i - 1])) * ((2**power)))
ans = prod + ans
prod = 0
power = power + 1
# 2. Python also supports negative indexing, So you may run a loop from -1 to -len(value).
for i in range (-1,-len(value) - 1,-1):
prod = ((int(value[i])) * ((2**power)))
ans = prod + ans
prod = 0
power = power + 1
# 3. You can reverse the whole string in your first step and then loop from 0 to len(value)-1.
value = reversed(value)
for i in range (len(value)):
prod = ((int(value[i])) * ((2**power)))
ans = prod + ans
prod = 0
power = power + 1
But there are some bugs in the code (or may be lack on information). This code works only for unsigned integers. If you want it to work on signed numbers as well, you have to take 2's complement into consideration.
Below is a very simple code that works with signed numbers too (in case needed):
#convert binary string into decimal value. Works on 2's complement.
def binToDecimal(s):
neg = False
if s[0] == '1':
s = twosComp(s)
neg = True
#compute the decimal value
val = reduce(lambda x,y : int(x)*2+1 if y=='1' else int(x)*2,'0'+s)
#negate the value if the first bit is 1
return -val if neg else val
#return the 2's complement string
def twosComp(s):
s = list(s[::-1])
#take 1's complement
s = ['1' if i=='0' else '0' for i in s]
#take 2's complement
for i in range(len(s)):
if s[i] == '0':
#no carry will be generated in this case, so we break it.
s[i] = '1'
break
else:
s[i]='0'
# return 2's complement string
return ''.join(map(str,s))[::-1]
value = input("Enter the binary value to convert to a decimal number.")
power = 0
ans = 0
for i in reversed(value):
prod = int(i) * (2**power)
ans = prod + ans
power += 1
else:
print(ans)
Improved your code while keeping it as close to your code as possible. Your for loop was creating a list of 1 to whatever the value we input, that's not what you should be doing. One way of doing is, treating your input as a string (which basically is a list that can be iterated through) reverse it so you go from right to left, then do your operation on it on each value. You were trying to get the index of the location of the value input right? Why? Python is beautiful where you most likely don't need to directly tell the index of something.
value = input("Enter the binary value to convert to a decimal number.")
prod = 0
power = 0
ans = 0
for i in range(int(len(value))-1):
prod = ((int(value[-1])) * ((2**power)))
ans = prod + ans
prod = 0
power + 1
else:
print (ans)
You were doing the range of the value and not the input len so we use len() to get the length of the string that was inputted. -1 is there because the length of a string can be 3 for input 001 but if indexing 3 would be out of bounds because indexing starts at 0 not 1
Note that in Python a negative index value is accepted. Negative index means starts from the end of the list and count backwards, so I think that was the answer you were looking for.
For example if we have the list my_list=['a','b','c'] and we call my_list[-2] it will return 'b'
You have some mistakes in your code, so replace it with this:
value = input("Enter the binary value to convert to a decimal number: ")
value = int(value) # conversion from string to number
power = 0
ans = 0
while(value > 0):
lastDigit = value % 10 # last digit
value = value // 10 # cutting off last digit (for next iteration)
prod = lastDigit * (2 ** power)
ans = prod + ans
power = power + 1
print (ans)
Last digit is calculated as the remainder after division by 10 (value % 10)
and is cutting of by integer division by 10 (value // 10) - as in first grades of basic school: 27 % 10 = 7 27 // 10 = 2
Simpler way to achieve this with be to mention base as 2 with int(). For example:
>>> num = '110'
>>> int(num, 2)
6
In case you are looking for custom solution, you may create a function as:
def binary_string_to_int(binary_string):
int_num = 0
for i in binary_string:
int_num += int(i)
int_num *= 2
return int_num / 2
Sample run:
>>> binary_string_to_int('111')
7
>>> binary_string_to_int('101')
5
I am attempting to do Project Euler problem #2. Which is:
Each new term in the Fibonacci sequence is generated by adding the previous two
terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed
four million, find the sum of the even-valued terms.
However the terminal window hangs when I use the following code with 4000000. Smaller numbers run ok. Is there something about this code that is really inefficient, hence the lagginess?
n = int(raw_input("Enter the start number: "))
def fib_generator():
a, b = 0, 1
yield 0
while True:
a, b = b, a + b
yield a
def even_sum(fib_seq):
seq = []
seq = [next(fib_seq) for number in range(n)]
seq = [number for number in seq if number % 2 == 0]
return sum(seq)
def start():
fib = fib_generator()
even_sum = even_sum(fib)
print even_sum
start()
You have a bug. You're generating the first 4,000,000 Fibonacci numbers, but the problem statement only asks for those Fibonacci numbers whose values are not more than 4,000,000.
Since the Fibonacci numbers grow exponentially (Fn ~ 1.618n), you're generating some numbers with a very large number of digits (log10 Fn ~ n / 5) and that will take an immense amount of time.
Fix the bug, and you'll be okay.
You just need to add logic to stop when the next fibonacci number exceeds 4000000.
Also, I spy a potential problem with this line:
def start():
fib = fib_generator()
even_sum = even_sum(fib) #<--- right here
print even_sum
It isn't good to have a variable name the same as the function name.
Yes, there is something inefficient in your code, you load a very long list into memory twice, with your two seq = ... statements. Why not try one generator expression rather than two list comprehensions? Also, you could alter your Fibonacci generator to stop at a certain number:
def fib_generator(n):
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
def even_sum(fib_seq):
seq = (number for number in fib_seq if not number % 2)
return sum(seq)
def start():
n = int(raw_input('Enter max constraint: '))
fib_seq = fib_generator(n)
even_sum1 = even_sum(fib_seq)
print even_sum1
start()
This ran pretty fast for me
lst = []
num1 = 1
num2 = 2
sum = 0
jump = 0
next = 0
while next<4000000:
next = num1 + num2
if next<4000000:
if jump ==0:
num1 = next
jump = 1
else:
num2 = next
jump = 0
if next%2 == 0:
lst.append(next)
for item in lst:
sum+=item
print ''
print "Sum: ",
print sum
I am a student in a concepts of programming class. The lab is run by a TA and today in lab he gave us a real simple little program to build. It was one where it would multiply by addition. Anyway, he had us use absolute to avoid breaking the prog with negatives. I whipped it up real quick and then argued with him for 10 minutes that it was bad math. It was, 4 * -5 does not equal 20, it equals -20. He said that he really dosen't care about that and that it would be too hard to make the prog handle the negatives anyway. So my question is how do I go about this.
here is the prog I turned in:
#get user input of numbers as variables
numa, numb = input("please give 2 numbers to multiply seperated with a comma:")
#standing variables
total = 0
count = 0
#output the total
while (count< abs(numb)):
total = total + numa
count = count + 1
#testing statements
if (numa, numb <= 0):
print abs(total)
else:
print total
I want to do it without absolutes, but every time I input negative numbers I get a big fat goosegg. I know there is some simple way to do it, I just can't find it.
Perhaps you would accomplish this with something to the effect of
text = raw_input("please give 2 numbers to multiply separated with a comma:")
split_text = text.split(',')
a = int(split_text[0])
b = int(split_text[1])
# The last three lines could be written: a, b = map(int, text.split(','))
# but you may find the code I used a bit easier to understand for now.
if b > 0:
num_times = b
else:
num_times = -b
total = 0
# While loops with counters basically should not be used, so I replaced the loop
# with a for loop. Using a while loop at all is rare.
for i in xrange(num_times):
total += a
# We do this a times, giving us total == a * abs(b)
if b < 0:
# If b is negative, adjust the total to reflect this.
total = -total
print total
or maybe
a * b
Too hard? Your TA is... well, the phrase would probably get me banned. Anyways, check to see if numb is negative. If it is then multiply numa by -1 and do numb = abs(numb). Then do the loop.
The abs() in the while condition is needed, since, well, it controls the number of iterations (how would you define a negative number of iterations?). You can correct it by inverting the sign of the result if numb is negative.
So this is the modified version of your code. Note I replaced the while loop with a cleaner for loop.
#get user input of numbers as variables
numa, numb = input("please give 2 numbers to multiply seperated with a comma:")
#standing variables
total = 0
#output the total
for count in range(abs(numb)):
total += numa
if numb < 0:
total = -total
print total
Try this on your TA:
# Simulate multiplying two N-bit two's-complement numbers
# into a 2N-bit accumulator
# Use shift-add so that it's O(base_2_log(N)) not O(N)
for numa, numb in ((3, 5), (-3, 5), (3, -5), (-3, -5), (-127, -127)):
print numa, numb,
accum = 0
negate = False
if numa < 0:
negate = True
numa = -numa
while numa:
if numa & 1:
accum += numb
numa >>= 1
numb <<= 1
if negate:
accum = -accum
print accum
output:
3 5 15
-3 5 -15
3 -5 -15
-3 -5 15
-127 -127 16129
How about something like that? (Uses no abs() nor mulitiplication)
Notes:
the abs() function is only used for the optimization trick. This snippet can either be removed or recoded.
the logic is less efficient since we're testing the sign of a and b with each iteration (price to pay to avoid both abs() and multiplication operator)
def multiply_by_addition(a, b):
""" School exercise: multiplies integers a and b, by successive additions.
"""
if abs(a) > abs(b):
a, b = b, a # optimize by reducing number of iterations
total = 0
while a != 0:
if a > 0:
a -= 1
total += b
else:
a += 1
total -= b
return total
multiply_by_addition(2,3)
6
multiply_by_addition(4,3)
12
multiply_by_addition(-4,3)
-12
multiply_by_addition(4,-3)
-12
multiply_by_addition(-4,-3)
12
Thanks everyone, you all helped me learn a lot. This is what I came up with using some of your suggestions
#this is apparently a better way of getting multiple inputs at the same time than the
#way I was doing it
text = raw_input("please give 2 numbers to multiply separated with a comma:")
split_text = text.split(',')
numa = int(split_text[0])
numb = int(split_text[1])
#standing variables
total = 0
if numb > 0:
repeat = numb
else:
repeat = -numb
#for loops work better than while loops and are cheaper
#output the total
for count in range(repeat):
total += numa
#check to make sure the output is accurate
if numb < 0:
total = -total
print total
Thanks for all the help everyone.
Try doing this:
num1 = int(input("Enter your first number: "))
num2 = int(input("Enter your second number: "))
ans = num1*num2
if num1 > 0 or num2 > 0:
print(ans)
elif num1 > 0 and num2 < 0 or num1 < 0 and num1 > 0:
print("-"+ans)
elif num1 < 0 and num2 < 0:
print("Your product is "+ans)
else:
print("Invalid entry")
import time
print ('Two Digit Multiplication Calculator')
print ('===================================')
print ()
print ('Give me two numbers.')
x = int ( input (':'))
y = int ( input (':'))
z = 0
print ()
while x > 0:
print (':',z)
x = x - 1
z = y + z
time.sleep (.2)
if x == 0:
print ('Final answer: ',z)
while x < 0:
print (':',-(z))
x = x + 1
z = y + z
time.sleep (.2)
if x == 0:
print ('Final answer: ',-(z))
print ()