Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a JSON string | TypeError: string indices must be integers

I'm trying to create a program that will read in a JSON string through the GUI and then use this to perform additional functions, in this case breaking down a mathematical equation. At the moment I am getting the error:

"TypeError: string indices must be integers"

and I have no idea why.

The JSON I am trying to read in is as follows:

{
"rightArgument":{
"cell":"C18",
"value":9.5,
"type":"cell"
},
"leftArgument":{
"rightArgument":{
"cell":"C3",
"value":135,
"type":"cell"
},
"leftArgument":{
"rightArgument":{
"cell":"C4",
"value":125,
"type":"cell"
},
"leftArgument":{
"cell":"C5",
"value":106,
"type":"cell"
},
"type":"operation",
"operator":"*"
},
"type":"operation",
"operator":"+"
},
"type":"operation",
"operator":"+"
}
import json
import tkinter
from tkinter import *

data = ""
list = []

def readText():
    mtext=""
    mtext = strJson.get()
    mlabel2 = Label(myGui,text=mtext).place(x=180,y=200)
    data = mtext

def mhello():
    _getCurrentOperator(data)

def _getCurrentOperator(data):
    if data["type"] == "operation":

        _getCurrentOperator(data["rightArgument"])        
        _getCurrentOperator(data["leftArgument"]) 
        list.append(data["operator"])
    elif data["type"] == "group":
        _getCurrentOperator(data["argument"]) 
    elif data["type"] == "function":
        list.append(data["name"]) # TODO do something with arguments
        for i in range(len(data["arguments"])):
            _getCurrentOperator(data["arguments"][i])
    else:
        if (data["value"]) == '':
            list.append(data["cell"])
        else:
            list.append(data["value"])

print(list)

myGui = Tk()
strJson = StringVar()


myGui.title("Simple Gui")
myGui.geometry("400x300")

label = Label(text = 'Welcome!').place(x=170,y=40)
btnStart = Button(myGui,text='Start',command=mhello).place(x=210,y=260)
btnRead = Button(myGui,text='Read text',command=readText).place(x=210,y=200)
txtEntry = Entry(myGui, textvariable=strJson).place(x=150,y=160)
btnOptions = Button(myGui, text = "Options").place(x=150,y=260)

myGui.mainloop()
like image 269
Billy Dawson Avatar asked Jan 08 '15 11:01

Billy Dawson


People also ask

How do you resolve string indices must be integers?

1 comment. String indices must be integers. This means that when you're accessing an iterable object like a string, you must do it using a numerical value. If you are accessing items from a dictionary, make sure that you are accessing the dictionary itself and not a key in the dictionary.

How do I fix error string indices must be integers in python?

The Python "TypeError: string indices must be integers" occurs when we use a non-integer value to access a string at an index. To solve the error, make sure to use an integer, e.g. my_str[2] or a slice, e.g. my_str[0:3] when accessing a string at a specific index.

How do you parse a JSON string in Python?

Parse JSON - Convert from JSON to Python If you have a JSON string, you can parse it by using the json. loads() method. The result will be a Python dictionary.


3 Answers

You are never parsing the string to a dictionary (json object). Change data = mtext to: data = json.loads(mtext) You should also add global data to the readText method

like image 179
Vincent Beltman Avatar answered Sep 29 '22 01:09

Vincent Beltman


TypeError: string indices must be integers means an attempt to access a location within a string using an index that is not an integer. In this case your code (line 18) is using the string "type" as an index. As this is not an integer, a TypeError exception is raised.

It seems that your code is expecting data to be a dictionary. There are (at least) 3 problems:

  1. You are not decoding ("loading") the JSON string. For this you should use json.loads(data) in the readText() function. This will return the dictionary that your code expects elsewhere.
  2. data is a global variable with value initialised to an empty string (""). You can not modify a global variable within a function without first declaring the variable using the global keyword.
  3. The code builds a list by appending successive items to it, however, that list is not used elsewhere. It is printed after the definition of _getCurrentOperator() but this is before any processing has been done, hence it is still empty at that point and [] is displayed. Move print(list) to mhello() after_getCurrentOperator(). (BTW using list as a variable name is not advised as this shadows the builtin list)

You can revise readText() to this:

def readText():
    global data
    mtext=""
    mtext = strJson.get()
    mlabel2 = Label(myGui,text=mtext).place(x=180,y=200)
    data = json.loads(mtext)
like image 27
mhawke Avatar answered Sep 29 '22 01:09

mhawke


sometimes you need to use json.loads again.. this worked for me..

jsonn_forSaleSummary_string = json.loads(forSaleSummary)  //still string
jsonn_forSaleSummary        = json.loads(jsonn_forSaleSummary_string)

finally!! json

like image 43
Brian Sanchez Avatar answered Sep 29 '22 01:09

Brian Sanchez