Python: what's wrong with my nested loop? - python

Using the while loop, I wrote a procedure that takes as input a positive whole number, and prints out a multiplication table showing all the whole number multiplications up to and including the input number. The order in which the equations are printed matters.
for example, print_multiplication_table(2) gives:
1 * 1
1 * 2
2 * 1
2 * 2
This is my code:
def print_multiplication_table(n):
a = 1
b = 1
while a <= n:
while b <= n:
print str(a) + " * " + str(b)
b = b + 1
a = a + 1
However, this doesn't seem to work as it only print out
1 * 1
1 * 2
Does anyone know why? thanks!

You need to initialize counter for inner loop before its execution
def print_multiplication_table(n):
a = 1
b = 1 # won't do harm, but doesn't really need now
while a <= n:
b = 1 # <-- note
while b <= n:
print str(a) + " * " + str(b)
b = b + 1
a = a + 1

Consider using for in place of while:
def print_multiplication_table(n):
for a in range(1, n+1):
for b in range(1, n+1):
print str(a) + " * " + str(b)
which gives:
1 * 1
1 * 2
2 * 1
2 * 2
Using for will automatically keep track of your counter variables and avoid the type of error you encountered (this of course doesn't mean you can't make errors with for-loops, but it's easier to avoid the type of error you had)

Easier still with a Python comprehension:
>>> print '\n'.join('{} * {}'.format(a,b) for a in range(1,6) for b in range(1,6))
1 * 1
1 * 2
1 * 3
1 * 4
1 * 5
2 * 1
# etc...
Or, if you want the terminal new line:
>>> gen=('{} * {}'.format(a,b) for a in range(1,6) for b in range(1,6))
>>> print '\n'.join(gen),'\n'
I used a separate gen expression just to more clear about the print with the comma. This also works:
>>> print '\n'.join('{} * {}'.format(a,b) for a in range(1,6) for b in range(1,6)),'\n'
There is no reason to do an explicit call to str in your code. If you don't, you can still use a and b as integers:
>>> gen=('{} * {} = {:2}'.format(a,b,a*b) for a in range(1,3) for b in range(1,4))
>>> print '\n'.join(gen),'\n'
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6

Related

How do I write a program to find A,B answer that AAB +BB =BAA in python?

topic:
If A and B are both integers from 1 to 9, try to find out those (A, B) values that can meet the following conditions: AAB+BB=BAA
What I write:
for A in range (1,10):
for B in range(1,10):
if #I have no idea...
print(A,B)
Well, start with the fact that AAB is equal to A * 100 + A * 10 + B.
Apply that to the others, work out the expressions, and test for equality.
For example(1), to test if ABBA + AB is exactly seven greater than BBBB, you could use something like:
abba = A * 1000 + B * 100 + B * 10 + A # or A * 1001 + B * 110
ab = A * 10 + B
bbbb = B * 1000 + B * 100 + B * 10 + B # or B * 1111
if abba + ab == bbbb + 7:
do_something()
(1) Hopefully close enough that you can work it out for your specific question, but not so close that you can just plagiarise :-)
You can use:
from itertools import product
[(A,B,f'{A}{A}{B} + {B}{B} = {B}{A}{A}')
for A,B in product(range(1,10), range(1,10))
if A*100+A*10+B+B*10+B == B*100+A*10+A]
output: [(8, 9, '889 + 99 = 988')]
Using a classical loop:
for A in range(1,10):
for B in range(1,10):
if A*100+A*10+B+B*10+B == B*100+A*10+A:
print(f'A={A}, B={B} -> {A}{A}{B} + {B}{B} = {B}{A}{A}')
output:
A=8, B=9 -> 889 + 99 = 988
You can really simplify this by just casting to strings and back to integers. Since this is a small enough n there won't be any performance concerns.
You could apply math by adding factors of 10 in the appropriate places but to me, this is the most obvious what's going on.
for A in range (1, 10):
for B in range(1, 10):
AAB = int(str(A) + str(A) + str(B))
BB = int(str(B) + str(B))
BAA = int(str(B) + str(A) + str(A))
if AAB + BB == BAA:
print(A, B)
Or with f-strings.
for A in range (1, 10):
for B in range(1, 10):
AAB = int(f'{A}{A}{B}')
BB = int(f'{B}{B}')
BAA = int(f'{B}{A}{A}')
if AAB + BB == BAA:
print(A, B)
At first, lets simplify the expression.
AAB + BB = BAA == 100A + 10A + B + 10B + B = 100B + 10A + A == 99A = 88B == 9A = 8B.
As you can see, we can already suggest the right answer (A should be the value of B multiplier and vise versa).
But if you really need to write some Python code, here you go:
for a in range(1, 10):
for b in range(1, 10):
if a * 9 == b * 8:
print(f'A={a}, B={b}')
Output: A=8, B=9

