Python Tools — Session 8B

JSON Data Loading and PyMEL UI Building

2020.02.27 — Session 8B

Session Navigation

Overview

This session covers two projects. The first demonstrates loading external data from JSON files during class initialization, using file I/O with context managers and the json module to parse employee records. The second project builds an interactive Shapes UI with buttons that create spheres, planes, and random shapes, reinforcing PyMEL UI patterns from Session 8A.

Key Concepts

  • File I/O — Reading files using the with context manager for safe resource handling
  • JSON Parsing — Using the json module to convert file data into Python dictionaries
  • Class Initialization with Data — Calling functions during __init__ to dynamically load external data
  • Dictionary Access — Navigating nested JSON structures using dictionary key access
  • PyMEL UI Buttons — Creating buttons with pm.Callback to trigger shape creation methods
  • Random Shape Generation — Using random.randint to select and create different polygon primitives

Code

notes.py — JSON Data Loading and Shapes UI

"""
#############################################################################
filename    session_8b.py
author      Matt Osbond 
dP email    m.osbond@digipen.edu
course      CS115
Brief Description:
    Session 8B - Thursday Feb 27th 2020
    Using the initialization of a class to gather data using JSON
    Introducing file reading, contexts and dictionaries
    Intro to PyMel UI
#############################################################################
"""

# Making the __init__ do some work
"""
Small project to creat a class where the initialization method gathers some data using a JSON file
"""

import json

def get_level(first_name, last_name):
    """Gets the level of the user, provided their entry exists in the JSON file
    """
    # Define the file path
    file_path = r"C:\path\to\your\file"

    # The "with" keyword is called a context
    # The context lets you run an operation while inside it's scope
    # Then  once you exit, resources or handles are returned
    with open(file_path) as jf:
        # Read the raw file data
        data = jf.read()

    # Use the json module to turn it into a python dictionary
    db =  json.loads(data)

    # We iterate over each employee by accessing the "Employees" node
    # Look in the JSON file. You'll see each employee is actuall in a list
    # We can interate over this.
    # Dictionary elements can be accessed using the explicit KEY
    # (We will cover dictionaries mroe later)
    for employee in db['Employees']:
        # Check if the first name and last name for the current entry match what we were given
        if employee['LastName'] == last_name and employee['FirstName'] == first_name:
            # If so, return the level
            return employee['Level']

    # If we didn't find an entry, start them on 0
    return 0

class Employee():
    """Our base eployee class
    """
    def __init__(self, first, last):
        """Initialize, setting the first and last name
        """
        self.first_name = first
        self.last_name = last

        # In the initialization, we can dynamically call functions to gather data
        # So lets pretend the JSON is a big database, and ge the level of our employee
        self.level = get_level(self.first_name, self.last_name)

# Create an instance and print their level
e = Employee('Henry', 'Ford')
print e.level

# Intro to PyMel UI

"""
Small project to create little UI using PyMel
This UI will create shapes, with one button creating random shapes
"""

import pymel.core as pm
import random

class ShapesUI():
    """Base UI class
    """
    def __init__(self):
        """Initialization
        """
        # Set the window handle name. This is what Maya sees.
        # We need to set it here so we can check for it and delete it, ensuring only one exists
        self.handle = 'TestShapesUI'

        # Delete the window if it exists
        if pm.window(self.handle, exists=True):
            pm.deleteUI(self.handle)

        # Delete the window preferences if they exist
        if pm.windowPref(self.handle, exists=True):
            pm.windowPref(self.handle, remove=True)

        # Create the window using a context
        with pm.window(self.handle, title='Shapes', w=400, h=100):
            # Each layout can be creaed using contexts too
            with pm.columnLayout():

                # Create the three buttons, attaching each one their method
                pm.button(label='Sphere', w=100, h=40, command=pm.Callback(self.create_sphere))

                pm.button(label='Plane', w=100, h=40, command=pm.Callback(self.create_plane))

                pm.button(label='Random', w=100, h=40, command=pm.Callback(self.create_random))

        # Show the UI at the end of initialization
        pm.showWindow(self.handle)

    def create_sphere(self):
        """Create a sphere
        """
        pm.polySphere()

    def create_plane(self):
        """Create a plane
        """
        pm.polyPlane()

    def create_random(self):
        """Create a random shape
        """
        # Delete any existing meshes in the scene
        for node in pm.listTransforms(type='mesh'):
            pm.delete(node)

        # Get a random integer between 0 and 3 (including 3)
        rand = random.randint(0,3)

        # Use IF statements to create shapes based on the number
        if rand == 0:
            pm.polyTorus()
        if rand == 1:
            pm.polyPlane()
        if rand == 2:
            pm.polyDisc()
        if rand == 3:
            pm.polyCone()

        

        
# Call the class to create an instance
# Note, we don't need to capture it to a variable here
ShapesUI()
← Prev Next →