usage of continue loop, and or - python

I'm quite new in Python. I have searched on site but I couldn't find solution for that pease show me if I missed.
I am trying to understand loops and "and" "or" I did some experiment with these elements but I confused.
Bellow code I was expecting code pass the numbers which isn't dividable by 3 or 5 and print rest. But suprisingly It print the numbers which is dividable by 15! (other words which is dividable by 3 and 5)
for x in range(100):
if x % 3 != 0 or x % 5 != 0:
continue
print(x)
output:
0
15
30
45
60
75
90
And this one I was expecting it will pass the number which isn't dividable 3 and 5 But it prints the numbers which is dividable 3 or 5 as I wanted in my first example.
for x in range(100):
if x % 3 != 0 and x % 5 != 0:
continue
print(x)
output:
0
3
5
6
9
10
12
15
18
20
.............
I don't understand what I am missing. I'm aware that I can make it happen with if, elif and else form but I wanted to learn more about "continue" usage. I'd appereciate if you help me.
Thank you!

You may have an easier time understanding what's happening just by walking through the numbers and seeing what your logic does for each number. You have walked into a logic equivalence that can be confusing, and is expressed in De Morgan's Laws. Essentially you can say
(x % 3 != 0 or x % 5 != 0) = !(x % 3 == 0 and x % 5 == 0)
so your first logic test is checking whether a number is divisible by both 3 and 5, which are the multiples of 15. And your second test is
x % 3 != 0 and x % 5 != 0 = !(x % 3 == 0 or x % 5 == 0)
so you are testing whether a number is divisible by either 3 or 5.

