|
Python/FAQ/Числа
Материал из Wiki.crossplatform.ru
[править] Checking Whether a String Is a Valid Number
#-----------------------------
# The standard way of validating numbers is to convert them and catch
# an exception on failure
try:
myfloat = float(mystr)
print "is a decimal number"
except TypeError:
print "is not a decimal number"
try:
myint = int(mystr)
print "is an integer"
except TypeError:
print "is not an integer"
# DON'T DO THIS. Explicit checking is prone to errors:
if mystr.isdigit(): # Fails on "+4"
print 'is a positive integer'
else:
print 'is not'
if re.match("[+-]?\d+$", mystr): # Fails on "- 1"
print 'is an integer'
else:
print 'is not'
if re.match("-?(?:\d+(?:\.\d*)?|\.\d+)$", mystr): # Opaque, and fails on "- 1"
print 'is a decimal number'
else:
print 'is not'
#-----------------------------
[править] Comparing Floating-Point Numbers
#-----------------------------
# equal(num1, num2, accuracy) : returns true if num1 and num2 are
# equal to accuracy number of decimal places
def equal(num1, num2, accuracy):
return abs(num1 - num2) < 10**(-accuracy)
#-----------------------------
from __future__ import division # use / for float div and // for int div
wage = 536 # $5.36/hour
week = 40 * wage # $214.40
print "One week's wage is: $%.2f" % (week/100)
#=> One week's wage is: $214.40
#-----------------------------
[править] Rounding Floating-Point Numbers
#-----------------------------
rounded = round(num) # rounds to integer
#-----------------------------
a = 0.255
b = "%.2f" % a
print "Unrounded: %f\nRounded: %s" % (a, b)
print "Unrounded: %f\nRounded: %.2f" % (a, a)
#=> Unrounded: 0.255000
#=> Rounded: 0.26
#=> Unrounded: 0.255000
#=> Rounded: 0.26
#-----------------------------
from math import floor, ceil
print "number\tint\tfloor\tceil"
a = [3.3, 3.5, 3.7, -3.3]
for n in a:
print "% .1f\t% .1f\t% .1f\t% .1f" % (n, int(n), floor(n), ceil(n))
#=> number int floor ceil
#=> 3.3 3.0 3.0 4.0
#=> 3.5 3.0 3.0 4.0
#=> 3.7 3.0 3.0 4.0
#=> -3.3 -3.0 -4.0 -3.0
#-----------------------------
[править] Converting Between Binary and Decimal
#-----------------------------
# To convert a string in any base up to base 36, use the optional arg to int():
num = int('0110110', 2) # num is 54
# To convert an int to an string representation in another base, you could use
# <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/111286>:
import baseconvert
def dec2bin(i):
return baseconvert.baseconvert(i, baseconvert.BASE10, baseconvert.BASE2)
binstr = dec2bin(54) # binstr is 110110
#-----------------------------
[править] Operating on a Series of Integers
#-----------------------------
for i in range(x,y):
pass # i is set to every integer from x to y, excluding y
for i in range(x, y, 7):
pass # i is set to every integer from x to y, stepsize = 7
print "Infancy is:",
for i in range(0,3):
print i,
print
print "Toddling is:",
for i in range(3,5):
print i,
print
# DON'T DO THIS:
print "Childhood is:",
i = 5
while i <= 12:
print i
i += 1
#=> Infancy is: 0 1 2
#=> Toddling is: 3 4
#=> Childhood is: 5 6 7 8 9 10 11 12
#-----------------------------
[править] Working with Roman Numerals
#-----------------------------
# See http://www.faqts.com/knowledge_base/view.phtml/aid/4442
# for a module that does this
#-----------------------------
[править] Generating Random Numbers
#-----------------------------
import random # use help(random) to see the (large) list of funcs
rand = random.randint(x, y)
#-----------------------------
rand = random.randint(25, 76)
print rand
#-----------------------------
elt = random.choice(mylist)
#-----------------------------
import string
chars = string.letters + string.digits + "!@$%^&*"
password = "".join([random.choice(chars) for i in range(8)])
#-----------------------------
[править] Generating Different Random Numbers
#-----------------------------
# Changes the default RNG
random.seed()
# Or you can create independent RNGs
gen1 = random.Random(6)
gen2 = random.Random(6)
gen3 = random.Random(10)
a1, b1 = gen1.random(), gen1.random()
a2, b2 = gen2.random(), gen2.random()
a3, b3 = gen3.random(), gen3.random()
# a1 == a2 and b1 == b2
#-----------------------------
[править] Making Numbers Even More Random
#-----------------------------
# see http://www.sbc.su.se/~per/crng/ or http://www.frohne.westhost.com/rv11reference.htm
#-----------------------------
[править] Generating Biased Random Numbers
#-----------------------------
import random
mean = 25
sdev = 2
salary = random.gauss(mean, sdev)
print "You have been hired at %.2f" % salary
#-----------------------------
[править] Doing Trigonometry in Degrees, not Radians
#-----------------------------
radians = math.radians(degrees)
degrees = math.degrees(radians)
# pre-2.3:
from __future__ import division
import math
def deg2rad(degrees):
return (degrees / 180) * math.pi
def rad2deg(radians):
return (radians / math.pi) * 180
#-----------------------------
# Use deg2rad instead of math.radians if you have pre-2.3 Python.
import math
def degree_sine(degrees):
radians = math.radians(degrees)
return math.sin(radians)
#-----------------------------
[править] Calculating More Trigonometric Functions
#-----------------------------
import math
# DON'T DO THIS. Use math.tan() instead.
def tan(theta):
return math.sin(theta) / math.cos(theta)
#----------------
# NOTE: this sets y to 16331239353195370.0
try:
y = math.tan(math.pi/2)
except ValueError:
y = None
#-----------------------------
[править] Taking Logarithms
#-----------------------------
import math
log_e = math.log(VALUE)
#-----------------------------
log_10 = math.log10(VALUE)
#-----------------------------
def log_base(base, value):
return math.log(value) / math.log(base)
#-----------------------------
# log_base defined as above
answer = log_base(10, 10000)
print "log10(10,000) =", answer
#=> log10(10,000) = 4.0
#-----------------------------
[править] Multiplying Matrices
#-----------------------------
# NOTE: must have NumPy installed. See
# http://www.pfdubois.com/numpy/
import Numeric
a = Numeric.array( ((3, 2, 3),
(5, 9, 8) ), "d")
b = Numeric.array( ((4, 7),
(9, 3),
(8, 1) ), "d")
c = Numeric.matrixmultiply(a, b)
print c
#=> [[ 54. 30.]
#=> [ 165. 70.]]
print a.shape, b.shape, c.shape
#=> (2, 3) (3, 2) (2, 2)
#-----------------------------
[править] Using Complex Numbers
#-----------------------------
a = 3+5j
b = 2-2j
c = a * b
print "c =", c
#=> c = (16+4j)
print c.real, c.imag, c.conjugate()
#=> 16.0 4.0 (16-4j)
#-----------------------------
import cmath
print cmath.sqrt(3+4j)
#=> (2+1j)
#-----------------------------
[править] Converting Between Octal and Hexadecimal
#-----------------------------
number = int(hexadecimal, 16)
number = int(octal, 8)
s = hex(number)
s = oct(number)
num = raw_input("Gimme a number in decimal, octal, or hex: ").rstrip()
if num.startswith("0x"):
num = int(num[2:], 16)
elif num.startswith("0"):
num = int(num[1:], 8)
else:
num = int(num)
print "%(num)d %(num)x %(num)o\n" % { "num": num }
#-----------------------------
[править] Putting Commas in Numbers
#-----------------------------
def commify(amount):
amount = str(amount)
firstcomma = len(amount)%3 or 3 # set to 3 if would make a leading comma
first, rest = amount[:firstcomma], amount[firstcomma:]
segments = [first] + [rest[i:i+3] for i in range(0, len(rest), 3)]
return ",".join(segments)
print commify(12345678)
#=> 12,345,678
# DON'T DO THIS. It works on 2.3+ only and is slower and less straightforward
# than the non-regex version above.
import re
def commify(amount):
amount = str(amount)
amount = amount[::-1]
amount = re.sub(r"(\d\d\d)(?=\d)(?!\d*\.)", r"\1,", amount)
return amount[::-1]
[править] Printing Correct Plurals
# Printing Correct Plurals
#-----------------------------
def pluralise(value, root, singular="", plural="s"):
if value == 1:
return root + singular
else:
return root + plural
print "It took", duration, pluralise(duration, 'hour')
print "%d %s %s enough." % (duration,
pluralise(duration, 'hour'),
pluralise(duration, '', 'is', 'are'))
#-----------------------------
import re
def noun_plural(word):
endings = [("ss", "sses"),
("([psc]h)", r"\1es"),
("z", "zes"),
("ff", "ffs"),
("f", "ves"),
("ey", "eys"),
("y", "ies"),
("ix", "ices"),
("([sx])", r"\1es"),
("", "s")]
for singular, plural in endings:
ret, found = re.subn("%s$"%singular, plural, word)
if found:
return ret
verb_singular = noun_plural; # make function alias
#-----------------------------
[править] Program: Calculating Prime Factors
# Program: Calculating Prime Factors
#-----------------------------
#% bigfact 8 9 96 2178
#8 2**3
#
#9 3**2
#
#96 2**5 3
#
#2178 2 3**2 11**2
#-----------------------------
#% bigfact 239322000000000000000000
#239322000000000000000000 2**19 3 5**18 39887
#
#
#% bigfact 25000000000000000000000000
#25000000000000000000000000 2**24 5**26
#-----------------------------
import sys
def factorise(num):
factors = {}
orig = num
print num, '\t',
# we take advantage of the fact that (i +1)**2 = i**2 + 2*i +1
i, sqi = 2, 4
while sqi <= num:
while not num%i:
num /= i
factors[i] = factors.get(i, 0) + 1
sqi += 2*i + 1
i += 1
if num != 1 and num != orig:
factors[num] = factors.get(num, 0) + 1
if not factors:
print "PRIME"
for factor in sorted(factors):
if factor:
tmp = str(factor)
if factors[factor]>1: tmp += "**" + str(factors[factor])
print tmp,
print
#--------
if __name__ == '__main__':
if len(sys.argv) == 1:
print "Usage:", sys.argv[0], " number [number, ]"
else:
for strnum in sys.argv[1:]:
try:
num = int(strnum)
factorise(num)
except ValueError:
print strnum, "is not an integer"
#-----------------------------
# A more Pythonic variant (which separates calculation from printing):
def format_factor(base, exponent):
if exponent > 1:
return "%s**%s"%(base, exponent)
return str(base)
def factorise(num):
factors = {}
orig = num
# we take advantage of the fact that (i+1)**2 = i**2 + 2*i +1
i, sqi = 2, 4
while sqi <= num:
while not num%i:
num /= i
factors[i] = factors.get(i, 0) + 1
sqi += 2*i + 1
i += 1
if num not in (1, orig):
factors[num] = factors.get(num, 0) + 1
if not factors:
return ["PRIME"]
out = [format_factor(base, exponent)
for base, exponent in sorted(factors.items())]
return out
def print_factors(value):
try:
num = int(value)
if num != float(value):
raise ValueError
except (ValueError, TypeError):
raise ValueError("Can only factorise an integer")
factors = factorise(num)
print num, "\t", " ".join(factors)
|