Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python print Unicode character

Tags:

python

unicode

I'm making a card game, but I've run into what seems to be an encoding issue. I'm trying to print a card like this:

def print(self):
    print("|-------|")
    print("| %s     |" % self.value)
    print("|       |")
    print("|   %s   |" % self.suit.encode("utf-8"))
    print("|       |")
    print("|    %s  |" % self.value)
    print("|-------|")

This is what I want:

|-------|
| 10    |
|       |
|   ♦   |
|       |
|    10 |
|-------|

...but this is what I get:

|-------|
| 10    |
|       |
|   b'\xe2\x99\xa6'   |
|       |
|    10 |
|-------|

I'm on Windows and Python 3 if that matters.

The value of self.suit can be any of the following:

spade = "♠"
heart = "♥"
diamond = "♦"
club = "♣"

If I remove the .encode("utf-8") I get this error:

Traceback (most recent call last):

  File "main.py", line 79, in <module>
    start()
  File "main.py", line 52, in start
    play()
  File "main.py", line 64, in play
    card.print()
  File "main.py", line 36, in print
    print("|   \u2660   |")
  File "C:\Python34\lib\encodings\cp850.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2660' in position
4: character maps to <undefined>
like image 649
Wahoozel Avatar asked Jun 23 '15 19:06

Wahoozel


People also ask

How do I print a Unicode character in Python?

Use the "\u" escape sequence to print Unicode characters In a string, place "\u" before four hexadecimal digits that represent a Unicode code point. Use print() to print the string.

How do you print symbols in Python?

To print any character in the Python interpreter, use a \u to denote a unicode character and then follow with the character code. For instance, the code for β is 03B2, so to print β the command is print('\u03B2') . There are a couple of special characters that will combine symbols.

Does Python support Unicode?

Python's string type uses the Unicode Standard for representing characters, which lets Python programs work with all these different possible characters. Unicode (https://www.unicode.org/) is a specification that aims to list every character used by human languages and give each character its own unique code.


1 Answers

This takes advantage of the fact that the OEM code pages in the Windows console print some visible characters for control characters. The card suits for cp437 and cp850 are chr(3)-chr(6). Python 3 (prior to 3.6) won't print the Unicode character for a black diamond, but it's what you get for U+0004:

>>> print('\N{BLACK DIAMOND SUIT}')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python33\lib\encodings\cp437.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2666' in position 0: character maps to <undefined>
>>> print(chr(4))
♦

Therefore:

#!python3
#coding: utf8
class Card:
    def __init__(self,value,suit):
        self.value = value
        self.suit = suit    # 1,2,3,4 = ♥♦♣♠

    def print(self):
        print("┌───────┐")
        print("| {:<2}    |".format(self.value))
        print("|       |")
        print("|   {}   |".format(chr(self.suit+2)))
        print("|       |")
        print("|    {:>2} |".format(self.value))
        print("└───────┘") 

Output:

>>> x=Card('K',4)
>>> x.print()
┌───────┐
| K     |
|       |
|   ♠   |
|       |
|     K |
└───────┘
>>> x=Card(10,3)
>>> x.print()
┌───────┐
| 10    |
|       |
|   ♣   |
|       |
|    10 |
└───────┘

Python 3.6 Update

Python 3.6 uses Windows Unicode APIs to print so no need for the control character trick now, and the new format strings can be used:

#!python3.6
#coding: utf8
class Card:
    def __init__(self,value,suit):
        self.value = value
        self.suit = '♥♦♣♠'[suit-1] # 1,2,3,4 = ♥♦♣♠

    def print(self):
        print('┌───────┐')
        print(f'| {self.value:<2}    |')
        print('|       |')
        print(f'|   {self.suit}   |')
        print('|       |')
        print(f'|    {self.value:>2} |')
        print('└───────┘') 

Output:

>>> x=Card('10',3)
>>> x.print()
┌───────┐
| 10    |
|       |
|   ♣   |
|       |
|    10 |
└───────┘
like image 165
Mark Tolonen Avatar answered Sep 28 '22 02:09

Mark Tolonen