The continue keyword will essentially end the current iteration of the loop, and jump directly to the start of the loop to re-evaluate the loop condition (see https://docs.python.org/3.8/tutorial/controlflow.html).
So, in your first block of code, any time x is not divisible by 3 or 5, it will not print the number, meaning the only numbers which are printed are those which are divisible by both 3 and 5.

You can clear up the or logic like this:
for x in range(100):
if x % 3 != 0: # skip 1,2,4,5,7,8,10,11,13,14,16....
continue
if x % 5 != 0: # skip 1,2,3,4,6,7,8,9,11,12,13,14,16...
continue
print(x) # only numbers that pass both checks 0,15,30,...
With this, only 0, 15, 30, ... get through
If you convert it with boolean algebra,
if x % 3 != 0 or x % 5 != 0:
is the same as
if x % 3 == 0 and x % 5 == 0:
which gives the same results (0,15,30,...)

Related

finding divisor with condition with python using 'if' and 'while'

trying to find how many divisors in 120, and printing divisors
div_n = 1
count = 0
n = 120
while div_n <= n:
if n % div_n == 0:
print(div_n)
count += 1
div_n += 1
print('number of divisor that 120 is {}.'.format(count))
the output should be
1
2
3
4
5
6
8
10
12
15
20
24
30
40
60
120
number of divisor that 120 is 16
But the problem I'm trying to solve says the code is not meeting the requirements.
If there is nothing wrong, or more information is needed let me know.
You can use this:
def get_factors(n):
ret = []
for i in range(1, n+1):
if not n % i:
ret.append(i)
return ret
factors = get_factors(120)
print(*factors, sep='\n')
print('Total factors:', len(factors))
Output:
1
2
3
4
5
6
8
10
12
15
20
24
30
40
60
120
Total factors: 16
Your code, once properly indented, works just fine. So I suspect the requirement you don't meet is that of speed - try the code with n=120000000.
When you look for divisors you don't need to check all the numbers from 1 to n: just check numbers from 1 to int(sqrt(n)) - when you find a divisor lower than the square root you have also found a related divisor, greater than the square root. In your example, when you find 2 you also find 60, and so on.
So I would do something like:
def divisors(n):
divs = []
divs2 = []
r = int(sqrt(n))
for d in range(1,r):
q,m = divmod(n,d)
if m == 0:
divs.append(d)
divs2.append(q)
if n % r == 0:
divs.append(r)
for d in divs:
print(d)
for d in divs2[::-1]:
print(d)
print(f'Divisors for {n}: {len(divs)+len(divs2)}')
EDIT: there was a small bug - if n happened to be a perfect square, my code would count its square root twice. So we better stop at int(sqrt(n))-1 and handle the square root separately.

Finding the n-th number that consists of only 2 or 3

I am really struggling with this program. I would appreciate any kind of help.
For a natural number we say that it is strange if it is completely composed of digits 2 and 3. The user enters a natural number. The program prints the n-th strange number.
Numbers that are considered strange are 2, 3, 22, 23, 33...
n = int(input())
current_number = 1
counter_strange = 0
counter = 0
while counter_strange < n:
x = current_number
while x < n:
k = x % 10
if k != 2 or k != 3:
counter += 1
else:
break
if counter >= 1:
counter_strange += 1
current_number += 1
print(current_number-1)
Strange numbers come in blocks. A block of 2 1-digit numbers, followed by a block of 4 2-digit numbers, then 8 3-digit numbers. You can do the math and determine which block of k-digit numbers a given index n is, and how far into that block it lies. Convert that distance into a base-2 number, zero-filled to k digits, then replace 0 by 2 and 1 by 3. Convert the result back to an int:
from math import log2, ceil
def strange(n):
"""returns the nth strange number"""
#first determine number of digits:
k = ceil(log2(n+2)) - 1
#determine how far is in the block of strange k-digit numbers
d = n - (2**k - 1)
#convert to base 2, zfilling to k digits:
s = bin(d)[2:].zfill(k)
#swap 2,3 for 0,1:
s = s.replace('0','2').replace('1','3')
#finally:
return int(s)
for n in range(1,10): print(n,strange(n))
Output:
1 2
2 3
3 22
4 23
5 32
6 33
7 222
8 223
9 232
You can use a while loop with itertools.product in a generator function. Using a generator will allow you to create a stream from which you can access strange numbers on the fly:
import itertools
def strange():
c = 0
while True:
yield from map(''.join, itertools.product(*([['2', '3']]*(c:=c+1))))
s = strange()
for _ in range(10):
print(int(next(s)))
Output:
2
3
22
23
32
33
222
223
232
233

checking if a very large number is divisible by 2 comes wrong

I am trying some stuff on the 3x+1 problem and noticed when I check if this num is divisible by two comes always true even that the second iteration should be false it goes like this for 20 iterations and then start to act right. I guess it is a long number issue?
num = 3656565605161651626526625291991265161656
while num != 1:
if (num % 2 == 0):
num /= 2
print("2")
else:
num *= 3
num += 1
print("3")
num2=f'{num:.1f}'
print(num2)
Here is the start of the result:
2
1828282802580825918440824287108404346880
2
914141401290412959220412143554202173440
2
457070700645206479610206071777101086720
2
You need to use integer division, not float.
num //= 2
Here are the first 20 lines of the output, where you can see it is working:
2
1828282802580825813263312645995632580828
2
914141401290412906631656322997816290414
2
457070700645206453315828161498908145207
3
1371212101935619359947484484496724435622
2
685606050967809679973742242248362217811
3
2056818152903429039921226726745086653434
2
1028409076451714519960613363372543326717
3
3085227229355143559881840090117629980152
2
1542613614677571779940920045058814990076
2
771306807338785889970460022529407495038

Python: How to make numeric triangle with recursion

while I was working on the Python practice, I found a question that I cannot solve by myself.
The question is,
Input one integer(n), and then write the codes that make a triangle using 1 to 'n'. Use the following picture. You should make only one function, and call that function various times to solve the question. The following picture is the result that you should make in the codes.
Receive one integer as an argument, print the number from 1 to the integer received as a factor in a single line, and then print the line break character at the end. Once this function is called, only one line of output should be printed.
So by that question, I found that this is a question that requires the
recursion since I have to call your function only once.
I tried to work on the codes that I made many times, but I couldn't solve it.
global a
a = 1
def printLine(n):
global a
if (n == 0):
return
for i in range(1, a + 1):
print(i, end=" ")
print()
a += 1
for k in range(1, n+1):
print(k, end=" ")
print()
printLine(n - 1)
n = int(input())
printLine(n)
Then I wrote some codes to solve this question, but the ascending and descending part is kept overlapping. :(
What I need to do is to break two ascending and descending parts separately in one function, but I really cannot find how can I do that. So which part should I have to put the recursive function call?
Or is there another way can divide the ascending and descending part in the function?
Any ideas, comments, or solutions are appreciated.
Thx
You can use the below function:
def create_triangle(n, k: int = 1, output: list = []):
if n == 1:
output.append(n)
return output
elif k >= n:
output.append(" ".join([str(i) for i in range(1, n + 1)]))
return create_triangle(n - 1, k)
else:
output.append(" ".join([str(i) for i in range(1, n + 1)[:k]]))
return create_triangle(n, k + 1)
for i in create_triangle(5):
print(i)
Output:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
# function to print all the numbers from 1 to n with spaces
def printLine(k):
# create a range. if k is 4, will create the range: 1, 2, 3, 4
rng = range(1, k + 1)
# convert each number to string
str_rng = map(lambda x: str(x), rng)
# create one long string with spaces
full_line = " ".join(str_rng)
print(full_line)
# capture input
n = int(input())
# start from 1, and up to n, printing the first half of the triangle
for i in range(1, n):
printLine(i)
# now create the bottom part, by creating a descending range
for i in range(n, 0, -1):
printLine(i)
Using default parameter as a dict, you can manipulate it as your function variables, so in that way, you can have a variable in your function that keeps the current iteration you are at and if your function is ascending or descending.
def triangle_line(n, config={'max':1, 'ascending':True}):
print(*range(1, config['max'] + 1))
if config['ascending']:
config['max'] += 1
else:
config['max'] -= 1
if config['max'] > n:
config['ascending'] = False
config['max'] = n
elif config['max'] == 0:
config['ascending'] = True
config['max'] = 1
Each call you make will return one iteration.
>>> triangle_line(4)
1
>>> triangle_line(4)
1 2
>>> triangle_line(4)
1 2 3
>>> triangle_line(4)
1 2 3 4
>>> triangle_line(4)
1 2 3 4
>>> triangle_line(4)
1 2 3
>>> triangle_line(4)
1 2
>>> triangle_line(4)
1
Or you can run on a loop, two times your input size.
>>> n = 4
>>> for i in range(0,n*2):
... triangle_line(n)
...
1
1 2
1 2 3
1 2 3 4
1 2 3 4
1 2 3
1 2
1

What exactly does this mean in Python? [duplicate]

This question already has answers here:
What is the result of % in Python?
(20 answers)
Closed 9 years ago.
I was working on a project Euler problem and found this code online:
a = 1
b = 2
s = 0
while b <= 4000000:
if not b % 2:
s += b
a, b = b, a + b
print s
I am not entirely sure what if not b % 2: means and was wondering if someone would mind shedding some light on it for me.
From the docs:
The % (modulo) operator yields the remainder from the division of the first argument by the second.
e.g. 5/2 == 2.5 # or 2 remainder 1, 5%2 == 1
The only time a % operation will come out to 0 (which satisfies not x%y) is if it's evenly divisible. In other words, 4 % 2 == 0 because 2 divides 4 evenly.
In your code, it's saying:
while b is less than 4,000,000:
if b is even:
set s equal to s+b
The modulo % operator returns the remainder of the division of b per 2 (in your case).
So if not b % 2 is the same meaning that if b % 2 == 0: it checks if the number is even.
b % 2 is the remainder after dividing by 2. So it will be 1 if b is odd, or 0 otherwise.
if not b % 2 can thus be translated to "if b is even"
Python interprets the value 1 as True and 0 as False:
>>> 1 == True
True
>>> 0 == True
False
The modulo operation x % y returns the remainder when x is divided by y. Therefore b % 2 will be 0 when b is even, and 1 when b is odd.
Combining all this together, the statement if not b % 2: corresponds to "if b is even".
It's just a cute way of writing if b%2==0. The not operator when passed 0 will return True, and False given anything else.

Categories

Resources