Avoiding decimals when parsing json

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
Post Reply
User avatar
dhallgb
Posts: 7
Joined: Tue Oct 04, 2016 3:24 pm

Avoiding decimals when parsing json

Post by dhallgb » Thu Oct 13, 2016 7:29 pm

When parsing the return from a weather service using the ujson module I get an error:
ValueError: decimal numbers not supported
Whilst I can use the round() function to return integers once I have the values, how can I avoid the parser throwing an error?

Code: Select all

pt1 = "http://api.openweathermap.org/data/2.5/weather?id="
pt2 = "&units=metric&appid="
url = pt1+cfg["Openweathercity"]+pt2+cfg["OpenWeatherAPI"]
req = urlopen(url)
weather = req.read()
weather_json = ujson.loads(weather.decode("utf-8"))
The OpenWeatherMap service can return XML and I could parse that with xmltok.
Would that be any better - or should I just manually slice it up and get the integers I need?

jgmdavies
Posts: 57
Joined: Tue Aug 09, 2016 2:39 pm

Re: Avoiding decimals when parsing json

Post by jgmdavies » Sun Oct 16, 2016 6:43 pm

I also used that weather source a while ago and ended up just 'slicing' the json response, as you say, e.g. something like:

Code: Select all

from WiPyFloat import *

		api_key = "YOUR_API_KEY"
		url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&APPID=" + api_key

		resp = urequests.get(url)

		if (resp.status_code != 200):
			print("Bad response from GET to: " + url + ", status code " + str(resp.status_code) + " (" + resp.reason + ")")
			return None

		content = resp.text
		print(content)

		index = content.find('"temp":')
		if (index < 0):
			print("No temperature found in response from: " + url)
			return None

		index += 7
		index2 = content.find(",", index)
		if (index < 0):
			print("No temperature found in response from: " + url)
			return None

		s = content[index:index2]
		print(s)

		index = s.find(",")
		if (index > 0):
			s = s[:index]

		temp = Float(s) - Float("273.15")
		print ("temp=", temp)
I used my WiPyFloat package for floating point support ( http://forum.micropython.org/viewtopic.php?f=11&t=2332 ). If you just want ints, you can change the last part to something like:

Code: Select all

		index = s.find(".")
		if (index > 0):
			s = s[:index]

		temp = int(s) - 273
		print ("temp=", temp)
HTH
Jim

User avatar
dhallgb
Posts: 7
Joined: Tue Oct 04, 2016 3:24 pm

Re: Avoiding decimals when parsing json

Post by dhallgb » Sun Oct 16, 2016 7:06 pm

Thanks Jim, that sounds a really good idea. I've been going down the route of the parse_float handler and still encountering problems with argument num/types mismatch in the call.

Code: Select all

ujson.loads(weather_str, parse_float=parseFloat)
Doing it manually like your code sounds a lot less painful, I'll give it a try.

jgmdavies
Posts: 57
Joined: Tue Aug 09, 2016 2:39 pm

Re: Avoiding decimals when parsing json

Post by jgmdavies » Thu Oct 20, 2016 3:37 pm

Alternatively, you could consider getting a WiPy2, which supports floating point and has somewhat more free memory. :D

Post Reply