Passed
Push — master ( c2a3b6...15a61d )
by Chris
01:00 queued 14s
created

abydos.compression._rle.rle_encode()   A

Complexity

Conditions 2

Size

Total Lines 46
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 46
ccs 6
cts 6
cp 1
rs 9.95
c 0
b 0
f 0
cc 2
nop 2
crap 2
1
# Copyright 2014-2020 by Christopher C. Little.
2
# This file is part of Abydos.
3
#
4
# Abydos is free software: you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# Abydos is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with Abydos. If not, see <http://www.gnu.org/licenses/>.
16
17
"""abydos.compression._rle.
18
19 1
Run-Length Encoding encoder/decoder
20
"""
21
22
from itertools import groupby
23
24 1
__all__ = ['RLE']
25
26
27
class RLE(object):
28
    """Run-Length Encoding.
29
30
    Cf. :cite:`Robinson:1967`.
31 1
32
    Based on http://rosettacode.org/wiki/Run-length_encoding#Python
33 1
    :cite:`rosettacode:2018`. This is licensed GFDL 1.2.
34
35 1
    Digits 0-9 cannot be in text.
36 1
37
    .. versionadded:: 0.3.6
38 1
    """
39
40
    def encode(self, text):
41 1
        r"""Perform encoding of run-length-encoding (RLE).
42
43
        Parameters
44
        ----------
45
        text : str
46
            A text string to encode
47
48
        Returns
49
        -------
50
        str
51
            Word decoded by RLE
52
53
        Examples
54 1
        --------
55
        >>> from abydos.compression import BWT
56
        >>> rle = RLE()
57
        >>> bwt = BWT()
58
        >>> rle.encode(bwt.encode('align'))
59
        'n\x00ilag'
60
        >>> rle.encode('align')
61
        'align'
62
63
        >>> rle.encode(bwt.encode('banana'))
64
        'annb\x00aa'
65
        >>> rle.encode('banana')
66
        'banana'
67
68
        >>> rle.encode(bwt.encode('aaabaabababa'))
69
        'ab\x00abbab5a'
70
        >>> rle.encode('aaabaabababa')
71
        '3abaabababa'
72
73
        .. versionadded:: 0.1.0
74
        .. versionchanged:: 0.3.6
75
            Encapsulated in class
76
77
        """
78
        if text:
79
            text = ((len(list(g)), k) for k, g in groupby(text))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable g does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable k does not seem to be defined.
Loading history...
80
            text = (
81
                (str(n) + k if n > 2 else (k if n == 1 else 2 * k))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable n does not seem to be defined.
Loading history...
82
                for n, k in text
83
            )
84
        return ''.join(text)
85
86
    def decode(self, text):
87
        r"""Perform decoding of run-length-encoding (RLE).
88
89
        Parameters
90
        ----------
91 1
        text : str
92 1
            A text string to decode
93 1
94
        Returns
95
        -------
96
        str
97 1
            Word decoded by RLE
98
99 1
        Examples
100
        --------
101
        >>> from abydos.compression import BWT
102
        >>> rle = RLE()
103
        >>> bwt = BWT()
104
        >>> bwt.decode(rle.decode('n\x00ilag'))
105
        'align'
106
        >>> rle.decode('align')
107
        'align'
108
109
        >>> bwt.decode(rle.decode('annb\x00aa'))
110
        'banana'
111
        >>> rle.decode('banana')
112
        'banana'
113
114
        >>> bwt.decode(rle.decode('ab\x00abbab5a'))
115
        'aaabaabababa'
116
        >>> rle.decode('3abaabababa')
117
        'aaabaabababa'
118
119
        .. versionadded:: 0.1.0
120
        .. versionchanged:: 0.3.6
121
            Encapsulated in class
122
123
        """
124
        mult = ''
125
        decoded = []
126
        for letter in list(text):
127
            if not letter.isdigit():
128
                if mult:
129
                    decoded.append(int(mult) * letter)
130
                    mult = ''
131
                else:
132
                    decoded.append(letter)
133
            else:
134
                mult += letter
135
136 1
        text = ''.join(decoded)
137 1
        return text
138 1
139 1
140 1
if __name__ == '__main__':
141 1
    import doctest
142 1
143
    doctest.testmod()
144