What's the problem with my Python script? - python

I'm trying to use Python to solve my maths homework (you have a two digit number ab, and ab+ba=88) and my program doesn't work.
a=10
b=10
for i in range(100):
a+=1
for i in range(100):
b+=1
if int(str(a+b))+int(str(b+a))==88:
print((str(a+b))+"+"+str(b+a))
It gives the output of 44. This isn't the good answer, because a and b have to be different numbers, but I didn't code that restriction yet. More important, the code should find 26;62 and other solutions. How can I find all the solutions?
I know the answers, but I want to solve it in this way too.

If I understand correctly, you have a two digit number ab such that ab + ba = 88
Ex) For "ab" = 26 --> 26 + 62 = 88.
If that is the case, this is the solution I propose the solution:
for a in range(10): # Iterate over ten's place values [0 to 9]
for b in range(10): # Iterate over one's place values [0 to 9]
ab = str(a)+str(b) # Construct the string "ab"
if (int(ab) + int(ab[::-1]) == 88): # Test if ab + ba = 88
print(ab + " + " + ab[::-1]) # Print the successful value of ab
The logic is that you construct a string ab by combining the possible values of 0 to 10 in each of the ten's and one's place of the two digit number. Then, test if the integer value of ab and its reverse, ba, are equal to 88.
OUTPUT:
08 + 80
17 + 71
26 + 62
35 + 53
44 + 44
53 + 35
62 + 26
71 + 17
80 + 08
NOTE: This method uses a string from the get go in order to avoid the many calls to int(str()).
NOTE: In Python, the operator [::-1] returns the reverse of the string. Just a convenient trick!

You have a couple of logic problems here. The first is your loop control. You start with
a=10
for i in range(100):
a+=1
This will run a over the range 10 to 10+100. Now, for each value of a, you do:
b=10
...
for i in range(100):
b+=1
First of all, you've changed the value of i, which the outer loop is still trying to use. This is the first problem, the one that's killing your current program. Second, if you fix this by changing the loop index to j (for instance), then you will increment b 100*100 times, so it ends up at 10010.
On top of this, a and b are never individual digits! You've started each as a 2-digit number.
Instead, make two changes:
Put the values you actually want into the for loop.
Use strings, not integers, if that's what you're trying to do.
for a in "0123456789":
for b in "0123456789":
if int(a+b) + int(b+a) == 88:
This code makes 2-digit strings. Another way is to work with the single-digit integers, but then use algebra to make the 2-digit numbers:
if (10*a + b) + (10*b + a) == 88:
Finally, you can simplify the entire process by doing basic algebra on the above expression:
(10*a + b) + (10*b + a) == 88
11*a + 11*b == 88
a + b = 8
From here, you note simply that b = 8-a, and you can reduce your program to a single loop.

Let's walk through what your code does.
First you assign both a and b to be 10
a=10
b=10
Then you start a loop that will run 100 times, each time it runs it will increment a by one
for i in range(100):
a+=1
Then you start a nested loop which will run 100 times each time the outer loop runs once and increments b on each loop. It is important to note that because you have defined b outside of the scope of this loop, it will keep growing. The second time the outer loop runs, b is going to start at 110
What you need to know here is that python is a weakly typed language. Variables take on the same type as the data assigned to them. a and b are integers, so you can already perform mathematical operations on them. Also, there's no reason to typecast the same variable twice in one spot. you should write the if statement like this:
if a + b + b +a == 88:
You can see more easily now that all it is checking is if (a + b) * 2 is equal to 80
Finally you output your answer but, do to the commutative property of addition, you're always going to show the same sum + itself
print((str(a+b))+"+"+str(b+a))
What I would recommend doing here, besides cleaning up your if statement, is resetting b each time the outer loop runs. I'm also unclear why you've instantiated your variable to equal 10 but that's your business.
Try this:
a=10
for i in range(100):
b=10
a+=1
for i in range(100):
b+=1
if a+b == 88:
print((str(a))+"+"+str(b))

Use this code to understand:
a=10
b=10
for i in range(100):
a+=1
for i in range(100):
b+=1
if int(str(a+b))+int(str(b+a))==88:
print(a)
print(b)
print((str(a+b))+"+"+str(b+a))
break;
Output:
11
33
44+44
So:
A = 11
B = 33

Related

Gaussian Addition - Python Challenge

