bindings/python/rad_util.py
author Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
Sun, 12 Oct 2008 18:04:10 +0100
changeset 3743 d0cf214d050c
parent 3408 2cc40b3e4fa5
permissions -rw-r--r--
Rescan API for Python.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3408
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     1
# Copyright (c) 2007 RADLogic
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     2
# 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     3
# Permission is hereby granted, free of charge, to any person obtaining a copy
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     4
# of this software and associated documentation files (the "Software"), to deal
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     5
# in the Software without restriction, including without limitation the rights
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     6
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     7
# copies of the Software, and to permit persons to whom the Software is
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     8
# furnished to do so, subject to the following conditions:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
     9
# 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    10
# The above copyright notice and this permission notice shall be included in
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    11
# all copies or substantial portions of the Software.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    12
# 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    13
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    14
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    15
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    16
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    17
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    18
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    19
# THE SOFTWARE.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    20
"""Provide various handy Python functions.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    21
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    22
Running this script directly will execute the doctests.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    23
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    24
Functions:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    25
int2bin(i, n) -- Convert integer to binary string.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    26
bin2int(bin_string) -- Convert binary string to integer.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    27
reverse(input_string) -- Reverse a string.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    28
transpose(matrix) -- Transpose a list of lists.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    29
polygon_area(points_list) -- Calculate the area of an arbitrary polygon.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    30
timestamp() -- Return string containing current time stamp.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    31
pt2str(point) -- Return prettier string version of point tuple.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    32
gcf(a, b) -- Return the greatest common factor of two numbers.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    33
lcm(a, b) -- Return the least common multiple of two numbers.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    34
permutations(input_list) -- Generate all permutations of a list of items.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    35
reduce_fraction(fraction) -- Reduce fraction (num, denom) to simplest form.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    36
quantile(l, p) -- Return p quantile of list l. E.g. p=0.25 for q1.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    37
trim(l) -- Discard values in list more than 1.5*IQR outside IQR.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    38
nice_units(value) -- Return value converted to human readable units.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    39
uniquify(seq) -- Return sequence with duplicate items in sequence seq removed.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    40
reverse_dict(d) -- Return the dictionary with the items as keys and vice-versa.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    41
lsb(x, n) -- Return the n least significant bits of x.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    42
gray_encode(i) -- Gray encode the given integer.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    43
random_vec(bits, max_value=None) -- Return a random binary vector.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    44
binary_range(bits) -- Return list of all possible binary numbers width=bits.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    45
float_range([start], stop, [step]) -- Return range of floats.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    46
find_common_fixes(s1, s2) -- Find common (prefix, suffix) of two strings.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    47
is_rotated(seq1, seq2) -- Return true if the list is a rotation of other list.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    48
getmodule(obj) -- Return the module that contains the object definition of obj.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    49
                  (use inspect.getmodule instead, though)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    50
get_args(argv) -- Store command-line args in a dictionary.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    51
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    52
This module requires Python >= 2.2
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    53
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    54
"""
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    55
__author__ = 'Tim Wegener <twegener@radlogic.com.au>'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    56
__date__ = '$Date: 2007/03/27 03:15:06 $'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    57
__version__ = '$Revision: 0.45 $'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    58
__credits__ = """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    59
              David Chandler, for polygon area algorithm.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    60
               (http://www.davidchandler.com/AreaOfAGeneralPolygon.pdf)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    61
              """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    62
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    63
import re
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    64
import sys
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    65
import time
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    66
import random
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    67
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    68
try:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    69
    True, False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    70
