The homepage for Mathfun.py
This seems to be one of the many cases in which the admitted accuracy of mathematical processes is allowed to throw a wholly inadmissible appearance of authority over the results obtained by them. Mathematics may be compared to a mill of exquisite workmanship, which grinds your stuff of any degree of fineness; but, nevertheless, what you get out depends on what you put in; and as the grandest mill in the world will not extract wheat flour from peascods, so pages of formulae will not get a definite result out of loose data. - Huxley, Thomas Henry (1825-1895), Quarterly Journal of the Geological Society, 25,1869.
|Well, one's luck has to run out at some time. In previous versions of mathfun, there was a pretty nasty bug in .isprime that calculated certain numbers incorrectly. (The first four are 25, 35, 49 and 121...) It would return a false positive on these numbers, due to an idiot coding mistake of mine. I've corrected it (and fixed the previously outstanding bug along with it) and the function works properly this time, I promise. No other numbers or calculations were impacted, btw... [2000.8.11]|
Mathfun.py is a rather small Python library that contains some of the more obscure (others would say 'less useful' 8^) mathematical formula/functions that I have always found interesting/amusing. These include primality tests, fibonacci sequences and turning characters into numbers, among other things. The next paragraph includes a little story about my strange habits as a teenager. The paragraph after that contains some ramblings about primes and formulas. The paragraph after that hasn't been decided on yet, but you can be assured that it will be more stream-of- consciousness rambling about something mathematic by yours truly. If you're looking for information on the library itself, it can be found in the Documentation section.
One of the reasons that this library exists is that, as a junior programmer in high school, I spent an insane amount of time writing BASIC programs on our IIgs that would calculate the first 100 primes or some other such nonsense. I would write it one way, get out a stop watch, run it, record the time it took, rewrite it, rerun it, retime it and calculate the difference as percentage decrease in time. Repeat the previous until you get BASIC that looked like an explosion in a type factory. All in some sort of quest to... well, I don't really know what I was shooting for. I just enjoyed it. Calculating if a number was prime, calculating the prime factorization, calculating the first N prime numbers... Yeah, I was a strange one.
But, in retrospect, all that solitary math kinda helped. While I reinvented many a prime wheel, I did it on my own, which was something of a personal fulfillment once I had learned more of a history of mathematics. And I never forgot most of those formulas that I worked out on that Apple. For instance, mathfun.isprime(number) utilizes most of what I learned back in high school. It iterates through the odd numbers, up to the integer value of the square root of the number in question. I still remember the epiphany that I had that I only needed to calculate through the square root of the number. 8^)
There's a minor paradox with the calculation of a prime. The quickest way to generate primes would be to only attempt modular arithmetic with prime numbers. However, to do it that way means that you have to generate a list of prime numbers first, which involves a primality test on every odd number up to the square root of the number in question. This would be sloooooow for the primality test for any single number. (For instance, isprime(10000) would involved roughly 50 full primality tests to generate the list needed to be a maximally efficient test on it.) So, we accept that even if we're not going to get any results doing (N mod 9), it's much quicker to eat those wasted cycles than to determine if 9 is prime first. However, if you're doing nothing more than simply cranking out prime after prime, it becomes much more efficient to only do the primality test with a list of primes, since (if you start from 2) you've already determined the ealier ones before. (There's probably a break-even time first (machine dependent) before "determine all primes with primes" becomes more efficient than "crank through the odd numbers".) It's easy to see however, that for very large numbers it's much better to only work with primes.
There's also a minor question of the speed of the data structures used to store the prime list versus the very fast next odd number test. However, I'll leave that one up to the True Computer Scientists.
This section contains a (sometimes) short description of each function, it's parameters and what it returns.
isprime(a_number) - The function that started it all. This function returns a 1 if the given number is prime and 0 if it isn't. (For a quick discussion about the formula used to determine primality, see the introduction.
nextprime(a_number) - Given an integer, it returns the first prime after it.
prevprime(a_number) - Given an integer, it returns the first prime number that precedes it. I have no idea what happens if you give it something like 1. 8^) Just don't.
primerange(bot_num, top_num, max_ret=0) - This function returns a list containing all the prime numbers between bot_num and top_num including bot_num and top_num if they are prime. If max_ret is specified, then the list will contain a maximum of max_ret elements.
fibseq(bunny_one, bunny_two=0, count=0) - This function returns a list of numbers that constitute a Fibonacci sequence starting with bunny_one and bunny_one, unless bunny_two is specified in which case bunny_two is used. If count is given, then the list contains count number of elements. If count is not given, then the list returns 10, the first two elements and the next 8 in the sequence. Look out, a Fibonacci sequence can get very big very fast, so don't start it with too large of numbers or too big of a count or you could get an error.
primefactors(a_number) - Given an integer, this function return a list containing all the prime factors for that number.
numsum(a_number, down_to_one_digit=1) - Given an integer, this function sums the individual digits together to form a new number. If the result has more than one digit, then the process is repeated until a single digit number is obtained. This recursion can be turned off by sending down_to_one_digit a False (0). Then the function will return the first result obtained, single digit or not.
alphasum(a_string) - This function returns an integer that is the result of converting all the alphabet character in a_string to their 'location' value (a=1, b=2 and so on) and then adding the numbers up. Case doesn't matter, whitespace and non-alphabet characters (numbers, punctuation, ...) are ignored.
asciisum(a_string) - Given a string, it converts the characters to their ASCII table value and then sums and returns the results. Case matters, whitespace is ignored (But non-alphabetical characters aren't!). This function is possibly the least useful one that I have ever written.
Mathfun is available from several locations...
Mathfun.py is licensed under the LGPL. If you don't know what that means, please follow the link!