I am currently working on some beginner python challenges, I just finished a gaussian addition challenge. I was able to get the output that the challenge was looking for, but it seems like I over complicated things.
The challenge is as follows:
Write a program that passes a list of numbers to a function.
The function should use a while loop to keep popping the first and last numbers from the list and calculate the sum of those two numbers.
The function should print out the current numbers that are being added, and print their partial sum.
The function should keep track of how many partial sums there are.
The function should then print out how many partial sums there were.
The function should perform Gauss' multiplication, and report the final answer.
Prove that your function works, by passing in the range 1-100, and verifying that you get 5050.
gauss_addition(list(range(1,101)))
Your function should work for any set of consecutive numbers, as long as that set has an even length.
Bonus: Modify your function so that it works for any set of consecutive numbers, whether that set has an even or odd length.
My function is as follows:
def gauss(numbers):
for number in numbers:
while len(numbers) > 0:
num1 = numbers.pop(0)
print(num1)
num2 = numbers.pop(-1)
print(num2)
calc = num1 + num2
print(str(num1) + " + " + str(num2) + " = " + str(calc))
print("Final answer is: " + str(num1 * calc))
gauss(list(range(1,101)))
Can someone explain how I can simplify this function without the use of python modules? I understand how the function that I wrote is working, but I also want to know if there is an easier, "more condensed" way of achieving this.
I should specify that I only know the basics of python...
Using list to approach this problem seems to be too expensive, for the reason of repeatedly pop will be costly as cited in early notes.
So instead of it, you can consider using collections module deque which will allow you to do the operations (pop) in both end efficiently.
Note - it will work well if the list is even-sized, but that's part of requirements already.
So the solution will be like this:
#
from collections import deque
dq = deque(range(1, 101)) # create a list (dq list)
total = 0
count = 0
while dq:
x, y = dq.popleft(), dq.pop()
print(x, y, x+y, end='\t')
count += 1 # how many partial sum?
print(count)
total += (x+y)
print(f' final total: {total} ')
Outputs: (partial - it's too long)
1 100 101 1
2 99 101 2
3 98 101 3
4 97 101 4
5 96 101 5
...........
...........
48 53 101 48
49 52 101 49
50 51 101 50
final total: 5050

Program not showing all values in for loop

i have started learning python and i have problem.
I learn for loops and i am a little bit confused.
I tried this:
for i in range(0,12,3):
print(i)
Why program is not showing 12 value?
In other languages e.g java it works.
Anyone help?
The upper bound of range is non-inclusive. From the documentation:
For a positive step, the contents of a range r are determined by the formula r[i] = start + step*i where i >= 0 and r[i] < stop.
Read more here.
Java's equivalent:
IntStream.range(0, 12 / 3).map(x -> x * 3).forEach(System.out::print);
Also does not include the upper bound. This will also print 0 3 6 9, not 12.
The upper bound of a range is not included. The main advantage is that range(len()) "just works" without having to subtract 1. For example:
>>> x = 'abcd'
>>> for i in range(len(x)):
... print(i, x[i])
...
0 a
1 b
2 c
3 d

How to set index as variables?

I am building a function, which contains many loops and conditions in it.
The input of the function is an element of a list.
I want the function to generate the result so that the nex time I don't need to run through those loop. The real code is really large so I pasted the main lines as follows, which is a toy model of the real code:
a=[1,2,3,4,5,6,7]
def ff(x):
b=0
for i in range(10000):
for k in range(10000):
if k/2 >20:
for j in range(1000):
if j**2-j>1:
b += a[x]^2+a[x]
return b
ff(2)
So, in fact the result of ff should be simple, but due to the loops and conditions it runs really slow. I don't want to run through the loops each time I call ff.
A bit more like the idea that the function is a tensor in tensorflow, and index is the feed value. The structure is built first and then can be executed with different feed in values. Maybe what I want is symbolic computation.
Is there a way so that I can store the result as a sturcture and next time I just feed in the value of the index.
I cannot simply feed the values of a, since a can be some other shapes.
Your code is equivalent to (if you'll start analyzing what each one of the loops is actually doing...):
def ff(x):
return 995900780000 * (a[x]^2+a[x])
This code should run very fast...
The condition k/2 >20 can be restated as k > 40; so rather than starting the k-loop from 0, start it from 41 and eliminate that condition. Likewise, the condition j**2 - j > 1 implies that you are only interested in j >= 2 since one solution of that is less than 0 (and you aren't interested in those values and the other is about 1.6 and the first integer greater than that is 2). So start the j loop from 2 and eliminate that condition. Finally, your b value does not depend on i, k or j, so make the rhs 1. You now have
def ff(x):
b=0
for i in range(10000):
for k in range(41, 10000):
for j in range(2, 1000):
b += 1
return b
The j loop will run 1000 - 2 = 998 times; k will run 10000 - 41 = 9959 times and i will run 10000 times. The total number of times that b will be incremented is 998*9959*10000 = 99390820000. That's how many times you will have added your rhs (a[x]**2 + a[x]) together...which, except for a different value, is what #alfasin is pointing out: your loops are effectively adding the rhs 99390820000 times so the result will be 99390820000*(a[x]**2 + a[x]) and now you never have to run the loop. Your whole function reduces to:
def ff(x):
return 99390820000*(a[x]**2 + a[x])
The "structure" of adding something within nested loops is to multiply that something by the product of the number of times each loop is run. So if you had
b = 0
for i in range(6):
for j in range(7):
b += 1
the value of b would be 6*7...and the answer (as always ;-)) is 42. If you were adding f(x) to b each time then the answer would be 42*f(x).

I'm brand new and working on Project Euler #2 in python

The goal is to sum up every even number up to 4 million.
I thought this would work but the program gets stuck running. Think it has to do with the if statement, but lost otherwise. Here's what I have.
list = []
a, b = 0, 1
while b <40:
if b%2 == 0:
list.append(b)
a, b = b, a+b
t=sum(list)
print(t)
This here is your biggest problem:
a, b = b, a+b
It has so much potential to mess up your loop! And like others mentioned it doesn't even update anything when b is odd, only when it is even, and then you're stuck.
Why not do this the simple way, with range:
mysum = sum([i for i in range(0, 40, 2)])
Will take care of everything with one line (and of course, replace 40 with 4,000,001 for your question, if you want to include the number 4,000,000 as well. If you just want everything up to it but not to include it, use just 4,000,000)
a, b = b, a+b
This line only runs if b % 2 == 0. I think you meant to run it every time. It should be indented one layer further out.
One can also use the mathematics rule where the sum of integers between 1 and n is equal to n*(n+1)/2. If we want to sum only even numbers, it is like considering only half the number to sum and multiply the result with two.
fSumEvenNumbers = lambda x: (x//2)*(x//2+1)
This would give
fSumEvenNumbers(40000000)
which is equivalent to
(2e7)**2 + 2e7
4e14 + 2e7
400000020000000

How to create a loop that shuts down when given answer in python?

what I am wanting to do is randomly generate two numbers that equal a given number. Yet to allow for this to get the desired answer I want it to be random. That is the problem.
a=(1,2,3,4,5,6,7,8,9,)
from random import choice
b=choice(a)
c=choice(b)
d= c+b
if d == 10:
#then run the rest of the program with the value's c and b in it
#probably something like sys.exit goes here but I am not sure to end \/
else:
# i have tryied a few things here but I am not sure what will loop it around*
(thanks for the help :D)
I have know created a list called 'right' and know trying to append values a and b to the list yet that is not working. For I am knowing running the program 'in for trail in range(100)' so I get the answer. Yet the values are not appending into the new list right. Which is the problem. Then what I am going to do it read values 0 and 1 in the list right and then use them.(sorry its not that well done for at school)
This is for fractions not adding to a given variable. This bit second but is.
import sys
right=(0)
y=x+x
from trail in range(y)
a=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
from random import choice
A=choice(a)
B=choice(a)
d=A/B
if d==1:
right.append(A)
right.append(B)
else:
x.append(1)
from random import choice
a = range(1, 10)
b = c = 0
while b + c != 10:
b = choice(a)
c = choice(a) # You meant choice(a) here, right?
But this accomplishes the same thing:
b = choice(a)
c = 10 - b
For decimal numbers betweeen 0 and 10:
from random import uniform
b = uniform(0, 10)
c = 10 - b
Maybe I'm missing the point, but there is no need of a loop to choose two random numbers that sum up to another. A randint and simple subtraction do the job:
from random import randint
def random_sum(given_number):
a = randint(1, given_number)
return a, given_number - a
This does what you describe, but the other two answers probably do what you want, since for any given digit, d, there will be only one other digit, d', s.t. d+d'=10. So my way is unnecessarily slow.
goal = 10 #the number you're trying to add up to
sum = 0
min = 1
max = 9
b = c = 0 # initialize outside your loop so you can access them afterward
while (sum != goal)
b = random.randint(min, max)
c = random.randint(min, max)
sum = b+c
but to answer the question you actually posed, in python "continue" will jump out of a conditional block or one iteration of a loop, and "break" will exit the loop completely. sys.exit() will quit python, so it's not what you want.

Categories