Last active
September 30, 2015 23:08
-
-
Save pedramamini/1877355 to your computer and use it in GitHub Desktop.
Collection of type conversion, output formatting, and other miscellaneous Python utilities I've written and used across a variety of projects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
######################################################################################################################## | |
def blend_colors (first, second, scale=.5): | |
''' | |
Takes 2 RGB color hex values and blend them together. | |
''' | |
rold = (first & 0xFF0000) >> 16 | |
gold = (first & 0x00FF00) >> 8 | |
bold = (first & 0x0000FF) | |
rnew = (second & 0xFF0000) >> 16 | |
gnew = (second & 0x00FF00) >> 8 | |
bnew = (second & 0x0000FF) | |
r = int((rold + (rnew - rold) * scale)) & 0xFF | |
g = int((gold + (gnew - gold) * scale)) & 0xFF | |
b = int((bold + (bnew - bold) * scale)) & 0xFF | |
return (r << 16) + (g << 8) + b | |
######################################################################################################################## | |
def calc_entropy (data): | |
''' | |
Calculate the entropy of supplied data. | |
''' | |
if not data: | |
return 0 | |
entropy = 0 | |
for x in range(256): | |
p_x = float(data.count(chr(x))) / len(data) | |
if p_x > 0: | |
entropy += -p_x * math.log(p_x, 2) | |
return entropy | |
######################################################################################################################## | |
def commify (n): | |
''' | |
Format a large integer with human readable commas. | |
''' | |
if n is not str: | |
n = str(n) | |
while True: | |
(n, count) = re.subn(r'^([-+]?\d+)(\d{3})', r'\1,\2', n) | |
if count == 0: | |
break | |
return n | |
######################################################################################################################## | |
def condence_spaces (n): | |
''' | |
Condense multiple spaces to one. | |
''' | |
return " ".join(str.split(str(s))) | |
######################################################################################################################## | |
def day_suffix (day): | |
''' | |
Return the numeric day with the appropriate suffix: st, nd, rd, th. | |
''' | |
day = int(day) | |
if 4 <= day <= 20 or 24 <= day <= 30: | |
suffix = "th" | |
else: | |
suffix = ["st", "nd", "rd"][day % 10 - 1] | |
return "%d%s" % (day, suffix) | |
######################################################################################################################## | |
def deg_to_dec (degrees, heading): | |
''' | |
Convert from degrees/minutes to decimal degrees. | |
''' | |
deg = math.floor(float(degrees) / 100.0) | |
frac = (float(degrees) / 100.0 - deg) / 0.6 | |
ret = deg + frac | |
if heading == "S" or heading == "W": | |
ret = -ret | |
return ret | |
######################################################################################################################## | |
def fit_curved (window_min, window_max, num_events): | |
''' | |
''' | |
y1 = float(0) # volume min | |
y2 = float(255) # volum nax | |
x1 = float(window_min) # min number of events over window | |
x2 = float(window_max) # max number of events over window | |
x = float(num_events) # current number of events to fit to volume | |
n = 2 # rate of curvature | |
y = 0 # volume, what we are solving for | |
y = ((y2 - y1) / (x2**n - x1**n)) + y1 - (((y2 - y1) * x1**n) / (x2**n - x1**n)) | |
return y | |
######################################################################################################################## | |
def fit_linear (window_min, window_max, num_events): | |
''' | |
''' | |
y1 = float(0) # volume min | |
y2 = float(255) # volum nax | |
x1 = float(window_min) # min number of events over window | |
x2 = float(window_max) # max number of events over window | |
x = float(num_events) # current number of events to fit to volume | |
y = 0 # volume, what we are solving for | |
y = ((y2 - y1) / (x2 - x1)) * (x - x1) + y1 | |
return y | |
######################################################################################################################## | |
def fit_mixed (window_min, window_max, num_events): | |
''' | |
''' | |
a = .6 # weight to apply to linear fit | |
b = .4 # weight to apply to curved fit | |
linear = linear_fit(window_min, window_max, num_events) | |
curved = curved_fit(window_min, window_max, num_events) | |
return a * linear + b * curved | |
######################################################################################################################## | |
def flip_hex_string_endian (s): | |
''' | |
Given a hex string such as "0000000000007000" will convert to "0070000000000000". | |
''' | |
# some python magic here makes "0000000000007000" -> [('0', '0'), ..., ('7', '0'), ('0', '0')] | |
s = zip(*[iter(s)] * 2) | |
# now we make flip it and turn it back into a string -> "0070000000000000". | |
return "".join([a + b for a, b in reversed(s)]) | |
######################################################################################################################## | |
def guid_parse (guid): | |
''' | |
Convert the binary representation of a GUID to a human readable string. | |
''' | |
(block1, block2, block3) = struct.unpack("<LHH", guid[:8]) | |
(block4, block5, block6) = struct.unpack(">HHL", guid[8:16]) | |
return "{%08X-%04X-%04X-%04X-%04X%08X}" % (block1, block2, block3, block4, block5, block6) | |
######################################################################################################################## | |
def hex_dump (data, addr=0): | |
''' | |
Dump data in hex format. | |
''' | |
dump = slice = "" | |
for byte in data: | |
if addr % 16 == 0: | |
dump += " " | |
for char in slice: | |
if ord(char) >= 32 and ord(char) <= 126: | |
dump += char | |
else: | |
dump += "." | |
dump += "\n%04x: " % addr | |
slice = "" | |
dump += "%02x " % ord(byte) | |
slice += byte | |
addr += 1 | |
remainder = addr % 16 | |
if remainder != 0: | |
dump += " " * (16 - remainder) + " " | |
for char in slice: | |
if ord(char) >= 32 and ord(char) <= 126: | |
dump += char | |
else: | |
dump += "." | |
return dump + "\n" | |
######################################################################################################################## | |
def knots_to_miles (knots): | |
''' | |
Convert from knots to miles. | |
''' | |
return float(knots) * 1.15077945 | |
######################################################################################################################## | |
def levenshtein_distance (first, second): | |
''' | |
Calculate the Levenshtein distance between two strings. ie: The number of transformations required to transform one | |
string to the other. | |
''' | |
if len(first) > len(second): | |
first, second = second, first | |
if len(second) == 0: | |
return len(first) | |
first_length = len(first) + 1 | |
second_length = len(second) + 1 | |
distance_matrix = [range(second_length) for x in range(first_length)] | |
for i in range(1, first_length): | |
for j in range(1, second_length): | |
deletion = distance_matrix[i-1][j] + 1 | |
insertion = distance_matrix[i][j-1] + 1 | |
substitution = distance_matrix[i-1][j-1] | |
if first[i-1] != second[j-1]: | |
substitution += 1 | |
distance_matrix[i][j] = min(insertion, deletion, substitution) | |
return distance_matrix[first_length-1][second_length-1] | |
######################################################################################################################## | |
def pattern_make (length): | |
''' | |
Make an identifiable pattern of the specified length. | |
''' | |
pattern = "" | |
for x in xrange(ord("A"), ord("Z") + 1): | |
for y in xrange(ord("a"), ord("z") + 1): | |
for z in xrange(ord("0"), ord("9") + 1): | |
pattern += chr(x) + chr(y) + chr(z) | |
if len(pattern) > length: | |
return pattern[:length] | |
######################################################################################################################## | |
def pattern_offset (length, key): | |
''' | |
Find the offset of the key in the specified length pattern. | |
''' | |
pattern = make_pattern(length) | |
return pattern.index(key) | |
######################################################################################################################## | |
def to_decimal (self, binary): | |
''' | |
Convert a binary string to decimal number. | |
''' | |
return int(binary, 2) | |
######################################################################################################################## | |
def to_binary (number, bit_count=32): | |
''' | |
Converts a decimal numer to binary string. | |
''' | |
return "".join(map(lambda x:str((number >> x) & 1), range(bit_count -1, -1, -1))) | |
######################################################################################################################## | |
def wrap_at (s, col=40, sep="\n"): | |
''' | |
Wrap a string at the specified column seperating with the specified separator. | |
''' | |
wrapped = "" | |
while s: | |
if wrapped: | |
wrapped += sep | |
wrapped += s[:col] | |
s = s[col:] | |
return wrapped | |
######################################################################################################################## | |
def byte (b): return (b & 0xff) | |
def word (w): return (w & 0xffff) | |
def dword (d): return (d & 0xffffffff) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment