How to loop over modulus? - python

newbie here. I've been trying to find the least common multiple of the numbers 1 thru 10. My code so far
def smallest_multiple():
a = 0
while True:
a += 1
if a%1 == 0 and a%2 == 0 and a%3 == 0 and a%4 == 0 and a%5 == 0 and a%6 == 0 and a%7 == 0 and a%8 == 0 and a%9 == 0 and a%10 == 0:
return a
print(smallest_multiple())
My result is 2520, which seems to be correct. It is the smallest number that is divisible by the numbers 1 thru 10 without remainder. But is there a way to make the 5 line shorter (not that much modulus) by iterating over them? I've tried something like this
def smallest_multiple():
a = 0
while True:
a += 1
for i in range(1, 11):
if a % i == 0:
return a
print(smallest_multiple())
But that returns just 1, not 2520. Is there a way to make
if a%1 == 0 and a%2 == 0 and a%3 == 0 and a%4 == 0 and a%5 == 0 and a%6 == 0 and a%7 == 0 and a%8 == 0 and a%9 == 0 and a%10 == 0:
shorter?

You could change it to
if all([a%i == 0 for i in range(1,11)]):
All takes a list and returns True if everything in the list is True
This uses a simple list comprehension to go through numbers 1 through 10, and check if they are all True with a%i == 0

You could use all:
def smallest_multiple():
factors = [i for i in range(1, 11)]
a = 0
while True:
a += 1
if all([a % factor == 0 for factor in factors]):
return a
print(smallest_multiple())
Output
2520
UPDATE
As suggested by #PatrickHaugh you can avoid the creation of lists:
def smallest_multiple():
factors = range(1, 11)
a = 0
while True:
a += 1
if all(a % factor == 0 for factor in factors):
return a
print(smallest_multiple())
Output
2520

Speaking of one-liners ^^
Not an Infinity loop, though
import sys
next(i for i in xrange(1, sys.maxsize) if len([j for j in range(1,10) if i % j == 0]) == 9)
#=> 2520
And this is not the most efficient solution.

Related

Trying to write a function that returns the number of digits in n that are divisble by m -- Too much output - Python

I'm currently trying to write a function that will take n and m as an argument and then will return the number of digits in n that are divisible by m. An example of this could be n = 305689 and m = 3. The answer here would be 4.
My program is able to get this result, but the interface I'm working is is saying that my program is running for too long or producing too much output.
Here's my program so far:
def count_divisible_digits(n, m):
count = 0
while n != 0:
if (n % 10) % m == 0:
count += 1
#print("dbg", count, n)
n = n // 10
return count
Try converting the input n to string datatype and getting the count as follows. This should be faster.
def count_divisible_digits(n, m):
count = 0
string = str(n)
if n == 0 and m == 0:
return 0
elif m == 0:
return 0
elif n == 0:
return 1
elif n < 0:
x = 1
else:
x = 0
for i in range(x, len(string)):
if string[i] == '.' or 0 < int(string[i]) < m:
continue
elif int(string[i]) % m == 0:
count += 1
return count
Try this again, miss the 0 ✅ check now;
count =sum(1 for s in str(n) if int(s)%m==0 and int(s) >0)

Create a list of numbers dividable by certain numbers by using the command « filter() »

I’m on Python) I have to use filter() to create a list of all numbers from 1 to 100 (inclusive) that are dividable by 7, 9 and 42. I wrote this code, however, when I start it, it does not give me the right solutions. Do you know where the problem is ?
listnumbers = []
for x in range (1, 101):
x = str(x)
listnumbers.append(x)
print (listnumbers)
def dividable(k):
for t in k:
if int(t) % 7 == 0:
return True
if int(t) % 9 == 0:
return True
if int(t) % 42 == 0:
return True
else:
return False
return dividable
s2u = list(filter(dividable, listnumbers))
for q in s2u:
print(q)
According to your problem statement the number should be divisible by 7 and 9 and 42.
listnumbers = list(range(1,101))
def dividable(k):
if k % 7 == 0 and k % 9 == 0 and k % 42 == 0:
return True
else:
return False
ans = list(filter(dividable, listnumbers))
print(ans)
Just eyeballing your code, I think dividable(k) is not written correctly. Update to :
def dividable(k):
n = int(k)
return n % 7 == 0 or n % 9 == 0 or n % 42 == 0:
Why was there a for look declared in this method? And why was it returning the function at the end if it passed through the rest of the conditions?

Very Beginner Problem in Python While Loop

