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()