import optparse
import os 
import sys 

def main():
    parser = optparse.OptionParser(usage='usage --> %prog [options] file1 [file2 [... fileN]]')
    parser.add_option('-b', '--blocksize', dest='blocksize', type='int', help='size (8..80) [default: %default]')
    parser.add_option('-d', '--decimal', dest='decimal', action='store_true', help='decimal block[default: hexadecimal')
    parser.add_option('-e', '--encoding', dest='encoding', help='encoding [default: %default]')
    parser.set_defaults(blocksize=16, decimal=False, encoding='UTF-8')
    opts, files = parser.parse_args()
    if not (8 <= opts.blocksize <= 80):
        parser.error('invalid blocksize')
    if not files:
        parser.error('no files specified')
    for i, filename in enumerate(files):
        if i :
        if len(files) > 1:
            print('File --> ', filename)
        xdump(filename, opts.blocksize, opts.encoding, opts.decimal)

def xdump(filename: str, blocksize: bytes, encoding: str, decimal: bytes) -> None:
    encoding_text = f'{encoding.upper()} characters'
    width = (blocksize * 2) + (blocksize // 4) 
    if blocksize % 4:
        width += 1
    print('Block     Bytes {0:{1}} {2}'.format('', (width - 5), encoding_text))
    print('-------- {0}   {1}'.format('-' * (width - 1), '-' * max(len(encoding_text), blocksize)))
    block_number_format = '{0:08} ' if decimal else '{0:08X} '
    block_number = 0
    fh = None
        fh = open(filename, 'rb')
        while True:
            data = fh.read(blocksize)
            if not data:
            line = [block_number_format.format(block_number)]
            chars = []
            for i, b in enumerate(data):
                if i % 4 == 0:
                    line.append(' ')
                chars.append(b if 32 <= b < 127 else ord('.'))
            for i, in range(len(data), blocksize):
                if i % 4 == 0:
                    line.append(' ')
                line.append('  ')
            line.append('  ')
            line.append(bytes(chars).decode(encoding, 'replace').replace('\uFFF0', '.'))
            block_number += 1
    except EnvironmentError as err:
        if fh is not None:

Share a link to this review

6.15% issue ratio

O23 Calculated multiple times

Calculating something multiple times is redundant - use variables to store result of some calculation.

R41 Too many lines of code

Functions should be small - at least fit your screen's height. Otherwise they will be hard to read and hard to test. Try splitting big function into smaller ones.

O15 Using print()

print() is a nice way to output to stdout. But one day you'll need to not only write to stdout, but also, say, to a file. Another day you'll need to output only severe errors' messages, and nothing else. This all could be solved if using logging module. Usually it's as easy as from logging import getLogger; log = getLogger(__name__).

L42 Too big "try" block

You should include as few lines of code inside try block as possible. First, you may accidentally catch exceptions from lines which you didn't want to be caught. Second, the smaller try ... except blocks are, the less cognitive load it makes.

Create new review request