Question

I've been learning Python 2.5.4 and I have the following problem to solve:

"Write a program that computes the sum of the logarithms of all the primes from 2 to some number n, and print out the sum of the logs of the primes, the number n, and the ratio of these two quantities. Test this for different values of n."

This is what I have so far:

from math import *
n = raw_input('This is a logarithm ratio tester. Which number do you want to test? ')
for x in range(2,n):                            #picks numbers to test
    for divisor in range(2, 1+int(sqrt(x+1))):
        if x%divisor == 0:                      #checks if x is prime
            log(x)                              #computes log of prime

Unfortunately I'm not sure how to implement a function for summing all the logs. I would imagine that once I have that, I just need to conclude the program with:

print 'Sum of the logs of the primes is',logsum
print 'n =',n
print 'Ratio of sum to n is',logsum/n

Or some variant. But what would be a good way to obtain what I've labeled logsum? Please note I have been studying programming for no more than a week, I know very few statements/functions by heart, and I am not a mathematician. When in doubt, assume I'm an idiot. Thanks!

Was it helpful?

Solution 2

You should check to see if the number is prime before calculating its log and then add the value of log(x) to a variable logsum like this:

from math import *
logsum = 0
n = raw_input('This is a logarithm ratio tester. Which number do you want to test? ')
for x in range(2,n):                            #picks numbers to test
    isprime = True
    for divisor in range(2, 1+int(sqrt(x+1))):
        if x%divisor == 0:                      #checks if x is prime
            isprime = False                                  #computes log of prime
            break
    if isprime:
        logsum += log(x)

Also, since you're checking a lot of values, maybe implementing The Sieve of Eratosthenes would be a nice way to continue learning.

EDIT: Using Juri Robl's suggestion, the code could be simplified to:

from math import *
logsum = 0
n = raw_input('This is a logarithm ratio tester. Which number do you want to test? ')
for x in range(2,n):                            #picks numbers to test
    for divisor in range(2, 1+int(sqrt(x+1))):
        if x%divisor == 0:                      #checks if x is prime
            break
    else:
        logsum += log(x)

OTHER TIPS

I would wrap some of your code in functions, and fix your definition of prime:

def isprime(x):
  for j in range(2,1 + int(sqrt(x - 1))):
    if x%j == 0:
      return False
  return True

def primes(n):
    return [j for j in range(2, n) if isprime(n)]

logsum = 0
for p in primes(n):
    logsum += log(p)

Notice that log(2) + log(3) + ... + log(n) = log(2*3*...*n)

You could then just use the Sieve of Eratosthenes to obtain a list of primes, multiply them together, and then take the logarithm of that product.

import math
import operator

def filter_primes(alist, newlist):
    for x in alist[1:]:
        if x%alist[0] != 0:
            newlist.append(x)
    return newlist

n = int(raw_input('This is a logarithm ratio tester. Which number do you want to test?'))
alist = range(2, n)
sieve_list = []
primes = [2]

while alist[0] < math.sqrt(n):
    a = filter_primes(alist, sieve_list)
    primes.append(a[0])
    alist = sieve_list
    sieve_list = []
for j in alist[1:]: primes.append(j)

product = reduce(lambda x, y: x*y, primes)
ans = math.log(product)

print 'The sum of the logs is: %d \nn is: %d \nThe ratio of these two quantities is: %s' %   (ans, n, float(ans/n))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top