New to Python & the community. Navigating different exercises and I'm having trouble finding the solution. I need to remove the trailing, that follows when using end=','
Any wisdom or guidance is very appreciated!
low = 10000
up = 10050
for num in range(low, up + 1):
if num > 1:
for i in range(2, num):
if (num % i) == 0:
break
else:
print(num,end=',')
It looks like you're trying to print prime numbers in a given range. Arguably, mixing discovery of prime numbers and printing them is what causes the problem. With proper decomposition, this problem won't exist:
def generate_primes(low, up):
for num in range(max(low, 2), up+1):
if all(num % i for i in range(2, num)):
yield num
print(*generate_primes(low, up), sep=',')
As a positive side effect, you can now reuse prime generator in other parts of the program which don't require printing.
Also note that checking all numbers up to num is not necessary - if the number is composite one of the factors will be less or equal to sqrt(num). So, a faster prime generator would be something like:
def generate_primes(low, up):
for num in range(max(low, 2), up+1):
if all(num % i for i in range(2, int(num**0.5 + 1))):
yield num
Try this :
low = 10000
up = 10050
nums = []
for num in range(low, up + 1):
if num > 1:
for i in range(2, num):
if (num % i) == 0:
break
else:
nums.append(str(num))
a = ",".join(nums)
print(a)
Essentially, just add all the elements that will be outputted in a list and then use the join function to convert them into a string and print it.
Solution
import sys
low = 10000
up = 10050
firstValuePrinted = 0
for rootIndex, num in enumerate(range(low, up + 1)):
if num > 1:
for subIndex, i in enumerate(range(2, num)):
if (num % i) == 0:
break
else:
print("", end = "," if firstValuePrinted==1 else "")
firstValuePrinted = 1
print(num, end = "")
sys.stdout.flush()
Explanation
Since we can't determine on which number num the loop will exit we can't exactly know the end condition. But we can figure out the starting number.
So based on that logic, instead of printing the "," at the end we actually print it at the start by using a variable to maintain if we have printed any values or not in the above code that is done by firstValuePrinted.
sys.stdout.flush() is called to ensure the console prints the output right away and does not wait for the program to complete.
Note: Don't forget to import sys at the start of the file.
Benefits when compared to other answers
This type of implementation is useful if you want to output the num variable continuously so as to not have to wait for all the numbers to be calculated before writing the value.
If you put all the values into an array and then print, you actually need large memory for storing all the numbers (if low and up is large) as well as the console will wait till the for loop is completed before executing the print command.
Especially when dealing with prime numbers if the low and up variables are far apart like low=0 and up=1000000 it will take a long time for it to be processed before any output can be printed. While with the above implementation it will be printed as it is being calculated. While also ensuring no additional "," is printed at the end.
Related
My code it generates a random number it checks if it is in the list if it is it generates another random number and then it checks if it is equal or not and shows the result and repeats the process. But when I start the code it generated the normal number but it repeats the numbers and it shouldn't repeat the number. What do I do?
from random import randint
import os
n = 0
numsort = 14564487
attempt = 0
numbers = []
while n < 100:
num = randint(10000000, 99999999)
if num in numbers:
num = randint(10000000, 99999999)
numbers.append(num)
attempt += 1
if num == numsort:
print(f'{num}' + '\033[32m' + ' Right number' + '\033[0m')
print(f'After {attempt} attempts it was')
break
if num != numsort:
print(f'{num}' + '\033[31m' + ' Wrong number' + '\033[0m')
print(f'Attempt # {attempt}')
os.system('clear')
The issue here is a simple one. The primary problem is with this code snippet:
num = randint(10000000, 99999999)
if num in numbers:
num = randint(10000000, 99999999)
numbers.append(num)
Translating this to English, we have:
Generate a random seven-digit integer
If the integer is in our list of numbers then regenerate it and add it to the list
The problem you have here is that you have no guarantee that the regenerated number won't also be in the list. The chance of this happening will grow as the list grows. And, since your loop variable is never updated, this list will grow infinitely.
To fix this problem, you have two possible solutions. For small lists, you can continue on with your strategy of regenerating numbers and replace the if with a while:
num = randint(1000000, 9999999)
while num in numbers:
num = randint(1000000, 999999999)
numbers.append(num)
Note that this will only work while the desired size of your list is much smaller than the range of possible values being generated. As you fill up the list, the chance of collisions between the range of possible values and actual values will increase, causing the while loop to run longer.
Alternatively, you can use sample to choose your values, which would replace the entire loop:
numbers = random.sample(range(1000000, 10000000), n)
Note here that the use of range means that this is actually just as space efficient as the previous solution and will guarantee unique values.
Ok i wrote this in python then rewrote because i don't like if else statements.
the first version worked perfectly. my second one failed and ended up taking more lines than my first version. my question is, am i just stupid? is there a better way to do this or should i just accept the need for if else statement?
sorry for the code dump, i am going mad
first attempt
#number we are starting with
num = 1
#what we are going to apply equation loop to
result = num
#how many times goes through equation loop before reaching 1
count = 0
# list of numbers used in equation loop
num_in_loop = [result]
#end equation loop function.
running = True
# equation loop
def eqation_loop(running, num_in_loop, count, num, result):
while running == True:
if (result % 2) == 0:
result = result /2
count +=1
num_in_loop.append(result)
elif result == 1.0:
print(num, "took", count ," loops to get to 1: numbers in loop = ", num_in_loop, file=open('3x+1/result.txt','a'))
num +=1
print(num)
result = num
num_in_loop = [result]
count = 0
elif num == 100:
running = False
elif (result % 2) != 0:
result = result * 3 + 1
count +=1
num_in_loop.append(result)
eqation_loop(running, num_in_loop, count, num, result)
second attempt:
#number we are starting with
num = 1
#what we are going to apply equation loop to
result = num
#how many times goes through equation loop before reaching 1
count = 0
# list of numbers used in equation loop
num_in_loop = [result]
limit = int(input("range you want to try: " ))
def update_var(num_in_loop,result,count):
count +=1
num_in_loop.append(result)
return equation_loop(limit,num, result)
def reset_var(num_in_loop, count, limit,num, result):
print(num, "took", count ," loops to get to 1: numbers in loop = ", num_in_loop, file=open('3x+1/test.txt','a'))
num +=1
result = num
num_in_loop = [result]
count = 0
return equation_loop(limit,num, result)
def equation_loop(limit,num, result):
if num == limit:
return
elif result == 1:
return reset_var(num_in_loop, count, limit,num, result)
elif (result % 2) == 0:
result = result /2
return update_var(num_in_loop,result,count)
elif (result % 2) != 0:
result = result *3 +1
return update_var(num_in_loop,result,count)
equation_loop(limit,num, result)
You can't write this without any if/else statements (okay maybe if you really know what you're doing you technically can by severely abusing while, but you shouldn't), but here's a simplified-down version that hopefully contains some useful examples of how to make your code easier to write (and read!):
def equation_loop(num: int) -> list[int]:
"""
Repeatedly applies the magic equation trying to
reach 1.0, starting with num. Returns all the results.
"""
nums = [num]
while True:
if num == 1:
return nums
if num % 2:
num = num * 3 + 1
else:
num = num // 2
nums.append(num)
for num in range(1, 100):
results = equation_loop(num)
print(f"{num} took {len(results)} loops to get to 1: {results}")
A key thing here is that you don't need so many variables! A single loop only needs its starting point (num) and only needs to return the list of results (from which you can get the count, since it'll be the length of the list). Reducing the number of redundant variables eliminates a lot of unnecessary lines of code that are just copying state back and forth. Passing a value like running = True is unnecessary when it will always be True until it's time to end the loop -- instead just use while True: and return or break when you're done.
The big takeaway is that if you have two variables that always have the same value (or even two values that are always related in exactly the same way, like a list and its length), you probably just need one of them.
You can also simplify the code by separating the two nested loops -- for a given num you want to loop until the number reaches 1, so that's one loop. You also want to loop over all the nums up to 99 (it took me a while to even figure out that that's what the code was doing; I had to run it and look at the output to see that some of those extra pieces of state were serving to implement nested loops inside a single loop). Doing those in two different loops makes it easy, and you can put one of them in a nice neat function (I used your equation_loop name for that, although it does less work than your original version does) that takes the starting num and returns the list of results for that starting point. That simple function can then be called in an even simpler for loop that iterates through the nums and prints the results for each one.
Note that I kept everything as ints by using int division (//) -- testing floats for exact equality is often dangerous because floating point numbers aren't exactly precise! Your equation is always operating with integer values (because you only divide by two if it's an even number) so it makes more sense to use int division and not even worry about floating point values.
I am trying to put together a simple program which could work out n prime numbers. I would like to do this by using a nested for loop, where one would go through the numbers, and another would divide that number by all of the numbers up to it to see if it would be divisible by anything.
The problem I am having is that in the main for loop, I need to start it at 2, seeing as 1 would mess up the system and I don't want it to be considered a prime. For the loop to have a starting number however, it also needs an ending number which is difficult in this instance as it is hard to generate the largest prime that will be needed prior to the loop working.
Here's the program that I am using right now. Where I have marked X is where I need to somehow put an ending number for the For Loop. I guess it would be much simpler if I let the For Loop be completely open, and simply take out anything that '1' would produce in the loop itself, but this feels like cheating and I want to do it right.
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
for i in range(2,X):
check = 0
if i > 1:
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
print (i)
Thanks for your help!
You can step through an unlimited amount of numbers using a generator object.
Insert the following somewhere near the top of your code:
def infinite_number_generator(initial_value=2):
""" Generates an infinite amount of numbers """
i = initial_value
while True:
yield i
i += 1
What this does is it creates a function for constructing generator objects that "pause" whenever they reach the yield statement to "yield" whatever value is specified by the yield command, and then continue to execute from the next line beneath the yield statement.
Python's own range function is itself an example of a generator, and is roughly equivalent to (ignoring the step argument and other peculiarities)
def range(start, end):
i = start
while i < end:
yield i
i += 1
So your program would then look like this:
def infinite_number_generator(initial_value=2):
""" Generates an infinite amount of numbers """
i = initial_value
while True:
yield i
i += 1
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
for i in infinite_number_generator():
check = 0
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
print (i)
if i == limit:
break
I should also point out that the code you provided is buggy - it will never stop printing because there's no checking whether you've found your limit number of primes yet or not.
This should do what you want.
check = 0
limit = int(input("Enter the amount of Prime Numbers"))
counter = 0
i = 2
while counter < limit:
check = 0
if i > 1:
for j in range(2,i):
if (i % j) == 0:
check = 1
if check == 0:
counter += 1
print (i)
i += 1
In your code you start i with 2 and always increment by 1, so the i will always remain greater than 1, therefore the test if i > 1 is useless.
For efficiency you can stop the check at the square of i or i/2 (no divisors in [i/2 + 1, i[ ).
you can update your code as follow:
n = int(input("Enter the amount of Prime Numbers: "))
FoundPrimes = 0
i = 2
while FoundPrimes < n:
isPrime = True
for j in range(2,1 + i//2):
if (i % j) == 0:
isPrime = False
if isPrime:
FoundPrimes += 1
print(i, end = '\t')
i += 1
I've recently started learning Python. My apologies if this is really obvious.
I am following along with the 2008 MIT open course on Computer Science and am working on the problem of calculating the 1000th prime integer. Python 2.7.3, Win7 lappy (cough, cough...)
Here's the code I came up with:
num = 3
primeList = [2]
while len(primeList) < 1000:
for i in primeList:
if num % i == 0:
break
else:
primeList.append(num)
num += 1
print "The 1,000th PRIME integer is", primeList[999]
One of the assignment conditions was to only check odd numbers. Given the starting num is three, I figured it would be easy enough to simply change num+=1 to num+=2. Of note: I won't bore you with the detailed code I composed, but while writing this I was using a very verbose mode of printing out the results of each check, whether or not it was prime, which number was being checked, which integer divided into it if it wasn't prime & such (again, sorry - newB!)
At this point I became curious to test if this was actually taking less time to compute - seemed like if half the numbers are being checked for primacy, it should take half the time, no?
I imported the time module to check how long this was taking. Computing to the 1000th was pretty quick either way so I increased the number of primes I was searching for to the 10,000th and didn't see any significant difference. between num+=1 & num+=2
import time
start = time.time()
num = 3
primeList = [2]
while len(primeList) < 10000:
for i in primeList:
if num % i == 0:
break
else:
primeList.append(num)
num += 2
print "The 10,000th PRIME integer is", primeList[9999]
end = time.time()
print "That took %.3f seconds" % (end-start)
Sometimes the n+=2 even took a couple milliseconds longer. ?. I thought this was odd and was wondering if someone could help me understand why - or, more to the point: how?
Furthermore, I next imported the sqrt() function thinking this would reduce the number of integers being checked before confirming primacy, but this doubled the runtime =^O.
import time
start = time.time()
from math import sqrt
num = 3
primeList = [2]
while len(primeList) < 100000:
for i in primeList:
if i <= sqrt(num):
if num % i == 0:
break
else:
primeList.append(num)
num += 2
print "The 100,000th PRIME integer is",primeList[99999]
end = time.time()
print 'that took', end - start, "seconds, or", (end-start)/60, "minutes"
Certainly - it might be the way I've written my code! If not, I'm curious what exactly I am invoking here that is taking so long?
Thank you!
Two things.
First, you're calculating sqrt(n) on every loop iteration. This will add work, because it's something else your code now has to do on every pass through the loop.
Second, the way you're using sqrt doesn't reduce the number of numbers it checks, because you don't exit the loop even when i is bigger than sqrt(n). So it keeps doing a do-nothing loop for all the higher numbers.
Try this instead:
while len(primeList) < 100000:
rootN = sqrt(num)
for i in primeList:
if i <= rootN:
if num % i == 0:
break
else:
primeList.append(num)
break
else:
primeList.append(num)
num += 2
This finds 100,000 primes in about 3 seconds on my machine.
I am working on a function which takes a positive integer N and computes the following sum:
1 - 2 + 3 - 4 + 5 - 6 + .... N.
My professor said we can not use "math formulas" on this, so how could I go about it?
I thought about using a for loop, but I don't know how or what to write for the print statement. This is what I have so far:
n=int(input("enter N="))
for i in range(1, n+1, 1):
if i % 2 == 0:
# I'm not sure what print statement to write here
I tried print(i= "+" i+1) and just weird stuff like that, but I get errors and am lost after that.
what i have now
n=int(input('enter N='))
total=0
print("sum",)
for i in range(1, n+1, 1):
if i % 2 == 0:
count=count - i
print("-", i)
else:
count=count + i
print("+", i, end=" ")
print("=", total)
#still get errors saying name count not defined and unsupported sperand for +:
First, to accumulate the sum as described, and to do it by looping instead of "using math formulas", you want to do this:
n=int(input("enter N="))
total = 0
for i in range(1, n+1, 1):
if i % 2 == 0:
????
else:
????
print(total)
You should be able to figure out what the ???? are: you need to do something to total for each i, and it's different for even and odd.
Now, if you want it to print out something like this:
sum 1 - 2 + 3 - 4 + 5 - 6 + .... N = X
You can print things out along the way like this:
n=int(input("enter N="))
total = 0
print ("sum", end=" ")
for i in range(1, n+1, 1):
if i % 2 == 0:
print("-", i, end=" ")
????
else:
if i == 1:
print(i, end=" ")
else:
print("+", i, end=" ")
????
print("=", total)
If you want to keep negative and positive totals separately and then add them, as you mentioned in an edit, change total = 0 to ntotal, ptotal = 0, 0, then change each of the ???? parts so one works on one total, one on the other.
All of the above is for Python 3. If you want to run it in Python 2, you need to turn those print function calls into print statements. For the simple cases where we use the default newline ending, that's just a matter of removing the parentheses. But when we're using the end=" ", Python 2's print statement doesn't take keyword parameters like that, so you instead have to use the "magic comma", which means to end the printout with a space instead of a newline. So, for example, instead of this:
print("+", i, end=" ")
You'd do this:
print "+", i,
Again, for Python 3, you don't have to worry about that. (Also, there are ways to make the exact same code run in both Python 2 and 3—e.g., use sys.stdout.write—which you may want to read up on if you're using both languages frequently.)
You're most of the way there already. I'm not sure why you think you need to put a print statement inside the loop, though. You only want one result, right? You already have if i % 2 == 0 - which is the case where it's even - and you want to either add or subtract based on whether the current i is odd or even. So keep a running tally, add or subtract in each loop iteration as appropriate, and print the tally at the end.
You see the difference between what happens with odd and even numbers, which is good.
So, as you cycle through the list, if the number is even, you do one operation, or else you do another operation.
After you've computed your result, then you print it.
There are a lot of explanations in the answers already here. So I will try to address the different ways in which you can compute this sum:
Method 1:
def mySum(N):
answer = 0
for i in range(1, N+1):
if i%2:
answer += i
else:
answer -= i
return answer
Method 2:
def mySum(N):
answer = 0
for i in range(1, N+1, 2):
answer += i
for i in range(2, N+1, 2):
answer -= i
return answer
Method 3:
def mySum(N):
pos = range(1, N+1, 2)
neg = range(2, N+1, 2)
return sum(pos) - sum(neg)
Method 4:
def mySum(N):
return sum([a-b for a,b in zip(range(1, N+1, 2), zip(2, N+1, 2))])
Method 5:
def mySum(N):
return sum([i*-1 if not i%2 else i for i in range(1,N+1)])
Method 6:
def mySum(N):
return sum(map(lambda n: n*[-1, 1][i%2], range(1, N+1)))
Again, these are only to help prime you into python. Others have provided good explanations, which this is not meant to be
count = 0
print "0"
for i in range(1, n+1, 1):
if i % 2 == 0:
count = count - i
print "-" , i
else:
count = count + i
print "+" , i
print "=", count