Python Fizzbuzz problems with loop - python

I've searched for the answer for about an hour, and it seems most people have coded fizzbuzz a different way than myself.
However, having tried everything to figure out why this simple code will not work I'm getting extremely frustrated.
Can anyone point out the simple problem I'm sure I'm having? The code runs but it just returns the value 1.
def fizzbuzz(intList):
for n in intList:
if n % 3 == 0 and n % 5 == 0:
return n.replace(str(n),"Fizzbuzz")
elif n % 3 == 0:
return n.replace(str(n),"Fizz")
elif n % 5 == 0:
return n.replace(str(n),"Buzz")
else:
return n

The first value it looks at is 1. Since 1%x is only 0 for an x of 1, it goes to the else and returns 1. And then it's done, because that's what return does.
That leads to the bigger problem, which is that you are starting a loop and then guaranteeing that you will leave that loop after only one iteration, because there's a return in every branch. You'll need to replace those return statements with either append()s to a list (don't forget to return the resulting list) or print() calls.
Also, if you started with something like 3, your code would try to use replace on an integer, which is not something you can do with integers. You would get a traceback.

The code is returning 1 because consider this list [1,2,3,4,5,6,7,8,9,10]. All three conditions will get false and the last else will return 1. If you want the answer, append them into list.
Something like this:
def fizzbuzz(intList):
temp = []
for n in intList:
if n % 3 == 0 and n % 5 == 0:
temp.append("Fizzbuzz")
elif n % 3 == 0:
temp.append("Fizz")
elif n % 5 == 0:
temp.append("Buzz")
else:
temp.append(n)
return temp
print fizzbuzz(range(1,20))

Perhaps if you take a look at this code you will
better understand yours. Although this is a completely
different implementation of fizzbuzz in Python3
#!/usr/bin/python3
for i in range(1,100):
msg = "Fizz" * bool(i%3==0)
msg += "Buzz" * bool(i%5==0)
if not msg:
msg = i
print(msg)

My skills in python are fairly average but i love using dicitonaries. Here is the Fizz Buzz program using dictionaries.Without an if.
for data in range(1, 101):
msg = [str((data % 3 == 0)), str((data % 5 == 0))]
// msg returns a list with ['True' ,'False'] depending on the condition
conveter = {"True False": "Fizz",
"False True": "Buzz",
"True True": "Fizz Buzz",
"False False": data
}
val = conveter[" ".join(msg)]
print(val)

I just implemented FizzBuzz as
for n in range(1, 100):
if n%15==0: print "FizzBuzz"
elif n%5==0: print "Buzz"
elif n%3==0: print "Fizz"
else: print n
The best thing with it that
It works
It fits into a tweet, with a margin

Years later, based on this...
FizzBuzz: For integers up to and including 100, prints FizzBuzz if the integer is divisible by 3 and 5 (15); Fizz if it's divisible by 3 (and not 5); Buzz if it's divisible by 5 (and not 3); and the integer otherwise.
def FizzBuzz():
for i in range(1,101):
print {
3 : "Fizz",
5 : "Buzz",
15 : "FizzBuzz"}.get(15*(not i%15) or
5*(not i%5 ) or
3*(not i%3 ), '{}'.format(i))
The .get() method works wonders here.
Operates as follows
For all integers from 1 to 100 (101 is NOT included),
print the value of the dictionary key that we call via get according to these rules.
"Get the first non-False item in the get call, or return the integer as a string."
When checking for a True value, thus a value we can lookup, Python evaluates 0 to False. If i mod 15 = 0, that's False, we would go to the next one.
Therefore we NOT each of the 'mods' (aka remainder), so that if the mod == 0, which == False, we get a True statement. We multiply True by the dictionary key which returns the dictionary key (i.e. 3*True == 3)
When the integer it not divisible by 3, 5 or 15, then we fall to the default clause of printing the int '{}'.format(i) just inserts i into that string - as a string.
Some of the output
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz

how a python function should look like if we want to see the next result in the interactive mode of the python interpreter:
>>> fizz(15)
[ 1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz' ]

n = int(input())
out = []
for i in range(1, n):
if i % 3 == 0 and i % 5 == 0:
out.append("fizzbuzz")
continue
elif i % 3 == 0:
out.append("fizz")
continue
elif i % 5 == 0:
out.append("buzz")
continue
out.append(i)
print(out)
Answer as [1,2,'fizz']

x = int(input('Enter the number: '))
if x % 3 ==0 and x % 5 ==0:
print('FizzBuzz')
elif x % 3 ==0:
print('Fizz')
elif x % 5 ==0:
print('Buzz')
else:
print(f'{x} ¯\_(ツ)_/¯')

Related

problem with a recursive function code for beginners

I'm currently learning about recursive functions on Python. So far I've solved this task:
A gold coin is placed in the safe and the safe is closed. The safe is then placed in another, larger safe and another gold coin is added. The second safe is placed in a third, even bigger safe, adding two more gold coins, etc. So with the first safe, 1 gold coin is placed in the next, with the second 2 gold coins, with the third 3 gold coins, etc.
Create a recursive function that takes the sequence number of the safe as an argument and returns the total number of gold coins hidden in this safe.
`
def gold(n):
if n == 1:
return 1
else:
return gold(n-1)+(n-1)
`
Now, I need to write a code where the number of coins increases like this: when n equals 1, return value is 2; when n equals 2, return value is 3; when n equals 3, return value is 4; when n equals 4, return value is 6; when n equals 5, return value is 7; when n equals 6, return value is 8; when n equals 7, return value is 10 and so on (the number of coins increases by 1 every time, except when n = 4, 7, 10, 13... where it increases by 2).
For example, the code should return these values:
>>> gold(7)
10
>>> gold(8)
11
So far I've only got this:
def gold(n):
if n == 1:
return 2
else:
How can I do so that usually the number of gold coins is increased by one coin but every 4th, 7th, 10th, ...etc it increases by two? I know this is probably a very easy and stupid question, but I can't figure it out
This code does what you want (you just have to test whether n == 4, 7, 10..., that is n == 3k+1, in other words, n modulo 3 == 1):
def gold(n):
if n == 1:
return 2
if n%3 == 1: # if n == 3k+1, so for n = 4, 7, 10 ...
return 2 + gold(n-1)
return 1 + gold(n-1)
Look according to your explanation every 4th, 7th and 10th ... safe should be added with TWO coins, so we can check so with a condition :
if n % 3 == 1:
return 2 + gold(n-1)
and in addition to my answer according to your explanation The First Safe will have two coins in it ... and hence the base/stop case will have the condition :
if n == 1:
return 2
So, the final recursive function will be :
def gold(n):
if n == 1:
return 2
elif n % 3 == 1:
return 2 + gold(n-1)
else:
return 1 + gold(n-1)
and the Output will be of your desire :
>>> gold(7)
10
>>> gold(8)
11
Maybe this is what you want
def gold(n):
if n == 1:
return 1
if (n - 1) % 3 == 0:
return 2 + gold(n-1)
else:
return 1 + gold(n-1)
You probabbly wants something like this:
Edited:
def gold(n):
if n == 1:
return 1
elif n == 2:
return 2
elif n % 2 == 0:
return gold(n-1) + 1
else:
return gold(n-1) + 2

Strange output when trying to find prime numbers Python

Ok, so I admittedly am kind of a noob, and I've been going through a course on udemy for programming. The problem is asking to write a function that finds all the prime numbers up to the number given. So I started writing the following code to extract the numbers that are not even, as well as the numbers not evenly divisible by 3 just to start:
def count_primes(num):
num_list5 = []
for i in range(num + 1):
print(i)
if i % 2 != 0 or i % 3 != 0:
num_list5.append(i)
return num_list5
When I call the function with a number of 100 like:
count_primes(100)
In the output, I get the num_list5 showing all the numbers in the range except for 6 and multiples of 6:
[1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14 ...]
Its like the if statement is doing an AND operation here... because 6 would be divisible by 2 AND 3. Is this a bug or something? Or am I not understanding and/or operations correctly?
What's weird is that it was working at one point and after making a change and reverting it, it started doing this...
I'm using VSCode and Jupyter notebooks and tried both Python 3.8.5 64-bit and 3.9.4 64-bit on Ubuntu 20.04
i % 2 != 0 or i % 3 != 0 is equal to not (i % 2 == 0 and i % 3 == 0) (De Morgan's laws)
It should be i % 2 != 0 and i % 3 != 0
If you are looking to generate all primes less than num, you should loop over all numbers j less than i and check if i%j is zero rather than just 2 and 3.
def count_primes(num):
num_list5 = []
for i in range(2, num + 1): # start at 2 because 1 and zero are not primes
print(i)
for j in range(2, i):
if i%j == 0:
break
else:
num_list5.append(i)
return num_list5
if __name__ == "__main__":
n = 100
print(count_primes(n))
Note that using Sieve of Eratosthenes method, this can be done more efficiently:
import math
def count_primes_sieve(num):
num_list5 = [False, False] + [True]*(num - 1)
for i in range(2, math.ceil(math.sqrt(num)) + 1):
if num_list5[i]:
j = i * i
while j < len(num_list5):
num_list5[j] = False
j += i
return [i for i, p in enumerate(num_list5) if p]
if __name__ == "__main__":
n = 100
print(count_primes_sieve(n))
We know some facts about prime numbers which you can use in your program. Negative numbers, 0 and 1 are not prime. 2 is the only even prime. A prime number only has itself and 1 as factors. From multiplication we know that if a x b = c then one of a, b is <= sqrt(c). That last fact helps us cut down the number of trial divisors we have to test. We can test for a prime by looking for a number that divides the target but is not the target itself or 1. If we find such a number then the target is not prime.
Here is some pseudocode to help:
function isPrime(num)
// 1, 0, negatives not prime.
if (num < 2)
return false
end if
// 2 is the only even prime.
if (num MOD 2 = 0)
return (num = 2)
end if
// Try odd factors up to square root.
limit <- 1 + sqrt(num)
for (test <- 3; test < limit; test <- test + 2)
if (num MOD test = 0)
// Not prime, we have found a factor.
return false
end if
end for
// If we get this far then num is prime.
return true
end function
After figuring out the propositional math and de Morgan's Law as someone pointed out, I was able to come up with a pretty simple solution using or and mod operators and only goes through a the sequence once:
def count_primes(num):
num_list5 = []
for i in range(2, num + 1):
if i == 2 or i == 3 or i == 5 or i == 7:
num_list5.append(i)
if not (i % 2 == 0 or i % 3 == 0 or i % 5 == 0 or i % 7 == 0):
num_list5.append(i)
return num_list5
print(count_primes(100))

Project Euler #37 issue

I tried to solve Project Euler #37:
The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
I wrote my code in Python but I am facing weird issues.
Here's my code:
def isPrime(n):
if n == 2 or n == 3 or n == 5: return True
if n < 2 or n%2 == 0: return False
if n < 9: return True
if n%3 == 0: return False
if n%5 == 0: return False
r = int(n**0.5)
f = 5
while f <= r:
if n%f == 0: return False
if n%(f+2) == 0: return False
f +=6
return True
def gen(nb):
results = []
nb_str = str(nb)
for k in range(0, len(nb_str) - 1):
results.append(nb_str[k:])
results.append(nb_str[-k:])
return results
def check(nb):
for t in gen(nb):
if not isPrime(int(t)):
return False
return True
c = 0
s = 0
i = 2
while c != 11:
if check(i):
c += 1
s += i
i += 1
print(s)
Where does the error come from? (The expected result is 748317)
I suspect the errors coming from the results list
Yes, the gen() function is not working correctly as your slicing is off, also, you count 2, 3, 5 and 7 as truncatable primes which the question denies.
The second slice should be the other way around:
>>> s = 'abcd'
>>> for i in range(1,len(s)-1):
... print(s[i:])
... print(s[:-i])
...
bcd
abc
cd
ab
which we can see produces the right strings.
Altogether then, the function should be:
def gen(nb):
results = [nb]
nb_str = str(nb)
for k in range(1, len(nb_str)):
results.append(int(nb_str[k:]))
results.append(int(nb_str[:-k]))
return results
note I also added a string to int conversion - not sure how Python didn't make that obvious for you :/
And before get the full solution, Project Euler nearly always gives you an example which you can use to check your code:
>>> check(3797)
True
You must also add a condition in the check function to return False if the number is 2, 3, 5 or 7 as this is stated clearly in the question.
And the result is the expected: 748317.
Joe Iddon has explained the error in your code, but you can speed it up a little by turning gen into an actual generator. That way, you can stop checking the results for a given nb as soon as you detect a composite number (and gen will stop generating them). I've also made a few minor tweaks to your primality tester. Remember, the or operator short-circuits, so if a is True-ish in a or b then it doesn't bother evaluating b.
def isPrime(n):
if n in {2, 3, 5, 7}:
return True
if n < 2 or n%2 == 0:
return False
if n%3 == 0 or n%5 == 0:
return False
r = int(n**0.5)
f = 5
while f <= r:
if n%f == 0 or n%(f+2) == 0:
return False
f += 6
return True
def gen(nb):
yield nb
nb_str = str(nb)
for k in range(1, len(nb_str)):
yield int(nb_str[k:])
yield int(nb_str[:-k])
def check(nb):
for t in gen(nb):
if not isPrime(t):
return False
return True
c = s = 0
# Don't check single digit primes
i = 11
while c < 11:
if check(i):
c += 1
s += i
print(i)
i += 2
print('sum', s)
output
23
37
53
73
313
317
373
797
3137
3797
739397
sum 748317
In fact, you can get rid of the check function, and replace it with all, which also short-circuits, like or does. So you can replace the
if check(i):
with
if all(map(isPrime, gen(i))):

Why doesn't my answer to project euler 3 work?

I've been trying to solve project Euler problem #3 for a while now. The code below still doesn't work the way I want it to.
Question 3: The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
getal = 13195
x = 2
while x in xrange(2,getal):
if getal % x == 0:
num = getal / x
for i in xrange (2,num):
if num % i == 0:
x += 1
break
else:
print num
else:
x += 1
continue
As you can see I'm running it right now with 13195 for the sake of simplicity, but eventually it should have to work with the bigger number.
My output is this:
2639 2639 2639 2639 2639 1885 1885 1885 1015 1015 1015 455 455 455 377
377 377 377 377 377 377 377 377 377 377 203 203 203 203 203 145 145
145 91 91 91 91 91 65 65 65 35 35 35 29 29 29 29 29 29 29 29 29 29 29
29 29 29 29 29 29 29 29 29 29 29 29 29 29
29 goes on for a while longer than I showed.
I do understand it just prints the number as soon as it has found an "i" that this number cannot be divided by. But I don't know how to prevent it from doing this. Because in the end 29 is the right answer, however it should just give this answer once and right away.
You can simplify your code to the code snippet below. It uses a list to store any candidates and then removes them if they are not prime numbers:
import math
getal = 600851475143
x = 2
candidates = [];
while (x < int(math.sqrt(getal)+1)):
if getal % x == 0:
candidates.append(x)
for i in xrange (2,int(math.sqrt(x)+1)):
if x % i == 0:
candidates.remove(x)
break
x = x + 1
print str(candidates).strip('[]')
You need to break out of your while when you find the answer.
You are not incrementing 'x' after print num statement.
for i in xrange (2,num):
if num % i == 0:
break
else:
print num
x += 1
you should be able to even getrid of second if statement as below
getal = 13195
x = 2
while x in xrange(2,getal):
if getal % x == 0:
num = getal / x
for i in xrange (2,num):
if num % i == 0:
break
else:
print num
x += 1
The Answer is 6857. You don't have to check from 2 to the number. Use the property of primes.Check only up-to the square root of the number that you are checking.You can use my Java Code for reference.
class p3{
public static boolean isprime(long y){
double sq = Math.sqrt(y);
long endl =(long) (sq+.5);
for(long j = 2;j <=endl ;j++)
{
if(y%j==0){
return false;
}
}
return true;
}
public static void main(String []asd){
long test = 600851475143L;
long ans =-1;
double e = Math.sqrt(test);
long end = (long)(e+1);
for(long i = 2 ; i <= end ;i++)
{
if(test%i==0){
boolean val = isprime(i);
if(val){
ans = i;
}
}
}
System.out.println(ans);
}
}
If you need any help. I have solved the problems in Project Euler and have saved them in my github repository. You are more than welcome to fork it.The url is:
https://github.com/vatsarahul999/ProjectEuler-.git
Writing the same code in python.
def isprime(n):
if n < 2:
return False
if n == 2:
return True
if not n & 1:
return False
for x in range(3, int(n**0.5)+1, 2):
if n % x == 0:
return False
return True
Now the main program
v = 13195
x = 2
while(x*x <= v)
if(isprime(x)):
a = x
while(v%x==0)
v=v/x;
x++
print a
Here's a sample (it can be improved in terms of performance):
import math
getal = 600851475143
def prime(number):
for i in xrange(2, int(math.sqrt(number)) + 1):
if (number % i) == 0:
return False
return True
def prime_factors(number):
ret = []
n = number
primes = []
for i in [item for item in xrange(2, int(math.sqrt(n)) + 1)]:
if prime(i):
primes.append(i)
for i in primes:
while n % i == 0:
ret.append(i)
n = n / i
return ret
print prime_factors(getal)
Why is everyone incrementing to find the largest number? Decrease!!!
def largestPrime(num):
from __future__ import division
for i in xrange(num//2 + 1, 1, -1):
if num%i == 0 and all([i%j != 0 for j in range(2,i//2 + 1)]):
return i
you are over complicating, to get all factors
getal = 13195
for x in range(2, getal):
if getal % x == 0:
print x
this one should use the for loop not a while,
to use a while here it would be like this
getal = 13195
x = 2
while x < getal:
if getal % x == 0:
print x
x += 1
you dont need to loop thru the constraints to do the work at the loop level - because you are doing it inside
you are actually very close to getting the right answer, you just need to remove indentation in your else statement to have a for else block:
>>> x = 2
>>> getal = 13195
>>> while x in range(2,getal):
if getal % x == 0:
num = getal // x
for i in range (2,num):
if num % i == 0:
x += 1
break #this will break for loop
else:#this is the only change, moving the else from an else inside of the for to a for else block
print (num)
break this will break while loop
else:
x += 1
continue
29
this is surprising for most people because the for-else statement is not well know but it pretty much means to only run the else block if the for block is not exited with a break.
With this in mind, YES, this code works but as a lot of other people said, this is NOT the best way to accomplish this task. Because #RahulVasta posted a good enough answer already, i wont. It is not to say that your logic does not work, but, since this is programming, there are infinite ways to approach a problem and some are better than others.

How can I condense this simple "if" line of code?

I have a line of code in my program that checks if a number is divisible by several numbers.
However, the way I currently have it is extremely inefficient and ugly.
It currently looks like:
if(x % 1 == 0 and x % 2 == 0 and x % 3 == 0) and so forth for several other numbers. I was hoping someone could teach me how I could take out the long and chain and help me replace it with something that makes more sense so instead it will look like:
if(x % a[1,2,3] == 0)
Is this possible and if so can anyone please help me?
EDIT: The x % 1 == 0, x % 2 == 0, etc.. Is not the full equation. I am checking far more than % 1,2, and 3. I am looking for a solution that can take say.. 1 through 15. That is why I am not using x % 6.
if all(x % k == 0 for k in [1, 2, 3]):
print 'yay'
n = 1*2*3
if(x%n == 0):
#do stuff
Will work for any set of prime numbers.
for 1 through 15,you can use all(x % (k+1) == 0 for k in range(15)). for example::
>>> for x in range(10):
... if all(x % (k+1) == 0 for k in range(3)): #checks weather x is divisible by 1,2,3
... print x
...
0
6
lcm = LCM of set of number to divide i.e. (1,2,3....)
if(x % lcm == 0)
//pass

Categories