Why this While loop is not breaking or stopping
I have added some output screenshot
term = 0
i = 13
while True:
print i > 1
print "i = ",i
if i == 1:
term += 1
break
if i%2 == 0:
i = i / 2
term += 1
if i%2 != 0:
i = i * 3 + 1
term += 1
Output
I also tried This way too
term = 1
i = 13
while i > 1:
print i > 1
if i%2 == 0:
i = i / 2
term += 1
if i%2 != 0:
i = i * 3 + 1
term += 1
Use elif to make the cases mutually exclusive. You don't want multiple if statements to execute in the same loop iteration.
if i%2 == 0:
i = i / 2
term += 1
elif i%2 != 0:
i = i * 3 + 1
term += 1
Or just make it else since the second condition is redundant.
if i%2 == 0:
i = i / 2
term += 1
else:
i = i * 3 + 1
term += 1
The reason it oscillates between 2 and 4 as written is because 2 causes both if statements to run. 2 is even so the first one runs and halves i, making it 1. Now it's odd and the second one triggers, turning 1 into 4.
if i%2 == 0:
i = i / 2 # 2 --> 1
term += 1
if i%2 != 0:
i = i * 3 + 1 # 1 --> 4
term += 1
The next iteration 4 becomes 2.
if i%2 == 0:
i = i / 2 # 4 --> 2
term += 1
These two iterations repeat over and over in an endless cycle.
Let's say your i is 2. It is divisible by 2, so if i % 2 == 0 fires, and i becomes 1. And the code continues to execute, so now we are at if i % 2 != 0 line, and this condition is also true, because you just modified i and it's now 1. So i becomes 4.
Your modified second attempt, which prevents the second condition from being checked if the first one succeeds, is below:
term = 1
i = 13
while i > 1:
print(i > 1)
if i % 2 == 0:
i = i / 2
term += 1
elif i % 2 != 0:
i = i * 3 + 1
term += 1
Also notice that you actually don't need to check the second condition, as it is definitely true if the first one is not, so elif ... line can be replaced just with else:
You can also use continue keyword to stop the rest of the loop from executing if the first condition is true:
term = 1
i = 13
while i > 1:
print(i > 1)
if i % 2 == 0:
i = i / 2
term += 1
continue
if i % 2 != 0:
i = i * 3 + 1
term += 1
Your first attempt has exactly the same problem; fixing it I leave as an exercise for the reader :)
P.S. do not learn Python 2
The problem is:
if i%2 == 0:
i = i / 2
term += 1
if i%2 != 0:
i = i * 3 + 1
term += 1
The problem is that, if i % 2 == 0 is true, it will remain true until i = 1. Once i = 1, i % 2 != 0 executes and makes i = 4.

FizzzBuzz Python Work Through

