Seite 1 von 1

Primzahlen - zum widerholten mal

Verfasst: Mittwoch 2. März 2005, 21:00
von Leonidas
Hallo!
Auf mehrfachen Request jetzt nochmal ein Primzahlen Benchmark.

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*- 
import sys, time

__version__ = "0.1.0"
args = """bench.py (%s) - Small benchmark with primes (Free Software - GPLed)
Commandline arguments:
bench.py [-n<number>|-t<number>|-u<number>|-i<number>] [-b|--benchmark]
  -n<number> : get next prime which is bigger than <number>
  -t<number> : find <number> primes
  -u<number> : find primes until <number>
  -i<number> : check whether <number> is a prime
  -b --benchmark : benchmark results"""

def checkPrime(number):
    """This is the core def, it checks whether
    the number is a prime or not."""
    prime_found = False
    # Some hacks, to return right values
    if number == 0:
        return False
    if number == 2:
        return True
    if number < 0:
        # If number is smaller than zero so use absolute value
        number = abs(number)
    for dividor in xrange(2, number):
        if number % dividor is 0:
            #print "No Prime: %d" % lastprime
            prime_found = False
            return False
        else:
            prime_found = True
    if prime_found is True:
        #print "Prime: %d" % lastprime
        return True
        
def nextPrime(prime_to_test):
    """Returns the next prime"""
    while True:
        prime_to_test = prime_to_test + 1
        #print "ptt==%d" % prime_to_test
        if checkPrime(prime_to_test):
            # Found prime
            #print "Prime==%d" % prime_to_test
            return prime_to_test
            #break
            
def findNumberOfPrimes(primes_to_find):
    """Returns a list of primes
    You have to wait long time without output
    cause it produces no output to stdout
    ToDo: make a starting value"""
    primes_found = 0
    lastnumber = 2
    primes_list = []
    while True:
        if checkPrime(lastnumber):
            primes_list.append(lastnumber)
            primes_found = primes_found + 1
        if primes_found == primes_to_find:
            return primes_list
        lastnumber = lastnumber + 1

def findPrimesUntil(until_number):
    """Finds primes until number N is reached"""
    primes_list = []
    for number in xrange(2, until_number):
        if checkPrime(number):
            primes_list.append(number)
    return primes_list

def main():
    """The main def, which makes this script executable
    PyLint: this def has to many branches, but what to do?"""
    benchmark = False
    if len(sys.argv) == 1: 
        # if no arguments display help
        print args % __version__
        # and exit
        sys.exit(1)
    elif len(sys.argv) == 3:
        # benchmarking on?
        if sys.argv[2][:2] == "-b" or sys.argv[2][:11] == "--benchmark":
            print "Benchmark enabled"
            benchmark = True
        else:
            print "There is no such commandline argument!"
    if sys.argv[1][:2] == "-n":
        # Simply get the next prime
        if benchmark:
            print "There is too less to benchmark"
        prime_to_test = int(sys.argv[1][2:])
        prime_found = nextPrime(prime_to_test)
        print "Prime==%d" % prime_found
    elif sys.argv[1][:2] == "-t":
        until_prime = int(sys.argv[1][2:])
        if benchmark: 
            startTime = time.time()
        primes = findNumberOfPrimes(until_prime)
        if benchmark:
            stopTime = time.time()
            taken = stopTime - startTime
        for prime in primes:
            print "Prime==%d" % prime
        if benchmark: 
            print "Seconds==%G" % taken

    elif sys.argv[1][:2] == "-u":
        until_number = int(sys.argv[1][2:])
        if benchmark: 
            startTime = time.time()
        primes = findPrimesUntil(until_number)
        if benchmark:
            stopTime = time.time()
            taken = stopTime - startTime
        for prime in primes:
            print "Prime==%d" % prime
        if benchmark: 
            print "Seconds==%G" % taken
            
    elif sys.argv[1][:2] == "-i":
        prime_to_check = int(sys.argv[1][2:])
        if benchmark:
            print "There is too less to benchmark"
        result = checkPrime(prime_to_check)
        if result == True:
            print "Prime==True"
        else:
            print "Prime==False"
        
def longxrange(start,stop=None,step=1):
    """myxrange([start=0],stop,[step=1]) --> iterator object like xrange for longs
    coded by Milan:
    http://python.sandtner.org/viewtopic.php?t=1366"""
    if stop == None:
        stop = start
        start = 0
    if step > 0:
        while start < stop:
            yield start
            start += step
    elif step < 0:
        while start > stop:
            yield start
            start += step
    else:
        raise ValueError, "step must be != 0"
            
if __name__ == '__main__':
    main()
Ich werde das Ding noch umbauen wenn ich Zeit finde, dass es optparse, timeit und Generatoren nutzt.

Für Optimierungsvorschläge bin ich offen.

Re: Primzahlen - zum widerholten mal

Verfasst: Donnerstag 3. März 2005, 07:06
von jens
Leonidas hat geschrieben:Ich werde das Ding noch umbauen wenn ich Zeit finde, dass es optparse, timeit und Generatoren nutzt.
Benutze doch besser keine Optionen, sodas ein direker Aufruf alle Varianten durchgeht... So kann man es einfacher Ausprobieren, oder?

Verfasst: Donnerstag 3. März 2005, 13:38
von Leonidas
Ja, ich könnte Defaultwerte setzen, das wäre eine Idee. Seit Python 2.3 gehört ja optparse zum Glück zum Standardumfang :)

