skip to Main Content

I’m working on a project for a Intro to programming logic class for school where we are reading in information from a .txt file, reformatitng it to JSON format and then writing that JSON format to a new .txt file while also printing the JSON formatted data to the screen.

I’m having an issue where my JSON key value pairs are putting quotes on data types that do not need quotes, such as integers and booleans.

def main():
    runtimeManager = RuntimeManager()
    jsonResult = runtimeManager.run()
    outputFileName=runtimeManager.outputFilename
    print(jsonResult)
    print("nOutput written to " +outputFileName+ ".")

class RuntimeManager:

    def run(self):
        ## Gather required member variables
        self.getUserInputFileName()
        self.getUserOutputFileName()

        ##Grabbing user file and extracting the CSV
        with open(self.inputFilename) as inputFile:
            jsonResult = CsvToJson(inputFile.readlines()).transformCsvToJson()
            with open(self.outputFilename, "w") as outputFile:
                outputFile.write(jsonResult)
            return jsonResult


    def getUserInputFileName(self):
        ## Prompt User for 
        self.inputFilename = input("Enter the filename:  ").strip()

    def getUserOutputFileName(self):
        self.outputFilename = input("Enter the OUTPUT filename:  ").strip()



class CsvToJson():

    def __init__(self, csv):
        self.csv = csv
        self.headers = csv[0].strip()
        self.data = csv[1:]

    def transformCsvToJson(self):
        jsonResult = "{"
        for i in range(0, len(self.data)):
            if (i != 0):
                jsonResult = jsonResult + "n,"
            jsonResult = jsonResult + """ + str(i+1) + "":" + self.createJsonObject(self.headers, self.data[i])
        return jsonResult + "n}"

    def createJsonObject(self, headers, csvRow):
        csvKeyArray = headers.split(",")
        csvValueArray = csvRow.strip().split(",")
        jsonObject = "{"
        for i in range(0, len(csvKeyArray)):
            jsonField = ""
            if (i != 0):
                jsonField = ","
            jsonField = jsonField + """ + str(csvKeyArray[i]) + "":" + self.getValueDataType(csvValueArray[i])
            jsonObject = jsonObject + jsonField
        return jsonObject + "}"

    def getValueDataType(self, value):
        if (type(value) == int):
            value = str(value)
        elif (type(value) == str):
            value = """ + value + """
        elif (type(value) == bool):
            if (value):
                value = "true"
            else:
                value = "false"
        elif (type(value) == null):
            value = "null"
        else:
            value = "ERROR"

        return value


if (__name__ == "__main__"):
    main()

I’ve put my program in here with line numbers. The stipulations of my assignment dictate that we are not permitted to use the JSON module built into python.

the issue I’m having is my JSON formatting looks like this:

{"1":{"Last Name":"Minion","First Name":"Bob","Preferred Name":"Bob","Preferred Pronoun":"he/him","SF ID #":"2211-4456","Program Code":"3504","Phone":"910-432-8765","Email":"[email protected]"}

and it should look like this:

{"1":{"Last Name":"Minion","First Name":"Bob","Preferred Name":"Bob","Preferred Pronoun":"he/him","SF ID #":"2211-4456","Program Code":3504,"Phone":"910-432-8765","Email":"[email protected]"}

with the quotes not being on the code in the Program Code:3504 key value pair, and I can’t figure out why the quotes are being placed on it.

example input file content looks like this:

Last Name,First Name,Preferred Name,Preferred Pronoun,SF ID #,Program Code,Phone,Email
Minion,Bob,Bob,he/him,2211-4456,3504,910-432-8765,[email protected]
Nichols,James,James,,1234-5678,3651,352-395-5220,[email protected]
Person,Punny,,,9999-1111,3840,352-123-4567,[email protected]
Person,Punny2,,,9999-1112,3841,352-123-6792,[email protected]
Person,Punny3,,,9999-1113,3842,352-123-3420,[email protected]
Smart,Maxwell,Max,,9922-4029,3650,310-2910,[email protected]
Tree,Groot,Groot,,1122-3344,3624,361-1234-5678,[email protected]

2

Answers


  1. Here is an example how you can produce valid json from the input you’ve provided (but beware: there are many caveats and shortcuts, without using csv/json modules it will be hard to cover all cases and inputs):

    tpl = """
    "{}": {{"Last Name":{},"First Name":{},"Preferred Name":{},"Preferred Pronoun":{},"SF ID #":{},"Program Code":{},"Phone":{},"Email":{}}}"""
    
    
    def format_val(val):
        if val == "":
            return "null"
        elif isinstance(val, str):
            return f'"{val}"'
        elif isinstance(val, (int, float)):
            return val
        elif isinstance(val, bool):
            return "true" if val else "false"
    
        raise ValueError(f"Unknown value type {val}")
    
    
    all_rows = []
    with open("file.csv", "r") as f_in:
        for line in map(str.strip, f_in):
            if f_in == "":
                continue
            row = list(map(str.strip, line.split(",")))
            all_rows.append(row)
    
    
    final_json = []
    for i, row in enumerate(all_rows[1:], 1):
        row[5] = int(row[5])
        final_json.append(tpl.format(i, *map(format_val, row)))
    
    final_json = "{" + ",n".join(final_json) + "}"
    print(final_json)
    

    Prints:

    {"1": {"Last Name":"Minion","First Name":"Bob","Preferred Name":"Bob","Preferred Pronoun":"he/him","SF ID #":"2211-4456","Program Code":3504,"Phone":"910-432-8765","Email":"[email protected]"},
    "2": {"Last Name":"Nichols","First Name":"James","Preferred Name":"James","Preferred Pronoun":null,"SF ID #":"1234-5678","Program Code":3651,"Phone":"352-395-5220","Email":"[email protected]"},
    "3": {"Last Name":"Person","First Name":"Punny","Preferred Name":null,"Preferred Pronoun":null,"SF ID #":"9999-1111","Program Code":3840,"Phone":"352-123-4567","Email":"[email protected]"},
    "4": {"Last Name":"Person","First Name":"Punny2","Preferred Name":null,"Preferred Pronoun":null,"SF ID #":"9999-1112","Program Code":3841,"Phone":"352-123-6792","Email":"[email protected]"},
    "5": {"Last Name":"Person","First Name":"Punny3","Preferred Name":null,"Preferred Pronoun":null,"SF ID #":"9999-1113","Program Code":3842,"Phone":"352-123-3420","Email":"[email protected]"},
    "6": {"Last Name":"Smart","First Name":"Maxwell","Preferred Name":"Max","Preferred Pronoun":null,"SF ID #":"9922-4029","Program Code":3650,"Phone":"310-2910","Email":"[email protected]"},
    "7": {"Last Name":"Tree","First Name":"Groot","Preferred Name":"Groot","Preferred Pronoun":null,"SF ID #":"1122-3344","Program Code":3624,"Phone":"361-1234-5678","Email":"[email protected]"}}
    
    Login or Signup to reply.
  2. All values from a split CSV line are type str which is why you get quotes around everything. You could write a coerce function that tests if the string can be converted to int:

        def coerce(value):
            try:
                return int(value)
            except ValueError:
                return value
                
        def getValueDataType(self, value):
            value = self.coerce(value)
            if (type(value) == int):
                value = str(value)
            ...
    

    I’ll leave it as an exercise to coerce bool and null.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search