Factorial number printing - python

I'm a newbie at python. I started it not long a ago as a hobby after uni lecture hours.
I found this exercise ( forgot where I got it from now) to do which is to print out the factorial numbers.
Which I did. But, problem is that I'm tasked to manipulate line 3 so it only prints out the number 1 once at the start of the sequence and I'm having trouble with that.
Please can any help? :)
In advance sorry if the question wasn't worded as good as it could have been.
a, b = 0, 1
while a < 19:
print b,
a, b = a + 1, b * (a+1)
Result:
1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 6227020800 87178291200 1307674368000 20922789888000 355687428096000 6402373705728000

a, b = 0, 1
while a < 19:
if a: print b,
a, b = a + 1, b * (a+1)
Use a in-line if statement to check if a is 1. If it's 1 then you know that you already went through the loop at least once.

Related

Python - Multiple Assignment [duplicate]

This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 2 years ago.
Recently I was reading through the official Python documentation when I came across the example on how to code the Fibonacci series as follows:
a, b = 0, 1
while a < 10:
print (a)
a, b = b, a + b
which outputs to 0,1,1,2,3,5,8
Since I've never used multiple assignment myself, I decided to hop into Visual Studio to figure out how it worked. I noticed that if I changed the notation to...
a = 0
b = 1
while a < 10:
print (a)
a, b = b, a + b
... the output remains the same.
However, if I change the notation to...
a = 0
b = 1
while a < 10:
print(a)
a = b
b = a + b
... the output changes to 0, 1, 2, 4, 8
The way I understand multiple assignments is that it shrinks what can be done into two lines into one. But obviously, this reasoning must be flawed if I can't apply this logic to the variables under the print(a) command.
It would be much appreciated if someone could explain why this is/what is wrong with my reasoning.
a = 0
b = 1
while a < 10:
print(a)
a = b
b = a + b
In this case, a becomes b and then b becomes the changed a + b
a, b = 0, 1
while a < 10:
print (a)
a, b = b, a+b
In this case, a becomes b and at the same time b becomes the original a + b.
That's why, in your case b becomes the new a + b, which, since a = b, basically means b = b + b. That's why the value of b doubles everytime.
When you do a, b = d, e the order in which assignment happens in from right to left. That is, b is first given the value of e and then the other assignment happens. So when you do a, b = b, a + b what you are effectively writing is,
b = a + b
a = b
Hence the difference.
You can verify this by doing
a = 0
b = 1
while a < 10:
a, b = b, a + b
print(a, b)
the first output is 1 1. So first b becomes 0+1 and then a is given the value of b=a making it also 1.
If you want more details on how this works, you can check out this question.
In a multiple assignment, the right side is always computed first.
In effect,
a, b = b, a + b
is the same as:
b = a + b
a = b

Any insight on how to solve this inequality: n! <= 10^6?

I have been working on dealing with n! <= 10^6 in python by using sympy.solver. For example, the below is my code:
import sympy as sy
print(sy.solve_univariate_inequality(sy.factorial(n) <= 10**6,n))
I tried solve_univariate_inequality and solve methods but none of them worked. The error was "raise NotImplementedError('solveset is unable to solve this equation.')"
I'm curious if there's any other way to deal with this inequality. Any insight please?
i = 1
factorial = 1
while factorial <= 1_000_000:
factorial *= i
i += 1
print(f"equation valid for n in [1-{i-2}]")
From docs
Currently supported:
polynomial
transcendental
piecewise combinations of the above
systems of linear and polynomial equations
systems containing relational expressions
Looks like factorial is not supported.
If you approach this problem purely mathematically you can just increment n to get the factorial which exceeds the threshold.
results=[]
n=0
n_factorial=1
while n_factorial<=10**6:
results.append(n)
print(n,n_factorial)
n+=1
n_factorial*=n
print(results)
Output:
0 1
1 1
2 2
3 6
4 24
5 120
6 720
7 5040
8 40320
9 362880
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Math function to find the biggest multiple of a number within a range

