-1

I'm trying to make a program to compute all primes smaller than a given number, and the natural logarithm of the product of all those primes. So because we're working with logarithms I could also just add the natural logarithm of each prime smaller than the given number. So I created the program, but the logarithms are acting kinda weird I think? I tried checking whether the summation my program gave was right but firstly my program only gives whole numbers as answers and secondly my calculator gives different answers. Is there something wrong with my code? The primes work fine but as said earlier the logarithms are wrong. See below for my code

def prime_program():
while True:

    answer = raw_input("Do you want to know the primes smaller than a number n and the natural logarithm of the product of those primes? Please answer yes or no    ")

    if answer == "yes":
        n = float(raw_input("Please enter a whole number bigger than 1 ")) 
        counter = 1
        prime = 3.0
        log_of_prime_sum = float(log(2.0)) #I'm starting out with log(2.0) cause 2 is the first prime not counted later



        if n > 2.0:
            print "these are the primes smaller than %d" % n
            print 2.0 #cause I want to see all the primes but only want to check the odd numbers

            while prime < n:

                for x in range(2,int(sqrt(prime))+1): #range only works with integers right?

                    if prime%x == 0.0:       
                        break#because if it isn't a prime I don't want to do anything with it
                else:
                    print(prime) #cause I want to know the primes
                    log_of_prime_sum += float(log(prime)) #cause I want to add all the logs of the primes

                prime += 2.0 #we're starting with three, which is an odd, 
                             #and I'm adding two because I only want to check the odd numbers,
                             #because no even number other than two is prime

            print "the natural logarithm of the product of all the primes smaller than %d is %d"  % (n, log_of_prime_sum)
            ratio = float(float(n)/float((log_of_prime_sum)))
            print "The ratio of %d to the sum of the natural logarithms smaller than %d is %d" % (n, n, ratio) #here I want to print the ratio of n and the log_of_prime_sum
        else:
            print "There is no prime smaller than 2"
    elif answer == "no": #like what why would anyone open this file if he wouldn't want to do this lol
        print "well ok then"
    else:
        print "I'm sorry that was not a valid answer, you can only answer yes or no"
        continue #jumps back to while True:
    return #finished; exit the function
        #here I want to go back to answer = raw_input

prime_program()

here is my output in windows powershell

Do you want to know the primes smaller than a number n and the natural log
arithm of the product of those primes? Please
answer yes or no    yes
Please enter a whole number bigger than 1 8
these are the primes smaller than 8
2.0
3.0
5.0
7.0
the natural logarithm of the product of all the primes smaller than 8 is 5
The ratio of 8 to the sum of the natural logarithms smaller than 8 is 1
pokemonfan
  • 209
  • 1
  • 2
  • 9

1 Answers1

1

Although your program is quite chaotic (and the way to determine whether the number is prime is far from optimal, there is probably one mistake).

log_of_prime_sum += log_of_prime_sum+float(log(2.0))

+= means that you "increase" the variable with the operand, so you state:

log_of_prime_sum = log_of_prime_sum+log_of_prime_sum+float(log(2.0))

A way to prevent such errors is for instance to initialize (at the top of your program, the log_of_prime_sum already with float(log(2.0)), it will even improve the performance of your algorithm a tiny bit.

In other words, you double the log_of_prime_sum...

But I would advice you to make the code more readable and use a faster prime check. You can for instance already stop enumerating potential dividers at log(n) with n the number you wish to check, so that would read:

for x in range(2,int(sqrt(prime))) :
    if prime%x == 0.0:
        break

And it is perhaps advisable to use int's for the prime calculation and only convert to a float in case you wish to add it to the log_of_prime_sum...

If one runs this program in the terminal:

import math

prime = 3
log_of_prime_sum = math.log(2.0) #I'm starting out with 0.0 cause the sum of the log of the primes should begin here
n = 8

print("these are the primes smaller than {}".format(n))
print(2)

while prime < n:
    for x in range(2,int(math.sqrt(prime))+1): #range only works with integers right?
        if prime%x == 0.0:       
            break
    else:
        print(prime)
        log_of_prime_sum += math.log(prime)

    prime += 2

print("the natural logarithm of the product of all the primes smaller than {} is {}".format(n, log_of_prime_sum))
ratio = (n)/(log_of_prime_sum)
print("the ratio is {}".format(ratio))

The result is:

$ python3 primefilter.py 
these are the primes smaller than 8
2
3
5
7
the natural logarithm of the product of all the primes smaller than 8 is 5.3471075307174685
the ratio is 1.4961359864267718
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • I fixed this and made the prime checker faster, but I still end up with whole numbers when running this code :( like when I want the sum of the natural logarithms of primes under 8 I get 5 instead of 5.347.... also the ratio between and n that sum (so n/sum of log primes) is rounded down to 1 instead of1.4961... I've tried using float but it's no help :( – pokemonfan Feb 22 '15 at 23:42
  • @pokemonfan: are you sure this is not a number formatting error. I tested it in the terminal (see answer) and got the expected result... – Willem Van Onsem Feb 22 '15 at 23:58
  • uhm maybe this sounds dumb but what's a number formatting error? – pokemonfan Feb 23 '15 at 00:45
  • 1
    Well you use `%d` and as you can see in the [documentation](https://docs.python.org/2/library/stdtypes.html#string-formatting-operations) that means you print the number as an **integer**, by using `%f` you will print the **float** thus with decimal dot etc. – Willem Van Onsem Feb 23 '15 at 00:47