Verfasst: Donnerstag 3. März 2005, 14:37
von Milan
HI. Wo ich den Code sehe, erinnere ich mich gleich wieder an etwas was ich noch machen wollte :wink: , nämlich longxrange verschnellern... wird wohl aber nix werden, da keine Zeit dafür ist. Ich wollte aber nur mal schnell drauf hinweisen, dass der Generator gar nicht benutzt wird. Wenn du ihn aus dem Quelltext rausnimmst gehts noch schneller (kleinerer Namesraum der durchsucht werden muss).

Verfasst: Donnerstag 3. März 2005, 15:12
von Leonidas
Ich weiß, aber ich wollte mal dein xlrange nutzen... nur ist mir inzwischen entfallen wozu :) Vielleicht fällt es mir ja irgendwann wieder ein. Derweil habe ich mal auf optparse portiert, so sieht das ganze natürlich gleich besser aus.

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*- 
"""Prime benchmark - and small library
You can use it in your own programs
"""

import sys, time, optparse

__version__ = "0.1.1"

def checkPrime(number):
    """This is the core def, it checks whether
    the number is a prime or not."""
    prime_found = False
    # Some hacks, to return right values
    if number == 0:
        return False
    if number == 2:
        return True
    if number < 0:
        # If number is smaller than zero so use absolute value
        number = abs(number)
    for dividor in xrange(2, number):
        if number % dividor == 0:
            #print "No Prime: %d" % lastprime
            prime_found = False
            return False
        else:
            prime_found = True
    if prime_found is True:
        #print "Prime: %d" % lastprime
        return True
        
def nextPrime(prime_to_test):
    """Returns the next prime"""
    while True:
        prime_to_test += 1
        #print "ptt==%d" % prime_to_test
        if checkPrime(prime_to_test):
            # Found prime
            #print "Prime==%d" % prime_to_test
            return prime_to_test
            #break
            
def findNumberOfPrimes(primes_to_find):
    """Returns a list of primes
    You have to wait long time without output
    cause it produces no output to stdout
    ToDo: make a starting value"""
    primes_found = 0
    lastnumber = 2
    primes_list = []
    while True:
        if checkPrime(lastnumber):
            primes_list.append(lastnumber)
            primes_found = primes_found + 1
        if primes_found == primes_to_find:
            return primes_list
        lastnumber = lastnumber + 1

def findPrimesUntil(until_number):
    """Finds primes until number N is reached"""
    primes_list = []
    for number in xrange(2, until_number):
        if checkPrime(number):
            primes_list.append(number)
    return primes_list

def main():
    """The main def, which makes this script executable"""
    parser = optparse.OptionParser()
    
    parser.add_option("-v", "--version", dest="version", default=False,
        action="store_true", help="print program versions and exit")
    parser.add_option("-b", "--benchmark", dest="benchmark", default=False,
        action="store_true", help="benchmark results")
    parser.add_option("-n", "--next", dest="next", default=False, metavar="NUMBER",
        action="store", help="get next prime which is bigger than NUMBER")
    parser.add_option("-t", "--times", dest="times", default=False, metavar="NUMBER",
        action="store", help="find NUMBER primes")
    parser.add_option("-u", "--until", dest="until", default=False, metavar="NUMBER",
        action="store", help="find primes until NUMBER")
    parser.add_option("-c", "--check", dest="check", default=False, metavar="NUMBER",
        action="store", help="check whether NUMBER is a prime")
    
    (options, args) = parser.parse_args()
    
    if options.version:
        print 'primebench.py (%s) - Small benchmark with primes (Free Software - GPLed)' % __version__
        sys.exit(0)
        
    if options.benchmark:
        print 'Benchmark enabled'
        
    if options.next:
        if options.benchmark:
            print "There is too less to benchmark"
        prime_found = nextPrime(int(options.next))
        print "Prime==%d" % prime_found
        sys.exit(0)
    
    if options.times:
        if options.benchmark: 
            startTime = time.time()
        primes = findNumberOfPrimes(int(options.times))
        if options.benchmark:
            stopTime = time.time()
            taken = stopTime - startTime
        for prime in primes:
            print "Prime==%d" % prime
        if options.benchmark: 
            print "Seconds==%G" % taken
    
    if options.until:
        if options.benchmark: 
            startTime = time.time()
        primes = findPrimesUntil(int(options.until))
        if options.benchmark:
            stopTime = time.time()
            taken = stopTime - startTime
        for prime in primes:
            print "Prime==%d" % prime
        if options.benchmark: 
            print "Seconds==%G" % taken
    
    if options.check:
        if options.benchmark:
            print "There is too less to benchmark"
        result = checkPrime(int(options.check))
        if result == True:
            print "Prime==True"
        else:
            print "Prime==False"
            
if __name__ == '__main__':
    main()

Verfasst: Freitag 4. März 2005, 01:57
von BlackJack
Leonidas hat geschrieben:Ich weiß, aber ich wollte mal dein xlrange nutzen... nur ist mir inzwischen entfallen wozu :)

Code: Alles auswählen

In [27]: xrange(2**31)
---------------------------------------------------------------------------
exceptions.OverflowError                  Traceback (most recent call last)

/home/bj/<console>

OverflowError: long int too large to convert to int
Vielleicht deswegen?

Verfasst: Freitag 4. März 2005, 13:31
von Leonidas
BlackJack hat geschrieben:

Code: Alles auswählen

In [27]: xrange(2**31)
---------------------------------------------------------------------------
exceptions.OverflowError                  Traceback (most recent call last)

/home/bj/<console>

OverflowError: long int too large to convert to int
Vielleicht deswegen?
Bingo!

Die neueste Version gibt es im Repository, allerdings ist Milans xlrange noch nicht verbaut.