A unique question I guess, given these unciode block elements:
https://en.wikipedia.org/wiki/Block_Elements
I want to get the relevant block element based on the matrix I get, so
11
01 will give ▜
00
10 will give ▖
and so on
I managed to do this in python, but I wonder if anyone got a more elegant solution.
from itertools import product
elements = [0, 1]
a = product(elements, repeat=2)
b = product(a, repeat=2)
matrices = [c for c in b]
"""
Matrices generated possiblities
00 00 00 00 01 01 01 01 10 10 10 10 11 11 11 11
00 01 10 11 00 01 10 11 00 01 11 10 00 01 10 11
"""
blocks = [' ', '▗', '▖', '▄', '▝', '▐', '▞', '▟', '▘', '▚', '▙', '▌', '▀', '▜', '▛', '█']
given = (
(0,1),
(1,0)
)
print(blocks[matrices.index(given)])
output: ▞
These characters, although existing, were not meant to have a direct correlation
of numbers-to-set-1/4 blocks.
So, I have a solution in a published package, and it is not necessarily
more "elegant" than yours, as it is far more verbose.
However, the code around it allows one to "draw" on a text terminal
using these 1/4 blocks as pixels, in a somewhat clean API.
So, this is the class I use to set/reset pixels in a character block. The relevant methods can be used straight from the class, and they take the"pixel coordinates", and the current character block upon which to set or reset the addressed pixel. The code instantiates the class just to be able to use the in operator to check for block-characters.
The project can be installed with "pip install terminedia".
The function and class bellow, extracted from the project, will work in standalone to do the same as you do:
# Snippets from jsbueno/terminedia, v. 0.2.0
def _mirror_dict(dct):
"""Creates a new dictionary exchanging values for keys
Args:
- dct (mapping): Dictionary to be inverted
"""
return {value: key for key, value in dct.items()}
class BlockChars_:
"""Used internaly to emulate pixel setting/resetting/reading inside 1/4 block characters
Contains a listing and other mappings of all block characters used in order, so that
bits in numbers from 0 to 15 will match the "pixels" on the corresponding block character.
Although this class is purposed for internal use in the emulation of
a higher resolution canvas, its functions can be used by any application
that decides to manipulate block chars.
The class itself is stateless, and it is used as a single-instance which
uses the name :any:`BlockChars`. The instance is needed so that one can use the operator
``in`` to check if a character is a block-character.
"""
EMPTY = " "
QUADRANT_UPPER_LEFT = '\u2598'
QUADRANT_UPPER_RIGHT = '\u259D'
UPPER_HALF_BLOCK = '\u2580'
QUADRANT_LOWER_LEFT = '\u2596'
LEFT_HALF_BLOCK = '\u258C'
QUADRANT_UPPER_RIGHT_AND_LOWER_LEFT = '\u259E'
QUADRANT_UPPER_LEFT_AND_UPPER_RIGHT_AND_LOWER_LEFT = '\u259B'
QUADRANT_LOWER_RIGHT = '\u2597'
QUADRANT_UPPER_LEFT_AND_LOWER_RIGHT = '\u259A'
RIGHT_HALF_BLOCK = '\u2590'
QUADRANT_UPPER_LEFT_AND_UPPER_RIGHT_AND_LOWER_RIGHT = '\u259C'
LOWER_HALF_BLOCK = '\u2584'
QUADRANT_UPPER_LEFT_AND_LOWER_LEFT_AND_LOWER_RIGHT = '\u2599'
QUADRANT_UPPER_RIGHT_AND_LOWER_LEFT_AND_LOWER_RIGHT = '\u259F'
FULL_BLOCK = '\u2588'
# This depends on Python 3.6+ ordered behavior for local namespaces and dicts:
block_chars_by_name = {key: value for key, value in locals().items() if key.isupper()}
block_chars_to_name = _mirror_dict(block_chars_by_name)
blocks_in_order = {i: value for i, value in enumerate(block_chars_by_name.values())}
block_to_order = _mirror_dict(blocks_in_order)
def __contains__(self, char):
"""True if a char is a "pixel representing" block char"""
return char in self.block_chars_to_name
#classmethod
def _op(cls, pos, data, operation):
number = cls.block_to_order[data]
index = 2 ** (pos[0] + 2 * pos[1])
return operation(number, index)
#classmethod
def set(cls, pos, data):
""""Sets" a pixel in a block character
Args:
- pos (2-sequence): coordinate of the pixel inside the character
(0,0) is top-left corner, (1,1) bottom-right corner and so on)
- data: initial character to be composed with the bit to be set. Use
space ("\x20") to start with an empty block.
"""
op = lambda n, index: n | index
return cls.blocks_in_order[cls._op(pos, data, op)]
#classmethod
def reset(cls, pos, data):
""""resets" a pixel in a block character
Args:
- pos (2-sequence): coordinate of the pixel inside the character
(0,0) is top-left corner, (1,1) bottom-right corner and so on)
- data: initial character to be composed with the bit to be reset.
"""
op = lambda n, index: n & (0xf - index)
return cls.blocks_in_order[cls._op(pos, data, op)]
#classmethod
def get_at(cls, pos, data):
"""Retrieves whether a pixel in a block character is set
Args:
- pos (2-sequence): The pixel coordinate
- data (character): The character were to look at blocks.
Raises KeyError if an invalid character is passed in "data".
"""
op = lambda n, index: bool(n & index)
return cls._op(pos, data, op)
#: :any:`BlockChars_` single instance: enables ``__contains__``:
BlockChars = BlockChars_()
After pasting only this in the terminal it is possible to do:
In [131]: pixels = BlockChars.set((0,0), " ")
In [132]: print(BlockChars.set((1,1), pixels))
# And this internal "side-product" is closer to what you have posted:
In [133]: BlockChars.blocks_in_order[0b1111]
Out[133]: '█'
In [134]: BlockChars.blocks_in_order[0b1010]
Out[134]: '▐'
The project at https://github.com/jsbueno/terminedia have a complete
drawing API do use these as pixels in an ANSI text terminal -
including bezier curves, filled ellipses, and RGB image display
(check the "examples" folder)
I am new to python so please forgive me if I'm asking a dumb question. In my function I generate a random byte array for a given number of bytes called "input_data", then I add bytewise some bit errors and store the result in another byte array called "output_data". The print function shows that it works exactly as expected, there are different bytes. But if I compare the byte arrays afterwards they seem to be identical!
def simulate_ber(packet_length, ber, verbose=False):
# generate input data
input_data = bytearray(random.getrandbits(8) for _ in xrange(packet_length))
if(verbose):
print(binascii.hexlify(input_data)+" <-- simulated input vector")
output_data = input_data
#add bit errors
num_errors = 0
for byte in range(len(input_data)):
error_mask = 0
for bit in range(0,7,1):
if(random.uniform(0, 1)*100 < ber):
error_mask |= 1 << bit
num_errors += 1
output_data[byte] = input_data[byte] ^ error_mask
if(verbose):
print(binascii.hexlify(output_data)+" <-- output vector")
print("number of simulated bit errors: " + str(num_errors))
if(input_data == output_data):
print ("data identical")
number of packets: 1
bytes per packet: 16
simulated bit error rate: 5
start simulation...
0d3e896d61d50645e4e3fa648346091a <-- simulated input vector
0d3e896f61d51647e4e3fe648346001a <-- output vector
number of simulated bit errors: 6
data identical
Where is the bug? I am sure the problem is somewhere between my ears...
Thank you in advance for your help!
output_data = input_data
Python is a referential language. When you do the above, both variables now refer to the same object in memory. e.g:
>>> y=['Hello']
>>> x=y
>>> x.append('World!')
>>> x
['Hello', 'World!']
>>> y
['Hello', 'World!']
Cast output_data as a new bytearray and you should be good:
output_data = bytearray(input_data)
I imported a cvs file and have a variable 'departure time' in my sas file that consists of four digits, e.g. 0856 for 08.56 AM. I would like SAS to recognise it as time and want it to appear as 08:56. I have tried:
put DEP_TIME hhmm5.;
format DEP_TIME hhmm5.;
Doesn't work. Can't seem to figure this out.
Any clues?
Informat B8601TM.
33 data _null_;
34 t='0856';
35 time = input(t,B8601TM.);
36 format time time.;
37 put 'NOTE: ' (_all_)(=);
38 run;
NOTE: t=0856 time=8:56:00
I don't think there's an informat which will convert a 4-digit string to a time.
There's a couple of ways to do this, either using hms() and substr() functions, or a custom picture format :
proc format ;
picture TM
low-high = '00:00' ;
run ;
data want ;
set have ;
/* hms and substr method */
new_time1 = hms(substr(dep_time,1,2),substr(dep_time,3,2)) ;
format new_time1 hhmm5. ;
/* input / put with picture format */
new_time2 = input(put(input(dep_time,4.),tm.),time5.) ;
format new_time2 hhmm5. ;
run ;
I have a .bin file, and I want to simply byte reverse the hex data. Say for instance # 0x10 it reads AD DE DE C0, want it to read DE AD C0 DE.
I know there is a simple way to do this, but I am am beginner and just learning python and am trying to make a few simple programs to help me through my daily tasks. I would like to convert the whole file this way, not just 0x10.
I will be converting at start offset 0x000000 and blocksize/length is 1000000.
EDIT:
here is my code, maybe you can tell me where i am messing up.
def main():
infile = open("file.bin", "rb")
new_pos = int("0x000000", 16)
chunk = int("1000000", 16)
data = infile.read(chunk)
save(data)
def save(data):
with open("reversed", "wb") as outfile:
outfile.write(data)
main()
how would i go about coding it to byte reverse from CDAB TO ABCD?
if it helps any the file is exactly 16MB
You can just swap the bytes manually like this:
with open("file.bin", "rb") as infile, open("reversed", "wb") as outfile:
data = infile.read()
for i in xrange(len(data) / 2):
outfile.write(data[i*2+1])
outfile.write(data[i*2])
I'm trying to convert an int into a byte in Processing 1.0.9.
This is the snippet of code that I have been working with:
byte xByte = byte(mouseX);
byte yByte = byte(mouseY);
byte setFirst = byte(128);
byte resetFirst = byte(127);
xByte = xByte | setFirst;
yByte = yByte >> 1;
port.write(xByte);
port.write(yByte);
According to the Processing API, this should work, but I keep getting an error at xByte = xByte | setFirst; that says:
cannot convert from int to byte
I have tried converting 128 and 127 to they respective hex values (0x80 and 0x7F), but that didn't work either. I have tried everything mentioned in the API as well as some other blogs, but I feel like I'm missing something very trivial.
I would appreciate any help.
Thank you.
I've never used Processing before, but it's possible the | operator returns an integer regardless of the arguments' types. Try changing the problematic line to
xByte = byte(xByte | setFirst);