Count up from 1. If the number is a multiple of 7 they say "zap" instead of the number. If the number has a digit of 3 in it they say "buzz" instead of the number, and if both things are true they say "zap buzz".
Devise a function zap_buzz that plays a turn of the game. Given a positive integer parameter it should either return that integer value if neither of the "zap"/"buzz" conditions hold. If some condition holds, it should return the string "zap", the string "buzz", or the string "zap buzz", whichever is appropriate. You are allowed to assume the parameter is less than 1000. As in the earlier exercises, please don't convert the integer to a string to determine its digits.
>>> zap_buzz(8)
8
>>> zap_buzz(14)
'zap'
>>> zap_buzz(13)
'buzz'
>>> zap_buzz(35)
'zap buzz'
^^^^^ is the prompt. I have gotten so far:
def zapbuzz(x):
x =0
if x % 3 == 0 and x % 7 == 0:
return str("ZapBuzz")
elif x % == 3 and x % 7 != 0 :
return str("Zap")
elif x % 3 != 0 and x % 7 == 0:
return str("Buzz")
else /* x % 3 >= 1 or x % 7 >= 1:
return x
****Please don't give me the answer, but a few good tips or maybe a "try thinking about XYZ/etc/whatevertip in a different way would be super awesome. Thank you!
okay I read through the comments, thank you for inspo!
I made the following changes:
n = input()
def ZapBuzz(n):
if n%7 == 0 & n%3 == 0:
return ("ZapBuzz")
elif n%7 == 0 & n%3 != 0:
return ("Zap")
elif n%7 != 0 & n%3 == 0:
return ("Buzz")
else:
return (n)
okay, just talked to a tutor.... I worked out the function, except the issue im having now is that when i input 1 into the function, the terminal spits out 'none'.
def zap_buzz(x):
i = 0
t = False
while i < 3:
if ((x // 10**i)%10) == 3:
t = True
i += 1
if t == True and x % 7 == 0:
return "zap buzz"
if x % 7 == 0:
return "zap"
if t == True:
return "buzz"

Locating max value in a list

I'm very new to Python programming and I've been tasked by an online friend to write code to solve the following problem:
'imagine a board game and you have to roll 2 dices.Write a program to roll the dices 100 times and find out which value (of both dices) appears most'
My attempt below kind of works in the sense that I'm able to ascertain the max frequency of two dice faces added together but not the actual dice thrown.(e.g. the total '9' was the most frequently thrown).
I'm sure there are plenty of ways of accomplishing the above so do excuse my very first attempt at coding!
import random
results = []
freq_2 = 0
freq_3 = 0
freq_4 = 0
freq_5 = 0
freq_6 = 0
freq_7 = 0
freq_8 = 0
freq_9 = 0
freq_10 = 0
freq_11 = 0
freq_12 = 0
for i in range(100):
face1 = random.randrange(1,7)
face2 = random.randrange(1,7)
value = face1 + face2
if value == 2:
freq_2 += 1
if value == 3:
freq_3 += 1
if value == 4:
freq_4 += 1
if value == 5:
freq_5 += 1
if value == 6:
freq_6 += 1
if value == 7:
freq_7 += 1
if value == 8:
freq_8 += 1
if value == 9:
freq_9 += 1
if value == 10:
freq_10 += 1
if value == 11:
freq_11 += 1
if value == 12:
freq_12 += 1
results.append(freq_2)
results.append(freq_3)
results.append(freq_4)
results.append(freq_5)
results.append(freq_6)
results.append(freq_7)
results.append(freq_8)
results.append(freq_9)
results.append(freq_10)
results.append(freq_11)
results.append(freq_12)
print max(results)
print freq_2, freq_3, freq_4, freq_5, freq_6, freq_7, freq_8, freq_9, freq_10, freq_11, freq_12
collections provides Counter which makes this task easy:
from random import choice
from collections import Counter
dice = range(1,7)
freq = Counter([choice(dice) + choice(dice) for i in range(100)])
print freq
print freq.most_common(1)
I would redo much of it, reducing the amount of variables you're using.
rather than a separate variable for each freq_#, use a list:
freqs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 12 zeroes
for i in range(100):
face1 = random.randrange(1,7)
face2 = random.randrange(1,7)
value = face1 + face2
freqs[value] += 1
This way, you also will not have to individually append each freq_# to a list afterwards.
Once this list is filled with its values, you can use a few simple python calls to find the data you'd like:
'The most frequent throw was 9 and it occurred 21 times'
The most frequent throw will be the index with the highest number in the list.
max_freq = max(freqs) # amount of times this number was thrown
the number that was rolled will be represented by the index of the max
most_frequent_roll = freqs.indexOf(max_freq) # the number that was thrown that many times.
You don't need to write explicitly all the cases. For such a task python dictionaries are very useful.
I won't solve the problem for you, but give you a hint how you could implement this using dictionaries:
# define a dictionary to hold the counts (just for a single dice here)
counts = {nbr_dots: 0 for nbr_dots in range(1, 7)}
# this will look like {1:0, 2:0, ...}
# now whenever you get a certain count (say 2 here) you can increment the value of
# this count by 1 like so:
counts[2] += 1
# now counts looks like: {1:0, 2:1, ...}
If then you want to get the key (so the count) that appeared the most:
most_frequent = max(counts, key=lambda k: counts[k])
# and the number of times it appeared:
nbr_observations = counts[most_frequent]
Hope this minimal example helps to get you started.
The other answers are good, but if for some reason you don't want to use them, then here is a simple loop that does the job after you have calculated the result.
maximum = 0
for i in range(len(results)):
if results[i] > maximum:
maximum = results[i]
itemAt = i
print('The most frequent throw was: '+ str(results[itemAt]))
print('It occured %d times' % maximum)
What you must do to find the value of each die is you must compose another for loop which records when the value of each face is a certain number, and then increase the frequency of that value:
face_freq_2 = 0
face_freq_3 = 0
face_freq_4 = 0
face_freq_5 = 0
face_freq_6 = 0
face_freq_7 = 0
face_freq_8 = 0
face_freq_9 = 0
face_freq_10 = 0
face_freq_11 = 0
face_freq_12 = 0
for j in range(100):
face_value1 = random.randrange(1,7)
face_value2 = random.randrange(1,7)
value1 = face_value1
value2 = face_value2
if (value1 == value2) and (value1 == 1):
face_freq_2 += 1
if (value1 == 1 and value2 == 2) or (value1 == 2 and value2 == 1):
face_freq_3 += 1
if (value1 == value2) and (value1 == 2):
face_freq_4 += 1
elif (value1 == 1 and value2 == 3) or (value1 == 3 and value2 == 1):
face_freq_4 += 1
if (value1 == 1 and value2 == 4) or (value1 == 4 and value2 == 1):
face_freq_5 += 1
elif (value1 == 2 and value2 == 3) or (value1 == 3 and value2 == 2):
face_freq_5 += 1
if (value1 == value2 and value1 == 3):
face_freq_6 += 1
elif (value1 == 1 and value2 == 5) or (value1 == 5 and value2 == 1):
face_freq_6 += 1
elif (value1 == 2 and value2 == 4) or (value1 == 4 and value2 == 2):
face_freq_6 += 1
From this you get the picture of what you must do, for as the values increase you will need more elif statements in addition to the initial if statement. Yes, it is a bit tedious but it should yield the desired results.

Categories