Search code examples
pythonjsoni2c

Unicode to ASCII string in Python 2


Trying to make a wall display of current MET data for a selected airport. This is my first use of a Raspberry Pi 3 and of Python.
The plan is to read from a net data provider and show selected data on a LCD display.

The LCD library seems to work only in Python2. Json data seems to be easier to handle in Python3.

This question python json loads unicode probably adresses my problem, but I do not anderstand what to do.

So, what shall I do to my code?

Minimal example demonstrating my problem:

#!/usr/bin/python
import I2C_LCD_driver
import urllib2
import urllib
import json

mylcd = I2C_LCD_driver.lcd()

mylcd.lcd_clear()

url = 'https://avwx.rest/api/metar/ESSB'
request = urllib2.Request(url)
response = urllib2.urlopen(request).read()
data = json.loads(response)

str1 = data["Altimeter"], data["Units"]["Altimeter"]

mylcd.lcd_display_string(str1, 1, 0)

The error is as follows:

$python Minimal.py
Traceback (most recent call last):
  File "Minimal.py", line 18, in <module>
    mylcd.lcd_display_string(str1, 1, 0)
  File "/home/pi/I2C_LCD_driver.py", line 161, in lcd_display_string
    self.lcd_write(ord(char), Rs)
TypeError: ord() expected a character, but string of length 4 found

Solution

  • It's a little bit hard to tell without seeing the inside of mylcd.lcd_display_string(), but I think the problem is here:

    str1 = data["Altimeter"], data["Units"]["Altimeter"]
    

    I suspect that you want str1 to contain something of type string, with a value like "132 metres". Try adding a print statement just after, so that you can see what str1 contains.

    str1 = data["Altimeter"], data["Units"]["Altimeter"]
    print( "str1 is: {0}, of type {1}.".format(str1, type(str1)) )
    

    I think you will see a result like:

    str1 is: ('foo', 'bar'), of type <type 'tuple'>.
    

    The mention of "type tuple", the parentheses, and the comma indicate that str1 is not a string.

    The problem is that the comma in the print statement does not do concatenation, which is perhaps what you are expecting. It joins the two values into a tuple. To concatenate, a flexible and sufficient method is to use the str.format() method:

    str1 = "{0} {1}".format(data["Altimeter"], data["Units"]["Altimeter"])
    print( "str1 is: {0}, of type {1}.".format(str1, type(str1)) )
    

    Then I expect you will see a result like:

    str1 is: 132 metres, of type <type 'str'>.
    

    That value of type "str" should work fine with mylcd.lcd_display_string().