Reputation: 65
Currently, I have two functions: char2bin
and segmentString
.
segmentString takes a string and a fill character and returns lists of 8 character strings. For example, if there is a 13 character string, it splits it into a list of two strings where the second string has 3 fill characters to make it a complete 8.
>>>segmentString("Hello, World!", "-")
['Hello, W', 'orld!---']
char2bin takes individual string characters (single character) and turns them into a list of 8 bits. It does not work for multiple character strings. For example,
>>>char2bin('a')
[0,1,1,0,0,0,0,1]
>>>char2bin('abc')
(ERROR)
I need to create a function (in this example, let's call it framer) that takes the result from segmentString and convert it into a list of bits, where each list of bits are contained in a separate list within a list.
For example, from the segmentString function, this would create a list of two strings. Each letter of each separate string is converted into a list of bits, and each list of bits is contained as a list for each string.
>>>F=framer("Hello, World!", "-")
>>>F
[[[0, 1, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1], [0,1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1,1,1], [0, 0, 1, 0, 1, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1,1, 1,0, 1, 1, 1]], [[0, 1, 1, 0, 1, 1, 1, 1], [0, 1, 1, 1, 0, 0,1, 0], [0,1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 0, 1, 0, 0], [0, 0,1, 0, 0, 0, 0,1], [0, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1,1, 0], [0, 1, 1, 1,1, 1, 1, 0]]]
As you can see, there is one general list that contains two lists that contain 8 lists of bits, which were converted from a string character by char2bin. How would I do this?
Upvotes: 2
Views: 304
Reputation: 23064
You can use a list comprehension for this:
def char2bin(byte):
return list(map(int, format(byte, '08b')))
def segmentString(text, padding, chunksize):
for index in range(0, len(text), chunksize):
yield text[index:index + chunksize].ljust(chunksize, padding)
def framer(text, padding='-', chunksize=8, encoding='utf8'):
return [[char2bin(byte) for byte in segment] for segment in
segmentString(text.encode(encoding), padding.encode(encoding), chunksize)]
This uses utf8 encoding, but since your input text is all ascii characters, there's one byte per character.
>>> framer('Hello, World!')
[[[0, 1, 0, 0, 1, 0, 0, 0],
[0, 1, 1, 0, 0, 1, 0, 1],
[0, 1, 1, 0, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 0, 0],
[0, 1, 1, 0, 1, 1, 1, 1],
[0, 0, 1, 0, 1, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 1, 1]],
[[0, 1, 1, 0, 1, 1, 1, 1],
[0, 1, 1, 1, 0, 0, 1, 0],
[0, 1, 1, 0, 1, 1, 0, 0],
[0, 1, 1, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 1, 1, 0, 1],
[0, 0, 1, 0, 1, 1, 0, 1],
[0, 0, 1, 0, 1, 1, 0, 1]]]
Non-ascii characters require multiple bits to encode.
>>> framer('💩', padding='\x00')
[[[1, 1, 1, 1, 0, 0, 0, 0],
[1, 0, 0, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 0, 0, 1, 0],
[1, 0, 1, 0, 1, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]]]
Upvotes: 1
Reputation: 8740
You can use below code to achieve your goal.
def segment_string(s, fill_by):
l = []
while s:
if len(s) < 8:
s = s + (fill_by) * (8 - len(s))
l.append(s[0:8])
s = s[8:]
return l # ['Hello, W', 'orld!---']
def char2bin(ch):
a = bin(ord(ch))[2:]
l = [int(c) for c in a]
if len(l) < 8:
l = ([0] * (8 - len(l))) + l # Adding extra 0s to front (if len(l) < 8)
return l # [0, 1, 0, 0, 1, 0, 0, 0]
def framer(s, fill_by='-'):
segments = segment_string(s, fill_by) # Calling segment_string()
print(segments)
arr = []
for segment in segments:
arr2 = []
for ch in segment:
arr3 = char2bin(ch); # Calling char2bin()
arr2.append(arr3)
arr.append(arr2)
return arr # final list to be returned
if __name__ == "__main__":
f = framer('Hello, World!', '~')
print(f)
Output »
[[[0, 1, 0, 0, 1, 0, 0, 0], [0, 1, 1, 0, 0, 1, 0, 1], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 1, 1, 1, 1], [0, 0, 1, 0, 1, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 1, 1, 1]], [[0, 1, 1, 0, 1, 1, 1, 1], [0, 1, 1, 1, 0, 0, 1, 0], [0, 1, 1, 0, 1, 1, 0, 0], [0, 1, 1, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1], [0, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1, 1, 0]]]
# >>> bin(126)
# '0b1111110'
# >>>
# >>> chr(126)
# '~'
# >>>
Upvotes: 0
Reputation: 74
You could either use list comprehensions or make use of the itertools
module.
You can learn more about list comprehensions here, and more about itertootls here.
Upvotes: 0