except NameError:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    71
    True, False = (1==1, 0==1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    72
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    73
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    74
def int2bin(i, n):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    75
    """Convert decimal integer i to n-bit binary number (string).
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    76
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    77
    >>> int2bin(0, 8)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    78
    '00000000'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    79
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    80
    >>> int2bin(123, 8)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    81
    '01111011'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    82
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    83
    >>> int2bin(123L, 8)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    84
    '01111011'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    85
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    86
    >>> int2bin(15, 2)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    87
    Traceback (most recent call last):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    88
    ValueError: Value too large for given number of bits.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    89
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    90
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    91
    hex2bin = {'0': '0000', '1': '0001', '2': '0010', '3': '0011',
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    92
               '4': '0100', '5': '0101', '6': '0110', '7': '0111',
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    93
               '8': '1000', '9': '1001', 'a': '1010', 'b': '1011',
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    94
               'c': '1100', 'd': '1101', 'e': '1110', 'f': '1111'}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    95
    # Convert to hex then map each hex digit to binary equivalent.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    96
    result = ''.join([hex2bin[x] for x in hex(i).lower().replace('l','')[2:]])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    97
                      
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    98
    # Shrink result to appropriate length.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
    99
    # Raise an error if the value is changed by the truncation.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   100
    if '1' in result[:-n]:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   101
        raise ValueError("Value too large for given number of bits.")
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   102
    result = result[-n:]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   103
    # Zero-pad if length longer than mapped result.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   104
    result = '0'*(n-len(result)) + result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   105
    return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   106
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   107
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   108
def bin2int(bin_string):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   109
    """Convert binary number string to decimal integer.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   110
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   111
    Note: Python > v2 has int(bin_string, 2)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   112
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   113
    >>> bin2int('1111')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   114
    15
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   115
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   116
    >>> bin2int('0101')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   117
    5
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   118
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   119
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   120
##     result = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   121
##     bin_list = list(bin_string)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   122
##     if len(filter(lambda x: x in ('1','0'), bin_list)) < len(bin_list):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   123
##         raise Exception ("bin2int: Error - not a binary number: %s"
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   124
##                          % bin_string)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   125
##     bit_list = map(int, bin_list)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   126
##     bit_list.reverse()  # Make most significant bit have highest index.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   127
##     for bit_place in range(len(bit_list)):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   128
##         result = result + ((2**bit_place) * bit_list[bit_place])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   129
##     return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   130
    return int(bin_string, 2)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   131
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   132
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   133
def reverse(input_string):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   134
    """Reverse a string. Useful for strings of binary numbers.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   135
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   136
    >>> reverse('abc')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   137
    'cba'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   138
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   139
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   140
    str_list = list(input_string)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   141
    str_list.reverse()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   142
    return ''.join(str_list)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   143
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   144
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   145
def transpose(matrix):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   146
    """Transpose a list of lists.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   147
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   148
    >>> transpose([['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   149
    [['a', 'd', 'g'], ['b', 'e', 'h'], ['c', 'f', 'i']]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   150
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   151
    >>> transpose([['a', 'b', 'c'], ['d', 'e', 'f']])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   152
    [['a', 'd'], ['b', 'e'], ['c', 'f']]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   153
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   154
    >>> transpose([['a', 'b'], ['d', 'e'], ['g', 'h']])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   155
    [['a', 'd', 'g'], ['b', 'e', 'h']]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   156
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   157
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   158
    result = zip(*matrix)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   159
    # Convert list of tuples to list of lists.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   160
    # map is faster than a list comprehension since it is being used with
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   161
    # a built-in function as an argument.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   162
    result = map(list, result)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   163
    return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   164
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   165
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   166
def polygon_area(points_list, precision=100):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   167
    """Calculate area of an arbitrary polygon using an algorithm from the web.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   168
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   169
    Return the area of the polygon as a positive float. 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   170
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   171
    Arguments:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   172
    points_list -- list of point tuples [(x0, y0), (x1, y1), (x2, y2), ...]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   173
                   (Unclosed polygons will be closed automatically.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   174
    precision -- Internal arithmetic precision (integer arithmetic).
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   175
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   176
    >>> polygon_area([(0, 0), (0, 1), (1, 1), (1, 2), (2, 2), (2, 0), (0, 0)])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   177
    3.0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   178
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   179
    Credits:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   180
    Area of a General Polygon by David Chandler
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   181
    http://www.davidchandler.com/AreaOfAGeneralPolygon.pdf
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   182
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   183
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   184
    # Scale up co-ordinates and convert them to integers.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   185
    for i in range(len(points_list)):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   186
        points_list[i] = (int(points_list[i][0] * precision),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   187
                          int(points_list[i][1] * precision))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   188
    # Close polygon if not closed.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   189
    if points_list[-1] != points_list[0]:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   190
        points_list.append(points_list[0])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   191
    # Calculate area.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   192
    area = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   193
    for i in range(len(points_list)-1):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   194
        (x_i, y_i) = points_list[i]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   195
        (x_i_plus_1, y_i_plus_1) = points_list[i+1]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   196
        area = area + (x_i_plus_1 * y_i) - (y_i_plus_1 * x_i)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   197
    area = abs(area / 2)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   198
    # Unscale area.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   199
    area = float(area)/(precision**2)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   200
    return area
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   201
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   202
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   203
def timestamp():
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   204
    """Return string containing current time stamp.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   205
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   206
    Note: In Python 2 onwards can use time.asctime() with no arguments.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   207
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   208
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   209
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   210
    return time.asctime()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   211
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   212
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   213
def pt2str(point):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   214
    """Return prettier string version of point tuple.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   215
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   216
    >>> pt2str((1.8, 1.9))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   217
    '(1.8, 1.9)'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   218
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   219
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   220
    return "(%s, %s)" % (str(point[0]), str(point[1]))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   221
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   222
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   223
def gcf(a, b, epsilon=1e-16):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   224
    """Return the greatest common factor of a and b, using Euclidean algorithm.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   225
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   226
    Arguments:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   227
    a, b -- two numbers
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   228
            If both numbers are integers return an integer result, 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   229
            otherwise return a float result.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   230
    epsilon -- floats less than this magnitude are considered to be zero
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   231
               (default: 1e-16)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   232
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   233
    Examples:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   234
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   235
    >>> gcf(12, 34)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   236
    2
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   237
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   238
    >>> gcf(13.5, 4)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   239
    0.5
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   240
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   241
    >>> gcf(-2, 4)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   242
    2
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   243
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   244
    >>> gcf(5, 0)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   245
    5
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   246
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   247
    By (a convenient) definition:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   248
    >>> gcf(0, 0)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   249
    0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   250
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   251
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   252
    result = max(a, b)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   253
    remainder = min(a, b)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   254
    while remainder and abs(remainder) > epsilon:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   255
        new_remainder = result % remainder
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   256
        result = remainder
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   257
        remainder = new_remainder
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   258
    return abs(result)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   259
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   260
def lcm(a, b, precision=None):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   261
    """Return the least common multiple of a and b, using the gcf function.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   262
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   263
    Arguments:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   264
    a, b -- two numbers. If both are integers return an integer result, 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   265
            otherwise a return a float result.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   266
    precision -- scaling factor if a and/or b are floats.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   267
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   268
    >>> lcm(21, 6)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   269
    42
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   270
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   271
    >>> lcm(2.5, 3.5)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   272
    17.5
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   273
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   274
    >>> str(lcm(1.5e-8, 2.5e-8, precision=1e9))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   275
    '7.5e-08'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   276
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   277
    By (an arbitary) definition:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   278
    >>> lcm(0, 0)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   279
    0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   280
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   281
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   282
    # Note: Dummy precision argument is for backwards compatibility.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   283
    # Do the division first.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   284
    # (See http://en.wikipedia.org/wiki/Least_common_multiple )
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   285
    denom = gcf(a, b)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   286
    if denom == 0:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   287
        result = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   288
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   289
        result = a * (b / denom)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   290
    return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   291
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   292
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   293
def permutations(input_list):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   294
    """Return a list containing all permutations of the input list.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   295
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   296
    Note: This is a recursive function.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   297
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   298
    >>> perms = permutations(['a', 'b', 'c'])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   299
    >>> perms.sort()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   300
    >>> for perm in perms:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   301
    ...     print perm
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   302
    ['a', 'b', 'c']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   303
    ['a', 'c', 'b']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   304
    ['b', 'a', 'c']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   305
    ['b', 'c', 'a']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   306
    ['c', 'a', 'b']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   307
    ['c', 'b', 'a']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   308
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   309
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   310
    out_lists = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   311
    if len(input_list) > 1:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   312
        # Extract first item in list.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   313
        item = input_list[0]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   314
        # Find all permutations of remainder of list. (Recursive call.)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   315
        sub_lists = permutations(input_list[1:])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   316
        # For every permutation of the sub list...
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   317
        for sub_list in sub_lists:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   318
            # Insert the extracted first item at every position of the list.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   319
            for i in range(len(input_list)):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   320
                new_list = sub_list[:]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   321
                new_list.insert(i, item)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   322
                out_lists.append(new_list)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   323
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   324
        # Termination condition: only one item in input list.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   325
        out_lists = [input_list]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   326
    return out_lists
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   327
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   328
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   329
def reduce_fraction(fraction):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   330
    """Reduce fraction tuple to simplest form. fraction=(num, denom)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   331
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   332
    >>> reduce_fraction((14, 7))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   333
    (2, 1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   334
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   335
    >>> reduce_fraction((-2, 4))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   336
    (-1, 2)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   337
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   338
    >>> reduce_fraction((0, 4))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   339
    (0, 1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   340
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   341
    >>> reduce_fraction((4, 0))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   342
    (1, 0)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   343
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   344
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   345
    (numerator, denominator) = fraction
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   346
    common_factor = abs(gcf(numerator, denominator))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   347
    result = (numerator/common_factor, denominator/common_factor)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   348
    return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   349
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   350
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   351
def quantile(l, p):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   352
    """Return p quantile of list l. E.g. p=0.25 for q1.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   353
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   354
    See:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   355
    http://rweb.stat.umn.edu/R/library/base/html/quantile.html
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   356
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   357
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   358
    l_sort = l[:]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   359
    l_sort.sort()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   360
    n = len(l)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   361
    r = 1 + ((n - 1) * p)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   362
    i = int(r)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   363
    f = r - i
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   364
    if i < n:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   365
        result =  (1-f)*l_sort[i-1] + f*l_sort[i]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   366
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   367
        result = l_sort[i-1]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   368
    return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   369
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   370
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   371
def trim(l):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   372
    """Discard values in list more than 1.5*IQR outside IQR.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   373
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   374
    (IQR is inter-quartile-range)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   375
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   376
    This function uses rad_util.quantile
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   377
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   378
    1.5*IQR -- mild outlier
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   379
    3*IQR -- extreme outlier
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   380
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   381
    See:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   382
    http://wind.cc.whecn.edu/~pwildman/statnew/section_7_-_exploratory_data_analysis.htm
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   383
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   384
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   385
    l_sort = l[:]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   386
    l_sort.sort()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   387
    # Calculate medianscore  (based on stats.py lmedianscore by Gary Strangman)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   388
    if len(l_sort) % 2 == 0:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   389
        # If even number of scores, average middle 2.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   390
        index = int(len(l_sort) / 2)  # Integer division correct
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   391
        median = float(l_sort[index] + l_sort[index-1]) / 2
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   392
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   393
        # int divsion gives mid value when count from 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   394
        index = int(len(l_sort) / 2)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   395
        median = l_sort[index]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   396
    # Calculate IQR.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   397
    q1 = quantile(l_sort, 0.25)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   398
    q3 = quantile(l_sort, 0.75)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   399
    iqr = q3 - q1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   400
    iqr_extra = iqr * 1.5
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   401
    def in_interval(x, i=iqr_extra, q1=q1, q3=q3):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   402
        return (x >= q1-i and x <= q3+i)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   403
    l_trimmed = [x for x in l_sort if in_interval(x)]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   404
    return l_trimmed
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   405
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   406
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   407
def nice_units(value, dp=0, sigfigs=None, suffix='', space=' ',
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   408
               use_extra_prefixes=False, use_full_name=False, mode='si'):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   409
    """Return value converted to human readable units eg milli, micro, etc.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   410
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   411
    Arguments:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   412
    value -- number in base units
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   413
    dp -- number of decimal places to display (rounded)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   414
    sigfigs -- number of significant figures to display (rounded)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   415
               This overrides dp if set.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   416
    suffix -- optional unit suffix to append to unit multiplier
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   417
    space -- seperator between value and unit multiplier (default: ' ')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   418
    use_extra_prefixes -- use hecto, deka, deci and centi as well if set.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   419
                          (default: False)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   420
    use_full_name -- use full name for multiplier symbol,
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   421
                     e.g. milli instead of m
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   422
                     (default: False)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   423
    mode -- 'si' for SI prefixes, 'bin' for binary multipliers (1024, etc.)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   424
            (Default: 'si')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   425
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   426
    SI prefixes from:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   427
    http://physics.nist.gov/cuu/Units/prefixes.html
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   428
    (Greek mu changed to u.)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   429
    Binary prefixes based on:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   430
    http://physics.nist.gov/cuu/Units/binary.html
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   431
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   432
    >>> nice_units(2e-11)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   433
    '20 p'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   434
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   435
    >>> nice_units(2e-11, space='')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   436
    '20p'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   437
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   438
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   439
    si_prefixes = {1e24:  ('Y', 'yotta'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   440
                   1e21:  ('Z', 'zetta'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   441
                   1e18:  ('E', 'exa'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   442
                   1e15:  ('P', 'peta'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   443
                   1e12:  ('T', 'tera'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   444
                   1e9:   ('G', 'giga'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   445
                   1e6:   ('M', 'mega'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   446
                   1e3:   ('k', 'kilo'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   447
                   1e-3:  ('m', 'milli'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   448
                   1e-6:  ('u', 'micro'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   449
                   1e-9:  ('n', 'nano'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   450
                   1e-12: ('p', 'pico'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   451
                   1e-15: ('f', 'femto'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   452
                   1e-18: ('a', 'atto'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   453
                   1e-21: ('z', 'zepto'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   454
                   1e-24: ('y', 'yocto')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   455
                   }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   456
    if use_extra_prefixes:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   457
        si_prefixes.update({1e2:  ('h', 'hecto'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   458
                            1e1:  ('da', 'deka'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   459
                            1e-1: ('d', 'deci'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   460
                            1e-2: ('c', 'centi')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   461
                            })
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   462
    bin_prefixes = {2**10: ('K', 'kilo'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   463
                    2**20: ('M', 'mega'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   464
                    2**30: ('G', 'mega'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   465
                    2**40: ('T', 'tera'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   466
                    2**50: ('P', 'peta'),
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   467
                    2**60: ('E', 'exa')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   468
                    }
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   469
    if mode == 'bin':
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   470
        prefixes = bin_prefixes
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   471
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   472
        prefixes = si_prefixes
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   473
    prefixes[1] = ('', '')  # Unity.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   474
    # Determine appropriate multiplier.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   475
    multipliers = prefixes.keys()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   476
    multipliers.sort()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   477
    mult = None
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   478
    for i in range(len(multipliers) - 1):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   479
        lower_mult = multipliers[i]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   480
        upper_mult = multipliers[i+1]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   481
        if lower_mult <= value < upper_mult:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   482
            mult_i = i
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   483
            break
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   484
    if mult is None:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   485
        if value < multipliers[0]:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   486
            mult_i = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   487
        elif value >= multipliers[-1]:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   488
            mult_i = len(multipliers) - 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   489
    mult = multipliers[mult_i]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   490
    # Convert value for this multiplier.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   491
    new_value = value / mult
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   492
    # Deal with special case due to rounding.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   493
    if sigfigs is None:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   494
        if mult_i < (len(multipliers) - 1) and \
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   495
               round(new_value, dp) == \
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   496
               round((multipliers[mult_i+1] / mult), dp):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   497
            mult = multipliers[mult_i + 1]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   498
            new_value = value / mult
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   499
    # Concatenate multiplier symbol.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   500
    if use_full_name:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   501
        label_type = 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   502
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   503
        label_type = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   504
    # Round and truncate to appropriate precision.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   505
    if sigfigs is None:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   506
        str_value = eval('"%.'+str(dp)+'f" % new_value', locals(), {})
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   507
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   508
        str_value = eval('"%.'+str(sigfigs)+'g" % new_value', locals(), {})
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   509
    return str_value + space + prefixes[mult][label_type] + suffix
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   510
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   511
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   512
def uniquify(seq, preserve_order=False):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   513
    """Return sequence with duplicate items in sequence seq removed.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   514
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   515
    The code is based on usenet post by Tim Peters.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   516
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   517
    This code is O(N) if the sequence items are hashable, O(N**2) if not.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   518
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   519
    Peter Bengtsson has a blog post with an empirical comparison of other
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   520
    approaches:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   521
    http://www.peterbe.com/plog/uniqifiers-benchmark
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   522
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   523
    If order is not important and the sequence items are hashable then
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   524
    list(set(seq)) is readable and efficient.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   525
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   526
    If order is important and the sequence items are hashable generator
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   527
    expressions can be used (in py >= 2.4) (useful for large sequences):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   528
    seen = set()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   529
    do_something(x for x in seq if x not in seen or seen.add(x))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   530
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   531
    Arguments:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   532
    seq -- sequence
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   533
    preserve_order -- if not set the order will be arbitrary
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   534
                      Using this option will incur a speed penalty.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   535
                      (default: False)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   536
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   537
    Example showing order preservation:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   538
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   539
    >>> uniquify(['a', 'aa', 'b', 'b', 'ccc', 'ccc', 'd'], preserve_order=True)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   540
    ['a', 'aa', 'b', 'ccc', 'd']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   541
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   542
    Example using a sequence of un-hashable items:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   543
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   544
    >>> uniquify([['z'], ['x'], ['y'], ['z']], preserve_order=True)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   545
    [['z'], ['x'], ['y']]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   546
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   547
    The sorted output or the non-order-preserving approach should equal
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   548
    that of the sorted order-preserving approach output:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   549
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   550
    >>> unordered = uniquify([3, 3, 1, 2], preserve_order=False)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   551
    >>> unordered.sort()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   552
    >>> ordered = uniquify([3, 3, 1, 2], preserve_order=True)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   553
    >>> ordered.sort()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   554
    >>> ordered
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   555
    [1, 2, 3]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   556
    >>> int(ordered == unordered)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   557
    1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   558
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   559
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   560
    try:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   561
        # Attempt fast algorithm.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   562
        d = {}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   563
        if preserve_order:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   564
            # This is based on Dave Kirby's method (f8) noted in the post:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   565
            # http://www.peterbe.com/plog/uniqifiers-benchmark
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   566
            return [x for x in seq if (x not in d) and not d.__setitem__(x, 0)]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   567
        else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   568
            for x in seq:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   569
                d[x] = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   570
            return d.keys()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   571
    except TypeError:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   572
        # Have an unhashable object, so use slow algorithm.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   573
        result = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   574
        app = result.append
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   575
        for x in seq:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   576
            if x not in result:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   577
                app(x)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   578
        return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   579
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   580
# Alias to noun form for backward compatibility.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   581
unique = uniquify
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   582
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   583
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   584
def reverse_dict(d):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   585
    """Reverse a dictionary so the items become the keys and vice-versa.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   586
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   587
    Note: The results will be arbitrary if the items are not unique.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   588
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   589
    >>> d = reverse_dict({'a': 1, 'b': 2})
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   590
    >>> d_items = d.items()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   591
    >>> d_items.sort()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   592
    >>> d_items
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   593
    [(1, 'a'), (2, 'b')]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   594
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   595
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   596
    result = {}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   597
    for key, value in d.items():
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   598
        result[value] = key
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   599
    return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   600
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   601
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   602
def lsb(x, n):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   603
    """Return the n least significant bits of x.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   604
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   605
    >>> lsb(13, 3)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   606
    5
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   607
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   608
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   609
    return x & ((2 ** n) - 1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   610
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   611
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   612
def gray_encode(i):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   613
    """Gray encode the given integer."""
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   614
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   615
    return i ^ (i >> 1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   616
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   617
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   618
def random_vec(bits, max_value=None):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   619
    """Generate a random binary vector of length bits and given max value."""
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   620
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   621
    vector = ""
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   622
    for _ in range(int(bits / 10) + 1):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   623
        i = int((2**10) * random.random())
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   624
        vector += int2bin(i, 10)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   625
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   626
    if max_value and (max_value < 2 ** bits - 1):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   627
        vector = int2bin((int(vector, 2) / (2 ** bits - 1)) * max_value, bits)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   628
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   629
    return vector[0:bits]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   630
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   631
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   632
def binary_range(bits):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   633
    """Return a list of all possible binary numbers in order with width=bits. 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   634
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   635
    It would be nice to extend it to match the
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   636
    functionality of python's range() built-in function.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   637
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   638
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   639
    l = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   640
    v = ['0'] * bits
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   641
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   642
    toggle = [1] + [0] * bits
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   643
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   644
    while toggle[bits] != 1:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   645
        v_copy = v[:]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   646
        v_copy.reverse()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   647
        l.append(''.join(v_copy))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   648
        
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   649
        toggle = [1] + [0]*bits
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   650
        i = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   651
        while i < bits and toggle[i] == 1:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   652
            if toggle[i]:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   653
                if v[i] == '0':
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   654
                    v[i] = '1'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   655
                    toggle[i+1] = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   656
                else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   657
                    v[i] = '0'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   658
                    toggle[i+1] = 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   659
            i += 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   660
    return l
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   661
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   662
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   663
def float_range(start, stop=None, step=None):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   664
    """Return a list containing an arithmetic progression of floats.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   665
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   666
    Return a list of floats between 0.0 (or start) and stop with an
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   667
    increment of step. 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   668
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   669
    This is in functionality to python's range() built-in function 
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   670
    but can accept float increments.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   671
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   672
    As with range(), stop is omitted from the list.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   673
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   674
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   675
    if stop is None:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   676
        stop = float(start)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   677
        start = 0.0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   678
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   679
    if step is None:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   680
        step = 1.0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   681
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   682
    cur = float(start)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   683
    l = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   684
    while cur < stop:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   685
        l.append(cur)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   686
        cur += step
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   687
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   688
    return l
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   689
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   690
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   691
def find_common_fixes(s1, s2):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   692
    """Find common (prefix, suffix) of two strings.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   693
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   694
    >>> find_common_fixes('abc', 'def')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   695
    ('', '')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   696
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   697
    >>> find_common_fixes('abcelephantdef', 'abccowdef')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   698
    ('abc', 'def')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   699
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   700
    >>> find_common_fixes('abcelephantdef', 'abccow')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   701
    ('abc', '')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   702
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   703
    >>> find_common_fixes('elephantdef', 'abccowdef')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   704
    ('', 'def')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   705
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   706
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   707
    prefix = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   708
    suffix = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   709
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   710
    i = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   711
    common_len = min(len(s1), len(s2))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   712
    while i < common_len:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   713
        if s1[i] != s2[i]:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   714
            break
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   715
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   716
        prefix.append(s1[i])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   717
        i += 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   718
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   719
    i = 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   720
    while i < (common_len + 1):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   721
        if s1[-i] != s2[-i]:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   722
            break
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   723
        
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   724
        suffix.append(s1[-i])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   725
        i += 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   726
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   727
    suffix.reverse()
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   728
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   729
    prefix = ''.join(prefix)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   730
    suffix = ''.join(suffix)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   731
        
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   732
    return (prefix, suffix)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   733
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   734
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   735
def is_rotated(seq1, seq2):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   736
    """Return true if the first sequence is a rotation of the second sequence.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   737
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   738
    >>> seq1 = ['A', 'B', 'C', 'D']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   739
    >>> seq2 = ['C', 'D', 'A', 'B']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   740
    >>> int(is_rotated(seq1, seq2))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   741
    1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   742
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   743
    >>> seq2 = ['C', 'D', 'B', 'A']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   744
    >>> int(is_rotated(seq1, seq2))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   745
    0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   746
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   747
    >>> seq1 = ['A', 'B', 'C', 'A']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   748
    >>> seq2 = ['A', 'A', 'B', 'C']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   749
    >>> int(is_rotated(seq1, seq2))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   750
    1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   751
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   752
    >>> seq2 = ['A', 'B', 'C', 'A']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   753
    >>> int(is_rotated(seq1, seq2))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   754
    1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   755
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   756
    >>> seq2 = ['A', 'A', 'C', 'B']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   757
    >>> int(is_rotated(seq1, seq2))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   758
    0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   759
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   760
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   761
    # Do a sanity check.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   762
    if len(seq1) != len(seq2):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   763
        return False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   764
    # Look for occurrences of second sequence head item in first sequence.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   765
    start_indexes = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   766
    head_item = seq2[0]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   767
    for index1 in range(len(seq1)):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   768
        if seq1[index1] == head_item:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   769
            start_indexes.append(index1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   770
    # Check that wrapped sequence matches.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   771
    double_seq1 = seq1 + seq1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   772
    for index1 in start_indexes:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   773
        if double_seq1[index1:index1+len(seq1)] == seq2:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   774
            return True
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   775
    return False
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   776
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   777
def getmodule(obj):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   778
    """Return the module that contains the object definition of obj.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   779
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   780
    Note: Use inspect.getmodule instead.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   781
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   782
    Arguments:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   783
    obj -- python obj, generally a class or a function
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   784
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   785
    Examples:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   786
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   787
    A function:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   788
    >>> module = getmodule(random.choice)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   789
    >>> module.__name__
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   790
    'random'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   791
    >>> module is random
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   792
    1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   793
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   794
    A class:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   795
    >>> module = getmodule(random.Random)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   796
    >>> module.__name__
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   797
    'random'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   798
    >>> module is random
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   799
    1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   800
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   801
    A class inheriting from a class in another module:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   802
    (note: The inheriting class must define at least one function.)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   803
    >>> class MyRandom(random.Random):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   804
    ...     def play(self):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   805
    ...         pass
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   806
    >>> module = getmodule(MyRandom)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   807
    >>> if __name__ == '__main__':
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   808
    ...     name = 'rad_util'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   809
    ... else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   810
    ...     name = module.__name__
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   811
    >>> name
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   812
    'rad_util'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   813
    >>> module is sys.modules[__name__]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   814
    1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   815
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   816
    Discussion:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   817
    This approach is slightly hackish, and won't work in various situations.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   818
    However, this was the approach recommended by GvR, so it's as good as
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   819
    you'll get.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   820
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   821
    See GvR's post in this thread:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   822
    http://groups.google.com.au/group/comp.lang.python/browse_thread/thread/966a7bdee07e3b34/c3cab3f41ea84236?lnk=st&q=python+determine+class+module&rnum=4&hl=en#c3cab3f41ea84236
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   823
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   824
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   825
    if hasattr(obj, 'func_globals'):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   826
        func = obj
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   827
    else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   828
        # Handle classes.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   829
        func = None
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   830
        for item in obj.__dict__.values():
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   831
            if hasattr(item, 'func_globals'):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   832
                func = item
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   833
                break
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   834
        if func is None:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   835
            raise ValueError("No functions attached to object: %r" % obj)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   836
    module_name = func.func_globals['__name__']
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   837
    # Get module.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   838
    module = sys.modules[module_name]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   839
    return module
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   840
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   841
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   842
def round_grid(value, grid, mode=0):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   843
    """Round off the given value to the given grid size.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   844
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   845
    Arguments:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   846
    value -- value to be roudne
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   847
    grid -- result must be a multiple of this
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   848
    mode -- 0 nearest, 1 up, -1 down
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   849
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   850
    Examples:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   851
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   852
    >>> round_grid(7.5, 5)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   853
    10
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   854
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   855
    >>> round_grid(7.5, 5, mode=-1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   856
    5
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   857
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   858
    >>> round_grid(7.3, 5, mode=1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   859
    10
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   860
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   861
    >>> round_grid(7.3, 5.0, mode=1)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   862
    10.0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   863
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   864
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   865
    off_grid = value % grid
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   866
    if mode == 0:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   867
        add_one = int(off_grid >= (grid / 2.0))
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   868
    elif mode == 1 and off_grid:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   869
        add_one = 1
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   870
    elif mode == -1 and off_grid:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   871
        add_one = 0
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   872
    result = ((int(value / grid) + add_one) * grid)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   873
    return result
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   874
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   875
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   876
def get_args(argv):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   877
    """Store command-line args in a dictionary.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   878
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   879
    -, -- prefixes are removed
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   880
    Items not prefixed with - or -- are stored as a list, indexed by 'args'
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   881
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   882
    For options that take a value use --option=value
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   883
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   884
    Consider using optparse or getopt (in Python standard library) instead.
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   885
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   886
    """
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   887
    d = {}
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   888
    args = []
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   889
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   890
    for arg in argv:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   891
            
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   892
        if arg.startswith('-'):
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   893
            parts = re.sub(r'^-+', '', arg).split('=')
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   894
            if len(parts) == 2:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   895
                d[parts[0]] = parts[1]
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   896
            else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   897
                d[parts[0]] = None
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   898
        else:
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   899
            args.append(arg)
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   900
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   901
    d['args'] = args
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   902
    
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   903
    return d
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   904
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   905
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   906
if __name__ == '__main__':
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   907
    import doctest
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   908
    doctest.testmod(sys.modules['__main__'])
2cc40b3e4fa5 python bindings
Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
parents:
diff changeset
   909