Search code examples
pythonstringpython-2.7non-printing-characters

neutralize non-visible ASCII characters for printing ASCII table


I'm trying to write a short script (for a tutorial) to show which of the first 128 ASCII characters are printable, recognizable characters.

The following script using `is in string.printable' partially works, but is still triggering off of things like line feeds, etc.

Is there one or two more lines I can add to trap and replace these control characters with spaces so that the table looks nice and shows printable characters?

Written out longhand for noob-readability:

import string
lines = []
for i in range(8):
    line = []
    for j in range(16):
        k = i + j *16
        thing = chr(k)
        if thing not in string.printable:
            thing = ' '
        line.append(thing)
    lines.append(line)

for line in lines:
    print "".join(line)

IDLE:

enter image description here

Copy/paste into SE including four spaces:

   0@P`p
  !1AQaq
  "2BRbr
  #3CScs
  $4DTdt
  %5EUeu
  &6FVfv
  '7GWgw
  (8HXhx
         )9IYiy

 *:JZjz
 +;K[k{
 ,<L\l|

-=M]m} .>N^n~ /?O_o


Solution

  • Updated code to replace unprintable characters as per OP's comment.

    from string import printable, whitespace
    
    replace_ch = ' '  # The character to replace non-printable characters with
    whitespace_ch = ' '  # The character to replace whitespace characters with
    
    # For console output
    out_width = 8
    out_height = 16
    
    chars = [chr(i) for i in range(128)]
    # Replace whitespace characters
    chars = [whitespace_ch if c in whitespace else c for c in chars]
    # Replace non-printable characters
    chars = [c if c in printable else replace_ch for c in chars]
    # Form lines for printing
    lines = [[chars[i + j * out_height] for j in range(out_width)] for i in range(out_height)]
    
    for line in lines:
        print(''.join(line))
    

    Outputs:

       0@P`p
      !1AQaq
      "2BRbr
      #3CScs
      $4DTdt
      %5EUeu
      &6FVfv
      '7GWgw
      (8HXhx
      )9IYiy
      *:JZjz
      +;K[k{
      ,<L\l|
      -=M]m}
      .>N^n~
      /?O_o
    

    An alternative is to simply avoid the first 32 characters of ASCII as they are defined as control characters. It may be more efficient to check the ord(c) of a character, c.