File: __init__.py

package info (click to toggle)
python-renardo-lib 0.9.12-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,220 kB
  • sloc: python: 10,999; sh: 34; makefile: 7
file content (174 lines) | stat: -rw-r--r-- 4,068 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
"""

    Useful functions and classes, mostly relating to the Pattern class
    but used in multiple sub-packages of FoxDot.

"""

import sys
import json
from socket import timeout as socket_timeout
from urllib.request import urlopen
from urllib.error import URLError

def get_pypi_version():
    """ Returns the most up-to-date version number on PyPI. Return None on error """
    try:
        addr = "https://pypi.org/pypi/FoxDot/json"
        page = urlopen(addr, timeout=2.5)
        data = json.loads(page.read().decode("utf-8"))
        version = data["info"]["version"]
    except (URLError, socket_timeout):
        version = None
    return version


def stdout(*args):
    """ Forces prints to stdout and not console """
    sys.__stdout__.write(" ".join([str(s) for s in args]) + "\n")

def sliceToRange(s):
    start = s.start if s.start is not None else 0
    stop  = s.stop
    step  = s.step if s.step is not None else 1
    try:
        return list(range(start, stop, step))
    except OverflowError:
        raise TypeError("range() integer end argument expected, got NoneType")

def LCM(*args):
    """ Lowest Common Multiple """

    args = [n for n in args if n != 0]

    # Base case
    if len(args) == 0:
        return 1

    elif len(args) == 1:
        return args[0]

    X = list(args)

    while any([X[0]!=K for K in X]):

        i = X.index(min(X))
        X[i] += args[i]

    return X[0]

def EuclidsAlgorithm(n, k, lo=0, hi=1):

    if n == 0: return [n for i in range(k)]

    data = [[hi if i < n else lo] for i in range(k)]

    while True:

        k = k - n

        if k <= 1:
            break

        elif k < n:
            n, k = k, n

        for i in range(n):
            data[i] += data[-1]
            del data[-1]

    return [x for y in data for x in y]


def PulsesToDurations(data):
    """ Returns a list of durations based on pulses (1s) and blanks (0s).
        Data should be a list of [1,0] where 1 is a pulse. """
    
    count, seq = 1, []

    for item in data[1:]:

        if item == 1:

            seq.append(count)
            count = 1

        else:

            count += 1

    seq.append(count)

    return seq

def get_first_item(array):
    """ Returns first item from a possibly nested list"""
    try:
        return get_first_item(array[0])
    except (TypeError, IndexError):
        return array

def modi(array, i, debug=0):
    """ Returns the modulo index i.e. modi([0,1,2],4) will return 1 """
    try:
        return array[i % len(array)]
    except(TypeError, AttributeError, ZeroDivisionError):
        return array

def get_expanded_len(data):
    """ (0,(0,2)) returns 4. int returns 1 """
    if type(data) is str and len(data) == 1:
        return 1
    l = []
    try:
        for item in data:
            try:
                l.append(get_expanded_len(item))
            except(TypeError, AttributeError):
                l.append(1)
        return LCM(*l) * len(data)
    except TypeError:
        return 1

def max_length(*patterns):
    """ Returns the largest length pattern """
    return max([len(p) for p in patterns])

def get_inverse_op(method):
    """ Returns the opposite __dunder__ method e.g.
        get_inverse_op("__add__") -> "__radd__"
        get_inverse_op("__ror__") -> "__or__"
    """
    if method.startswith("__r"):
        return method.replace("__r", "__")
    elif method.startswith("__"):
        return method.replace("__", "__r", 1)
    return method

def isiterable(obj):
    """ Returns true if an object is iterable by using `iter(obj)`"""
    try:
        iter(obj)
        return True
    except:
        return False

def recursive_any(seq):
    """ Like any but checks lists recursively """
    for item in seq:
        if isiterable(item):
            if recursive_any(item):
                return True
        else:
            if bool(item):
                return True
    else:
        return False

# Classes

class dots:
    """ Class for representing long Patterns in strings """
    def __repr__(self):
        return '...'