skip to Main Content

I am using the python json module to generate test data for a javascript program. numerical data produces the expected "name": value output but strings are being wrapped into lists like ** "name" : [ "value"]**

My code. I have truncated the data somewhat but it still runs.

import json
import random
import uuid

entry_template = {
    "itemId": None,
    "date": None,
    "subjectAreas": None,
    "images": None,
    "title": None,
    "description": None,
    "method": None,
    "materials": None,
    "size": {"width": None, "height": None, "depth": None},
    "weight": None
}

subjectAreas = [
    ["drawings"],
    ["prints"],
    ["watercolor"],
    ["automata"],
    ["art3d"],
    ["art3d", "automata"],
]

titles = [
    "Spring chicken",
    "Black nignt",
    "Red sunset",
]

descriptions = [
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sit amet arcu vitae ipsum luctus elementum. Aliquam vel tortor mi. Sed venenatis turpis justo, sit amet rhoncus magna dictum ac. Sed eget iaculis mi. Pellentesque habitant morbi.",
    "Pellentesque sollicitudin diam ac urna aliquet auctor. Nulla vel nisl lacus. Vestibulum eget vestibulum massa. Nulla blandit nec augue lacinia lobortis. Morbi lacus ipsum, aliquet sit amet volutpat at, pellentesque eget mauris. Nunc ullamcorper pulvinar ex, id accumsan orci hendrerit non. Etiam rhoncus eros a nulla fermentum iaculis. ",
]

methods = [
    "Pencil drawing",
    "print",
]

materials = [
    "wood",
    "watercolor on paper",
]


def sometimes(x):
    return random.randint(0, 12) > x


def gen_dimension():
    return random.randint(200, 500)


def select_val(list_name):
    return list_name[random.randint(0, len(list_name) - 1)]


def gen_id():
    return str(uuid.uuid4())


def gen_date_string():
    year = random.randint(1990, 2024)
    month = random.randint(1, 12)
    day = random.randint(1, 28)
    hour = random.randint(0, 23)
    minutes = random.randint(0, 59)
    seconds = random.randint(0, 59)
    return f"{year}-{month:02}-{day:02} {hour:02}:{minutes:02}:{seconds:02}"


images = ["10000", "10001", "10002", "10003"]

image_range = [1, 1, 1, 1, 1, 2, 2, 3]


def gen_image_ids():
    image_key = select_val(images)
    image_names = [image_key]
    for num in range(1, image_range[random.randint(0, len(image_range) - 1)]):
        image_names.append(f'{image_key}-{num}')
    return image_names


entries = []

for num in range(0, 2):
    entry = entry_template.copy()
    entry["itemId"] = gen_id(),
    entry["date"] = gen_date_string(),
    entry["subjectAreas"] = select_val(subjectAreas),
    entry["images"] = gen_image_ids(),
    entry["title"] = select_val(titles),
    entry["description"] = select_val(descriptions),
    entry["method"] = select_val(methods),
    entry["materials"] = select_val(materials),
    entry["size"] = {"width": gen_dimension(), "height": gen_dimension(), "depth": gen_dimension()},
    entry["weight"] = gen_dimension()
    # print(json.dumps(entry, indent=4))
    entries.append(entry)

entries_json = json.dumps(entries, indent=4)
entries_json = "const galleryItems = " + entries_json + "nnexport default galleryItems;n"


print(entries_json)


# with open("gallery.js", "w") as file:
#     file.write(entries_json)

The output generated is

const galleryItems = [
    {
        "itemId": [
            "42198f4d-c69d-4fa6-8146-6b08c6237240"
        ],
        "date": [
            "2011-08-11 22:41:09"
        ],
        "subjectAreas": [
            [
                "workshops"
            ]
        ],
        "images": [
            [
                "10002"
            ]
        ],
        "title": [
            "Black nignt"
        ],
        "description": [
            "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet."
        ],
        "method": [
            "Mechanical device"
        ],
        "materials": [
            "watercolor on paper"
        ],
        "size": [
            {
                "width": 272,
                "height": 206,
                "depth": 365
            }
        ],
        "weight": 450
    },
    {
        "itemId": [
            "f2f1c977-5e8a-469e-b6ea-e946a0aa9e68"
        ],
        "date": [
            "1991-01-25 01:04:48"
        ],
        "subjectAreas": [
            [
                "automata"
            ]
        ],
        "images": [
            [
                "10001",
                "10001-1
            ]
        ],
        "title": [
            "Black nignt"
        ],
        "description": [
            "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet."
        ],
        "method": [
            "Pencil drawing"
        ],
        "materials": [
            "Oilbased inks on paper"
        ],
        "size": [
            {
                "width": 380,
                "height": 214,
                "depth": 385
            }
        ],
        "weight": 448
    }
]

export default galleryItems;

what i would expect is (hand edited so format might not be quite as expected)

const galleryItems = [
    {
        "itemId": "42198f4d-c69d-4fa6-8146-6b08c6237240",
        "date": "2011-08-11 22:41:09",
        "subjectAreas": ["workshops"],
        "images": ["10002"],
        "title": "Black nignt",
        "description": "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet.",
        "method": "Mechanical device",
        "materials": "watercolor on paper",
        "size": {
                "width": 272,
                "height": 206,
                "depth": 365
            },
        "weight": 450
    },
    {
        "itemId": "f2f1c977-5e8a-469e-b6ea-e946a0aa9e68",
        "date": "1991-01-25 01:04:48",
        "subjectAreas": ["automata"],
        "images": ["10001","10001-1"],
        "title": "Black nignt",
        "description": "Donec pharetra sem a dui cursus porta nec eget mi. Cras condimentum, nibh non malesuada blandit, sem arcu efficitur mi, eget ultrices lacus erat vitae urna. Vestibulum rutrum felis ac malesuada aliquet.",
        "method": "Pencil drawing",
        "materials": "Oilbased inks on paper",
        "size": {
                "width": 380,
                "height": 214,
                "depth": 385
         },
         "weight": 448,
    }
]

2

Answers


  1. Be cautious of setting commas where it is not necessary. A trailing comma at the end of a line like entry["itemId"] = 123, will create a tuple!

    entry = {}
    entry["itemId"] = 123,
    print(entry)
    # outputs: {'itemId': (123,)}
    

    The jsonizer will create a list from the tuple, at the end. So just ensure not using unnecessary commas.

    Login or Signup to reply.
  2. To expand on the comment by @Guy, in Python, just like [...] creates a list, comma designates a tuple. So, in your loop:

    entry["itemId"] = gen_id(),
    entry["date"] = gen_date_string(),
    entry["subjectAreas"] = select_val(subjectAreas),
    

    All those create 1-element tuples containing just a string. These are mapped to lists when creating JSON string. You can verify it with

    entry["date"] = gen_date_string(),
    print(type(entry['date']))
    

    which will print <class 'tuple'>.
    Get rid of those commas and you will just get strings.

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