How can i get sum of all the numbers that this program prints?

B = 1
A = 3
C = 1
while C < 1000:
B = B + 1
C = A * B
print (C)
This is the code and i want to get the sum of the numbers that it prints
Here is a possibility,
B = 1
A = 3
C = 1
D = 0
while C < 1000:
B = B + 1
C = A * B
D += C
print (C)
# sum of all printed numbers
print(D)
B runs over all the integers from 2 to 334; you only need the sum of all integers from 2 to 334 (which is well known: average * number of elements) and then multiply it by A:
A = 3
B_max = 334 # ~ (1000 // A) + ...
res = A * (B_max + 2) * (B_max - 1) // 2
# 167832
you just need to make sure you get B_max right...
there is no reason for a loop at all if that is all you need to do.
define a list outside while:
dataList = []
then add C in that list:
while C < 1000:
B = B + 1
C = A * B
dataList.append(C)
then find sum:
print(sum(dataList))
for me, your goal is not clear. can you explain it more for me to be able to help you?
PS. your B = B + 1 can be simplified to:
B += 1
You should declare SUM first:
SUM=0
And at the end of while loop after print message, add
SUM = SUM + C
And thats all, simplest possible way.
B = 1
A = 3
C = 1
total = 0
while C < 1000:
B = B + 1
C = A * B
print(C)
total+=C
print("Sum is : ",total)

Solve equations with combinations and for loops

I have equations with multiple unknowns, and a number range:
eq1 = (x + 5 + y) #
ans = 15
no_range = [1..5]
I know that I can solve the equation by checking all possible combinations:
solved = False
for i in range(1, 5+1) # for x
for j in range(1, 5+1) # for y
if i + 5 + j == ans:
solved = True
So, the problem is that I want a function to deal with unknown_count amount of unknowns. So that both the following equations, or any, can be solved in the same manner above:
eq1 = (x + 5 + y)
ans = 15
eq2 = (x + 5 + y + z * a + 5 * b / c)
ans = 20
I just cannot think of a way, since for each unknown you need a for loop.
You could use itertools.product to generate the Cartesian product for an
arbitrary number of variables:
In [4]: import itertools
In [5]: list(itertools.product(range(1, 5+1), repeat=2))
Out[5]:
[(1, 1),
(1, 2),
(1, 3),
...
(5, 3),
(5, 4),
(5, 5)]
So you could modify your code like this:
import itertools as IT
unknown_count = 6
ans = 20
solved = False
def func(*args):
x, y, z, a, b, c = args
return x + 5 + y + z * a + 5 * b / c
for args in IT.product(range(1, 5+1), repeat=unknown_count):
if func(*args) == ans:
solved = True
print('{} + 5 + {} + {} * {} + 5 * {} / {} = {}'.format(*(args+(ans,))))
which yields a lot of solutions, such as
1 + 5 + 1 + 1 * 3 + 5 * 2 / 1 = 20
1 + 5 + 1 + 1 * 3 + 5 * 4 / 2 = 20
1 + 5 + 1 + 2 * 4 + 5 * 1 / 1 = 20
...
5 + 5 + 5 + 2 * 2 + 5 * 1 / 5 = 20
5 + 5 + 5 + 3 * 1 + 5 * 2 / 5 = 20
5 + 5 + 5 + 4 * 1 + 5 * 1 / 5 = 20
The * unpacking operator was used
to create a function, func, which accepts an arbitrary number of arguments (i.e. def func(*args)), and also to
pass an arbitrary number of arguments to func (i.e. func(*args)).

Fibonacci series in python giving odd results

I have started learning python and my first program on fibonacci started giving me some weird answer, I know I am missing conceptually something so need guide from some expert on this. My program looks like this
#! usr/bin/python
a,b = 0, 1
while (b < 50):
print(b)
a = b
b = a + b
output
1
2
4
8
16
32
But When i wrote like this I got correct result
#! usr/bin/python
a,b = 0, 1
while (b < 50):
print(b)
a,b = b, a + b
output:
1
1
2
3
5
8
13
21
34
Guide me pls
a,b = 0,1
a = b # a <- 1
b = a + b # b <- a + b (1 + 1 = 2)
That's two separate operations where the a in the final line has already been modified before use.
On the other hand:
a,b = b, a + b
is an atomic operation where everything on the right side of = is the original value.
Hence it's equivalent to:
a,b = 0,1
t = a # t <- 0
a = b # a <- 1
b = t + b # b <- t + b (0 + 1 = 1)

How to convert algorithm to python

new to python and I'm having trouble converting a script to a more effective algorithm I was given.
Here's the python code:
#!/usr/bin/env python
import itertools
target_sum = 10
a = 1
b = 2
c = 4
a_range = range(0, target_sum + 1, a)
b_range = range(0, target_sum + 1, b)
c_range = range(0, target_sum + 1, c)
for i, j, k in itertools.product(a_range, b_range, c_range):
if i + j + k == 10:
print a, ':', i/a, ',', b, ':', j/b, ',', c, ':', k/c
(it only does 3 variables just for example, but I want to use it on thousands of variables in the end).
Here's the result I am looking for(all the combo's that make it result to 10):
1 : 0 , 2 : 1 , 4 : 2
1 : 0 , 2 : 3 , 4 : 1
1 : 0 , 2 : 5 , 4 : 0
1 : 2 , 2 : 0 , 4 : 2
1 : 2 , 2 : 2 , 4 : 1
1 : 2 , 2 : 4 , 4 : 0
1 : 4 , 2 : 1 , 4 : 1
1 : 4 , 2 : 3 , 4 : 0
1 : 6 , 2 : 0 , 4 : 1
1 : 6 , 2 : 2 , 4 : 0
1 : 8 , 2 : 1 , 4 : 0
1 : 10 , 2 : 0 , 4 : 0
In question Can brute force algorithms scale? a better algorithm was suggested but I'm having a hard time implementing the logic within python. The new test code:
# logic to convert
#for i = 1 to k
#for z = 0 to sum:
# for c = 1 to z / x_i:
# if T[z - c * x_i][i - 1] is true: #having trouble creating the table...not sure if thats a matrix
# set T[z][i] to true
#set the variables
sum = 10
data = [1, 2, 4]
# trying to find all the different ways to combine the data to equal the sum
for i in range(len(data)):
print(i)
if i == 0:
continue
for z in range(sum):
for c in range(z/i):
print("*" * 15)
print('z is equal to: ', z)
print('c is equal to: ', c)
print('i is equal to: ', i)
print(z - c * i)
print('i - 1: ', (i - 1))
if (z - c * i) == (i - 1):
print("(z - c * i) * (i - 1)) match!")
print(z,i)
Sorry its obviously pretty messy, I have no idea how to generate a table in the section that has:
if T[z - c * x_i][i - 1] is true:
set T[z][i] to true
In other places while converting the algo, I had more problems because in lines like 'or i = 1 to k' converting it to python gives me an error saying "TypeError: 'int' object is not utterable"
You can get that block which creates the table for dynamic programming with this:
from collections import defaultdict
# T[x, i] is True if 'x' can be solved
# by a linear combination of data[:i+1]
T = defaultdict(bool) # all values are False by default
T[0, 0] = True # base case
for i, x in enumerate(data): # i is index, x is data[i]
for s in range(sum + 1):
for c in range(s / x + 1):
if T[s - c * x, i]:
T[s, i + 1] = True
You can create the table you need with a list of lists:
t = [[False for i in range(len(data))] for z in range(sum)] #Creates table filled with 'False'
for i in range(len(data)):
print(i)
if i == 0:
continue
for z in range(sum):
for c in range(int(z/i)):
print("*" * 15)
print('z is equal to: ', z)
print('c is equal to: ', c)
print('i is equal to: ', i)
print(z - c * i)
print('i - 1: ', (i - 1))
if (z - c * i) == (i - 1):
print("(z - c * i) * (i - 1)) match!")
t[z][i] = True # Sets element in table to 'True'
As for your TypeError, you can't say i = 1 to k, you need to say: for i in range(1,k+1): (assuming you want k to be included).
Another tip is that you shouldn't use sum as a variable name, because this is already a built-in python function. Try putting print sum([10,4]) in your program somewhere!

Categories

Resources