[go: up one dir, main page]

Menu

[r1450]: / mcomix / tools.py  Maximize  Restore  History

Download this file

149 lines (114 with data), 4.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"""tools.py - Contains various helper functions."""
import os
import sys
import re
import gc
import bisect
import operator
import math
NUMERIC_REGEXP = re.compile(r"\d+|\D+") # Split into numerics and characters
def alphanumeric_sort(filenames):
"""Do an in-place alphanumeric sort of the strings in <filenames>,
such that for an example "1.jpg", "2.jpg", "10.jpg" is a sorted
ordering.
"""
def _format_substring(s):
if s.isdigit():
return int(s)
return s.lower()
filenames.sort(key=lambda s: map(_format_substring, NUMERIC_REGEXP.findall(s)))
def alphanumeric_compare(s1, s2):
""" Compares two strings by their natural order (i.e. 1 before 10)
and returns a result comparable to the cmp function.
@return: 0 if identical, -1 if s1 < s2, +1 if s1 > s2. """
if s1 is None:
return 1
elif s2 is None:
return -1
stringparts1 = NUMERIC_REGEXP.findall(s1.lower())
stringparts2 = NUMERIC_REGEXP.findall(s2.lower())
for i, part in enumerate(stringparts1):
if part.isdigit():
stringparts1[i] = int(part)
for i, part in enumerate(stringparts2):
if part.isdigit():
stringparts2[i] = int(part)
return cmp(stringparts1, stringparts2)
def bin_search(lst, value):
""" Binary search for sorted list C{lst}, looking for C{value}.
@return: List index on success. On failure, it returns the 1's
complement of the index where C{value} would be inserted.
This implies that the return value is non-negative if and only if
C{value} is contained in C{lst}. """
index = bisect.bisect_left(lst, value)
if index != len(lst) and lst[index] == value:
return index
else:
return ~index
def get_home_directory():
"""On UNIX-like systems, this method will return the path of the home
directory, e.g. /home/username. On Windows, it will return an MComix
sub-directory of <Documents and Settings/Username>.
"""
if sys.platform == 'win32':
return os.path.join(os.path.expanduser('~'), 'MComix')
else:
return os.path.expanduser('~')
def get_config_directory():
"""Return the path to the MComix config directory. On UNIX, this will
be $XDG_CONFIG_HOME/mcomix, on Windows it will be the same directory as
get_home_directory().
See http://standards.freedesktop.org/basedir-spec/latest/ for more
information on the $XDG_CONFIG_HOME environmental variable.
"""
if sys.platform == 'win32':
return get_home_directory()
else:
base_path = os.getenv('XDG_CONFIG_HOME',
os.path.join(get_home_directory(), '.config'))
return os.path.join(base_path, 'mcomix')
def get_data_directory():
"""Return the path to the MComix data directory. On UNIX, this will
be $XDG_DATA_HOME/mcomix, on Windows it will be the same directory as
get_home_directory().
See http://standards.freedesktop.org/basedir-spec/latest/ for more
information on the $XDG_DATA_HOME environmental variable.
"""
if sys.platform == 'win32':
return get_home_directory()
else:
base_path = os.getenv('XDG_DATA_HOME',
os.path.join(get_home_directory(), '.local/share'))
return os.path.join(base_path, 'mcomix')
def number_of_digits(n):
if 0 == n:
return 1
return int(math.log10(abs(n))) + 1
def garbage_collect():
""" Runs the garbage collector. """
if sys.version_info[:3] >= (2, 5, 0):
gc.collect(0)
else:
gc.collect()
def div(a, b):
return float(a) / float(b)
def volume(t):
return reduce(operator.mul, t, 1)
def relerr(approx, ideal):
return abs((approx - ideal) / ideal)
def smaller(a, b):
""" Returns a list with the i-th element set to True if and only the i-th
element in a is less than the i-th element in b. """
return map(operator.lt, a, b)
def scale(t, factor):
return [x * factor for x in t]
def vector_sub(a, b):
""" Subtracts vector b from vector a. """
return map(operator.sub, a, b)
def vector_add(a, b):
""" Adds vector a to vector b. """
return map(operator.add, a, b)
def vector_opposite(a):
""" Returns the opposite vector -a. """
return map(operator.neg, a)
# vim: expandtab:sw=4:ts=4