I want to know if there is a math expression that I can use to find this relation between two numbers.
Some examples of the input and expected output are below:
Input Multiple Result
4 3 3
6 3 6
8 3 6
4 4 4
12 4 12
16 5 15
Also, the expressions below from Wolfram Alpha show me the expected result but since they don't expand on the explanation on how to do it I can't learn from them...
Biggest multiple of 4 from 10
Biggest multiple of 4 from 12
try with // and % operators!
for //, you would do
Result = (Input // Multiple) * Multiple
This way you get how many times Multiple Fits into Input - this number is then multiplied with the Multiple itself and therefore gives you the expected results!
EDIT: how to do it with modulo %?
Result = Input - (Input % Multiple)
taken from MCO's answer!
You can employ modulo for this. For example, to calculate the biggest multiple of 4 that is less or equal than 13:
13 % 4 = 1
13 - 1 = 12
in python, that could look like this:
def biggest_multiple(multiple_of, input_number):
return input_number - input_number % multiple_of
So you use it as:
$ biggest_multiple(4, 9)
8
$ biggest_multiple(4, 12)
12
Here's how I would do it:
return int(input / multiple) * multiple
It truncates the division so that you get an integer, which you can multiply.
This can be trivial but damn easy to understand. To take into account if multiple is negative or zero
Multiple=[3,3,3,4,4,5,0,-5]
Input=[4,6,8,4,12,16,1,8]
Result=[]
for input,multiple in zip(Input,Multiple):
if(multiple):
Result.append((range(multiple,input+1,abs(multiple)))[-1])
else:
Result.append(0)
print(Result)
Output:
[3, 6, 6, 4, 12, 15, 0, 5]

for loop conversion from C to Python

How can I write the for loop in Python as I write it in C:
for(i=0;i<10;)
{
if(i%2==0)
i=i+3;
else
i++;
printf("%d\n",i);
}
Can anyone tell me about this? I searched a lot but couldn't find it. I wrote it like this in Python:
for i in range(0,10):
if (i%2==0):
i+=3
else:
i+=1
print i
Output:
3
2
5
4
7
6
9
8
11
10
Expected output:
3
4
7
8
11
Can anyone also explain the reason of this output?
To write the same loop in Python:
i = 0
while i < 10:
if i % 2 == 0:
i += 3
else:
i += 1
print i
Which gives:
3
4
7
8
11
Note that, per the tutorial:
The for statement in Python differs a bit from what you may be used to
in C or Pascal. Rather than always iterating over an arithmetic
progression of numbers (like in Pascal), or giving the user the
ability to define both the iteration step and halting condition (as
C), Python’s for statement iterates over the items of any sequence (a
list or a string), in the order that they appear in the sequence.
In a Python for loop, any changes to the loop variable (i, in this case) that occur during the loop are ignored when the loop repeats, and the next value from the object being iterated over is used. In this case, the object is a list of numbers:
>>> range(10) # note that a 0 start is the default
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Some languages call this a for each loop. See also the language reference for more details.
range(0, 10) function returns list of values from 0 to 9:
range(0, 10) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Then for body is executed for each element in this list.
If You have 0, the 0 % 2 == 0 so it prints 0 + 3 etc.
In C You changed i value so You jumped to other value in set. Using python's for You will get through all elements. You should use
i = 0
while i < 10:
if (i % 2 == 0):
i += 3
else:
i += 1
print i
To have same results as in C
try this
for i in range(10):
if i%2 == 0:
i = i+3
else:
i = i + 1
print i
it gives the same output u asked for...hope this helps

error in generating prime numbers in python

I want to print all the prime numbers from 1 to 10 but nothing gets printed when i run the program
c=0
nums = []
k=0
for a in range(1,11):
for b in range(1,11):
if a%b==0:
c = c+1
if c==2:
nums.append(a)
k = k+1
for d in nums:
print nums[d]
I can't figure out why you are using k
and your c should reset in "a" loop and out of "b" loop
code like this:
nums = []
for a in range(1, 11):
c = 0
for b in range(1, 11):
if a % b == 0:
c = c + 1
if c == 2:
nums.append(a)
print nums
You should reset c to zero before the beginning of each inner loop:
nums = []
for a in range(1,11):
c = 0
for b in range(1,11):
if a%b==0:
c = c+1
if c==2:
nums.append(a)
for d in nums:
print d
Additionally, you should use print d, since the for-loop already gives every element in nums.
Using a list comprehension is generally faster and considered more pythonic than using a for-loop.
There are many different ways of calculating prime numbers. Here are some of them.
Here is your original algorithm, with some improvements;
def prime_list(num):
"""Returns a list of all prime numbers up to and including num.
:num: highest number to test
:returns: a list of primes up to num
"""
if num < 3:
raise ValueError('this function only accepts arguments > 2')
candidates = range(3, num+1, 2)
L = [c for c in candidates if all(c % p != 0 for p in range(3, c, 2))]
return [2] + L
For primes >2, they must be odd numbers. So candidates should contain only odd numbers.
For an odd number c to be prime, one must ensure that c modulo all previous odd numbers (p) must be non-zero.
Lastly, 2 is also prime.
A further improvement is to restrict p up to sqrt(c):
import math
def prime_list2(num):
if num < 3:
raise ValueError('this function only accepts arguments > 2')
candidates = range(3, num+1, 2)
L = [c for c in candidates if all(c % p != 0 for p in
range(3, int(math.sqrt(c))+1, 2))]
return [2] + L
Another implementation:
def prime_list3(num):
num += 1
candidates = range(3, num, 2)
results = [2]
while len(candidates):
t = candidates[0]
results.append(t)
candidates = [i for i in candidates if not i in range(t, num, t)]
return results
This starts off with a list of candidates that contains all odd numbers. Then is calculates a new list of candidates by removing the first number of the previous list and all all multiples of it.
Let's look at the speed of the algorithms.
For small numbers, the original prime_list is the fastest;
In [8]: %timeit prime_list(10)
100000 loops, best of 3: 8.68 µs per loop
In [9]: %timeit prime_list2(10)
100000 loops, best of 3: 10.9 µs per loop
In [10]: %timeit prime_list3(10)
100000 loops, best of 3: 8.96 µs per loop
For larger numbers, prime_list2 comes out the winner:
In [5]: %timeit prime_list(1000)
100 loops, best of 3: 8.28 ms per loop
In [6]: %timeit prime_list2(1000)
100 loops, best of 3: 2.46 ms per loop
In [7]: %timeit prime_list3(1000)
10 loops, best of 3: 23.5 ms per loop
In [11]: %timeit prime_list(10000)
1 loops, best of 3: 646 ms per loop
In [12]: %timeit prime_list2(10000)
10 loops, best of 3: 25.4 ms per loop
In [13]: %timeit prime_list3(10000)
1 loops, best of 3: 2.13 s per loop
I added two print statements to your code - first, under if a%b==0:, I added print a,b; and I print the final value of c after that loop. I get this output:
1 1
1
2 1
2 2
3
3 1
3 3
5
4 1
4 2
4 4
8
5 1
5 5
10
6 1
6 2
6 3
6 6
14
7 1
7 7
16
8 1
8 2
8 4
8 8
20
9 1
9 3
9 9
23
10 1
10 2
10 5
10 10
27
This tells you why you get nothing printed: after the b loop in a == 1, c is 1; after the same loop in the next iteration of the outer loop, c is now 3. So c==2 is never True when that test is made, so nums stays empty.
This also gives you a big hint as to what you need to do to fix it. c keeps increasing, but it should start counting afresh for each iteration of the outer loop - so, move your c=0 to be inside the outer for loop. You also need to change your final print loop to print d instead of print nums[d], or you will get another error. With those changes, your code looks like this:
nums = []
k=0
for a in range(1,11):
c=0
for b in range(1,11):
if a%b==0:
c = c+1
if c == 2:
nums.append(a)
k = k+1
for d in nums:
print d
and it prints
2
3
5
7
as expected.
Your c is not reset to zero inside the loop (the first loop). So set c=0 after line: for a in range(1,11):
I dont know what your k is for. Is it usefull for anything?
Printing the prime numbers dont do nums[d], print d. You are looping on the items not on the indices.
Your code has multiple issues - Every prime number is divisible by 1 so your checks will fail, you are printing nums[d] which is wrong, k is doing nothing, variable nomenclature is too obfuscated, you have unnecessary runs in for loop - you don't need to iterate for all values of b in range, it is sufficient to iterate over existing prime numbers and so on.
Here is how I would write it
primes = [2]
upper_limit = 1000 #find all primes < 1000
for candidate in range(2, upper_limit):
can_be_prime = True
for prime in primes:
if candidate % prime == 0:
can_be_prime = False
break
if can_be_prime:
primes.append(candidate)
print primes
This solution is a little neater:
nums = []
for a in range(2, 101):
for b in range(2, a):
if a % b == 0:
break
else:
nums.append(a)
print nums
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Still, there is no point trying b > sqrt(a).
Try this:
nums = []
k=0
for a in range(2,11):
c=0
for b in range(1,11):
if a%b==0:
c = c+1
if c==2:
nums.append(a)
k = k+1
for d in nums:
print d
You will get
2
3
5
7
Note the code could be more efficient.

Categories

Resources