pystrings / index.html
subbuadd's picture
Add 2 files
acc4385 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Python Strings and Methods for Autodesk Maya</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/css/all.min.css">
<style>
body {
background-color: #1a1a1a;
color: #e0e0e0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.method-container {
background-color: #2d2d2d;
border-radius: 8px;
margin-bottom: 20px;
transition: all 0.3s ease;
}
.method-container:hover {
box-shadow: 0 0 15px rgba(66, 153, 225, 0.3);
}
.play-button {
background-color: #4299e1;
transition: all 0.2s ease;
}
.play-button:hover {
background-color: #3182ce;
transform: scale(1.05);
}
.play-button:active {
transform: scale(0.98);
}
.result-box {
background-color: #363636;
border-left: 4px solid #4299e1;
font-family: 'Consolas', 'Courier New', monospace;
}
.section-title {
border-bottom: 2px solid #4299e1;
padding-bottom: 8px;
}
input[type="text"], textarea {
background-color: #363636;
border: 1px solid #4a4a4a;
color: #e0e0e0;
}
input[type="text"]:focus, textarea:focus {
border-color: #4299e1;
outline: none;
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.3);
}
code {
background-color: #363636;
padding: 2px 4px;
border-radius: 4px;
font-family: 'Consolas', 'Courier New', monospace;
}
</style>
</head>
<body class="px-4 py-6 max-w-6xl mx-auto">
<header class="mb-8">
<h1 class="text-4xl font-bold text-blue-400 mb-2">Python Strings and Methods for Autodesk Maya</h1>
<p class="text-lg text-gray-300">Interactive examples to practice string manipulation techniques useful in Maya scripting</p>
</header>
<main>
<!-- Introduction -->
<section class="mb-10">
<p class="mb-4">
In Maya Python scripting, strings are essential for working with node names, file paths, commands, and more.
This interactive guide lets you experiment with Python's string methods and see immediate results.
</p>
<p class="text-sm text-gray-400 italic mb-6">
For each example, enter your own text in the input field and click the play button to see the result.
</p>
</section>
<!-- Basic String Operations -->
<section class="mb-10">
<h2 class="text-2xl font-bold text-blue-300 section-title mb-4">Basic String Operations</h2>
<!-- Concatenation -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">String Concatenation</h3>
<p class="mb-3">Combines two or more strings together using the <code>+</code> operator. In Maya, this is often used to build command strings or create full paths.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block mb-2">First String:</label>
<input type="text" id="concat-input1" class="w-full p-2 rounded" value="sphere_" placeholder="Enter first string">
</div>
<div>
<label class="block mb-2">Second String:</label>
<input type="text" id="concat-input2" class="w-full p-2 rounded" value="01" placeholder="Enter second string">
</div>
</div>
<button onclick="concatStrings()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="concat-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>node_prefix = "pSphere"
node_number = "1"
full_node_name = node_prefix + node_number # Creates "pSphere1"
cmds.select(full_node_name)</code></pre>
</div>
</div>
<!-- Indexing -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">String Indexing</h3>
<p class="mb-3">Access individual characters in a string using their index position (starting from 0). Useful for inspecting specific characters in node names.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block mb-2">String:</label>
<input type="text" id="index-input" class="w-full p-2 rounded" value="pCube5_grp" placeholder="Enter a string">
</div>
<div>
<label class="block mb-2">Index Position:</label>
<input type="number" id="index-position" class="w-full p-2 rounded" value="1" min="0" placeholder="Enter index number">
</div>
</div>
<button onclick="indexString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="index-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>node_name = "pSphere1"
node_type = node_name[0] # Gets 'p' which can indicate a polygon object
if node_type == "p":
print("This is likely a polygon object")</code></pre>
</div>
</div>
<!-- Slicing -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">String Slicing</h3>
<p class="mb-3">Extract a substring using the slice notation <code>[start:end]</code>. Useful for extracting parts of object names or file paths in Maya.</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div>
<label class="block mb-2">String:</label>
<input type="text" id="slice-input" class="w-full p-2 rounded" value="pCylinder25_geo" placeholder="Enter a string">
</div>
<div>
<label class="block mb-2">Start Index:</label>
<input type="number" id="slice-start" class="w-full p-2 rounded" value="0" min="0" placeholder="Start index">
</div>
<div>
<label class="block mb-2">End Index:</label>
<input type="number" id="slice-end" class="w-full p-2 rounded" value="9" min="0" placeholder="End index">
</div>
</div>
<button onclick="sliceString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="slice-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>file_path = "C:/Projects/Maya/scenes/character_rig_v001.mb"
file_name = file_path[-11:] # Gets "v001.mb"
version_number = file_name[1:4] # Gets "001"</code></pre>
</div>
</div>
</section>
<!-- Case Methods -->
<section class="mb-10">
<h2 class="text-2xl font-bold text-blue-300 section-title mb-4">Case Methods</h2>
<!-- upper() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.upper()</h3>
<p class="mb-3">Converts all characters in a string to uppercase. Useful for case-insensitive comparisons in Maya scripts.</p>
<div class="mb-4">
<label class="block mb-2">String:</label>
<input type="text" id="upper-input" class="w-full p-2 rounded" value="leftArm_ctrl" placeholder="Enter a string">
</div>
<button onclick="upperCaseString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="upper-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>user_input = "yes"
if user_input.upper() == "YES":
# Process regardless of input case (yes, Yes, YES)
cmds.polyCube(name="new_cube")</code></pre>
</div>
</div>
<!-- lower() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.lower()</h3>
<p class="mb-3">Converts all characters in a string to lowercase. Useful for standardizing naming or case-insensitive comparisons.</p>
<div class="mb-4">
<label class="block mb-2">String:</label>
<input type="text" id="lower-input" class="w-full p-2 rounded" value="RightLeg_GRP" placeholder="Enter a string">
</div>
<button onclick="lowerCaseString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="lower-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>obj_name = "CHARACTER_RIG"
standardized_name = obj_name.lower() # "character_rig"
cmds.rename(obj_name, standardized_name)</code></pre>
</div>
</div>
<!-- title() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.title()</h3>
<p class="mb-3">Converts the first character of each word to uppercase and the rest to lowercase. Useful for formatting display names in UIs.</p>
<div class="mb-4">
<label class="block mb-2">String:</label>
<input type="text" id="title-input" class="w-full p-2 rounded" value="character facial controls" placeholder="Enter a string">
</div>
<button onclick="titleCaseString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="title-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>control_description = "head rotation controls"
display_name = control_description.title() # "Head Rotation Controls"
cmds.button(label=display_name)</code></pre>
</div>
</div>
<!-- capitalize() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.capitalize()</h3>
<p class="mb-3">Capitalizes the first character of the string and converts the rest to lowercase. Useful for formatting single labels or short descriptions.</p>
<div class="mb-4">
<label class="block mb-2">String:</label>
<input type="text" id="capitalize-input" class="w-full p-2 rounded" value="mainController" placeholder="Enter a string">
</div>
<button onclick="capitalizeString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="capitalize-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>error_message = "invalid selection"
formatted_message = error_message.capitalize() # "Invalid selection"
cmds.warning(formatted_message)</code></pre>
</div>
</div>
</section>
<!-- Search Methods -->
<section class="mb-10">
<h2 class="text-2xl font-bold text-blue-300 section-title mb-4">Search Methods</h2>
<!-- find() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.find()</h3>
<p class="mb-3">Returns the index of the first occurrence of a substring, or -1 if not found. Useful for locating specific patterns in node names or paths.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block mb-2">String:</label>
<input type="text" id="find-input" class="w-full p-2 rounded" value="character_arm_joint_01" placeholder="Enter a string">
</div>
<div>
<label class="block mb-2">Substring to Find:</label>
<input type="text" id="find-substring" class="w-full p-2 rounded" value="arm" placeholder="Enter substring to find">
</div>
</div>
<button onclick="findInString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="find-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>node_name = "character_arm_joint_01"
if node_name.find("arm") != -1:
print("This is an arm joint")
# Add arm-specific rigging code</code></pre>
</div>
</div>
<!-- startswith() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.startswith()</h3>
<p class="mb-3">Checks if a string starts with a specified prefix, returning True or False. Useful for filtering nodes by prefix naming conventions.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block mb-2">String:</label>
<input type="text" id="startswith-input" class="w-full p-2 rounded" value="jnt_spine_01" placeholder="Enter a string">
</div>
<div>
<label class="block mb-2">Prefix to Check:</label>
<input type="text" id="startswith-prefix" class="w-full p-2 rounded" value="jnt_" placeholder="Enter prefix to check">
</div>
</div>
<button onclick="checkStartsWith()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="startswith-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>all_nodes = cmds.ls()
joint_nodes = []
for node in all_nodes:
if node.startswith("jnt_"):
joint_nodes.append(node)
print(f"Found {len(joint_nodes)} joints")</code></pre>
</div>
</div>
<!-- endswith() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.endswith()</h3>
<p class="mb-3">Checks if a string ends with a specified suffix, returning True or False. Useful for filtering nodes by suffix naming conventions.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block mb-2">String:</label>
<input type="text" id="endswith-input" class="w-full p-2 rounded" value="character_head_ctrl" placeholder="Enter a string">
</div>
<div>
<label class="block mb-2">Suffix to Check:</label>
<input type="text" id="endswith-suffix" class="w-full p-2 rounded" value="_ctrl" placeholder="Enter suffix to check">
</div>
</div>
<button onclick="checkEndsWith()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="endswith-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>all_objects = cmds.ls()
control_objects = []
for obj in all_objects:
if obj.endswith("_ctrl"):
control_objects.append(obj)
cmds.select(control_objects) # Select all control objects</code></pre>
</div>
</div>
</section>
<!-- Modification Methods -->
<section class="mb-10">
<h2 class="text-2xl font-bold text-blue-300 section-title mb-4">Modification Methods</h2>
<!-- replace() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.replace()</h3>
<p class="mb-3">Replaces occurrences of a substring with another substring. Perfect for renaming parts of object names or updating file paths.</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div>
<label class="block mb-2">String:</label>
<input type="text" id="replace-input" class="w-full p-2 rounded" value="arm_left_ctrl" placeholder="Enter a string">
</div>
<div>
<label class="block mb-2">Text to Replace:</label>
<input type="text" id="replace-old" class="w-full p-2 rounded" value="left" placeholder="Text to replace">
</div>
<div>
<label class="block mb-2">Replacement Text:</label>
<input type="text" id="replace-new" class="w-full p-2 rounded" value="right" placeholder="Replacement text">
</div>
</div>
<button onclick="replaceInString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="replace-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>left_nodes = cmds.ls("*left*")
for node in left_nodes:
right_node_name = node.replace("left", "right")
duplicate_node = cmds.duplicate(node, name=right_node_name)
# Now mirror the duplicate to the right side</code></pre>
</div>
</div>
<!-- strip() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.strip()</h3>
<p class="mb-3">Removes leading and trailing whitespace or specified characters. Useful for cleaning up user input or imported data.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block mb-2">String (with whitespace or chars to remove):</label>
<input type="text" id="strip-input" class="w-full p-2 rounded" value=" pSphere1 " placeholder="Enter a string with whitespace">
</div>
<div>
<label class="block mb-2">Characters to Strip (optional):</label>
<input type="text" id="strip-chars" class="w-full p-2 rounded" placeholder="Enter specific chars to strip (leave empty for whitespace)">
</div>
</div>
<button onclick="stripString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="strip-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>user_input = " pCube1 " # User might add extra spaces
clean_input = user_input.strip()
if cmds.objExists(clean_input):
cmds.select(clean_input)
else:
cmds.warning("Object not found")</code></pre>
</div>
</div>
<!-- split() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">.split()</h3>
<p class="mb-3">Splits a string into a list using a delimiter. Perfect for parsing paths, node hierarchies, or breaking down complex names.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label class="block mb-2">String:</label>
<input type="text" id="split-input" class="w-full p-2 rounded" value="head_geo|head_eyebrows_geo|head_eyes_geo" placeholder="Enter a string">
</div>
<div>
<label class="block mb-2">Delimiter:</label>
<input type="text" id="split-delimiter" class="w-full p-2 rounded" value="|" placeholder="Enter delimiter character">
</div>
</div>
<button onclick="splitString()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="split-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>full_path = "characters|hero|skeleton|spine|neck|head"
path_components = full_path.split("|")
parent_node = path_components[-2] # "neck"
cmds.select(parent_node)</code></pre>
</div>
</div>
<!-- join() -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">str.join()</h3>
<p class="mb-3">Joins elements of an iterable with a specified string. Useful for building paths, constructing node names, or formatting output.</p>
<div class="mb-4">
<label class="block mb-2">List of Strings (comma-separated):</label>
<input type="text" id="join-input" class="w-full p-2 rounded" value="character,rig,arm,left,01" placeholder="Enter comma-separated strings">
<label class="block mt-4 mb-2">Join Character:</label>
<input type="text" id="join-char" class="w-full p-2 rounded" value="_" placeholder="Character to join with">
</div>
<button onclick="joinStrings()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Run Example
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="join-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>name_parts = ["character", "arm", "left", "ctrl"]
node_name = "_".join(name_parts) # "character_arm_left_ctrl"
cmds.circle(name=node_name)</code></pre>
</div>
</div>
</section>
<!-- Maya-Specific Examples -->
<section class="mb-10">
<h2 class="text-2xl font-bold text-blue-300 section-title mb-4">Maya-Specific Examples</h2>
<!-- Node Naming -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">Node Naming Convention Tool</h3>
<p class="mb-3">Creates a Maya-style node name based on input parts. Demonstrates string concatenation and naming conventions.</p>
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-4">
<div>
<label class="block mb-2">Prefix:</label>
<select id="node-prefix" class="w-full p-2 rounded bg-gray-700 text-white">
<option value="c_">c_ (center)</option>
<option value="l_">l_ (left)</option>
<option value="r_">r_ (right)</option>
</select>
</div>
<div>
<label class="block mb-2">Body Part:</label>
<input type="text" id="node-bodypart" class="w-full p-2 rounded" value="arm" placeholder="Body part">
</div>
<div>
<label class="block mb-2">Index:</label>
<input type="number" id="node-index" class="w-full p-2 rounded" value="1" min="1" placeholder="Index number">
</div>
<div>
<label class="block mb-2">Type:</label>
<select id="node-type" class="w-full p-2 rounded bg-gray-700 text-white">
<option value="_jnt">_jnt (joint)</option>
<option value="_geo">_geo (geometry)</option>
<option value="_ctrl">_ctrl (controller)</option>
<option value="_grp">_grp (group)</option>
</select>
</div>
</div>
<button onclick="generateNodeName()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Generate Node Name
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="maya-naming-result" class="result-box p-3 rounded"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>def create_named_joint(side, part, index):
side_prefix = {
"left": "l_",
"right": "r_",
"center": "c_"
}.get(side, "c_")
node_name = f"{side_prefix}{part}{str(index).zfill(2)}_jnt"
return cmds.joint(name=node_name)
# Create joints with proper naming
spine_joint = create_named_joint("center", "spine", 1)
left_arm_joint = create_named_joint("left", "arm", 1)</code></pre>
</div>
</div>
<!-- Path Manipulation -->
<div class="method-container p-4 mb-6">
<h3 class="text-xl font-semibold mb-2">Maya File Path Manipulation</h3>
<p class="mb-3">Extract and modify parts of a Maya file path. Demonstrates how to work with file paths in Maya scripts.</p>
<div class="mb-4">
<label class="block mb-2">Maya File Path:</label>
<input type="text" id="filepath-input" class="w-full p-2 rounded" value="C:/Projects/Character/scenes/character_model_v001.mb" placeholder="Enter a file path">
</div>
<button onclick="analyzeFilePath()" class="play-button px-4 py-2 rounded text-white flex items-center">
<i class="fas fa-play mr-2"></i> Analyze Path
</button>
<div class="mt-4">
<p class="font-medium mb-1">Result:</p>
<div id="filepath-result" class="result-box p-3 rounded whitespace-pre-line"></div>
</div>
<div class="mt-4 text-sm text-gray-400">
<p>Maya usage example:</p>
<pre class="bg-gray-800 p-2 rounded"><code>def increment_version(file_path):
# Split the path to get the directory and filename
components = file_path.replace("\\", "/").split("/")
directory = "/".join(components[:-1])
file_name = components[-1]
# Find version number
if "_v" in file_name:
base_name, version_ext = file_name.split("_v")
version_num, ext = version_ext.split(".")
# Increment version
new_version = str(int(version_num) + 1).zfill(len(version_num))
new_file_name = f"{base_name}_v{new_version}.{ext}"
# Join to get new path
new_path = f"{directory}/{new_file_name}"
return new_path
return file_path
current_path = cmds.file(q=True, sn=True)
new_path = increment_version(current_path)
cmds.file(rename=new_path)
cmds.file(save=True)</code></pre>
</div>
</div>
</section>
</main>
<footer class="mt-12 text-center text-gray-500 text-sm">
<p>Interactive Python String Methods for Autodesk Maya</p>
<p class="mt-2">Use these examples in Maya's Script Editor for practical applications</p>
</footer>
<script>
// Basic String Operations
function concatStrings() {
const str1 = document.getElementById('concat-input1').value;
const str2 = document.getElementById('concat-input2').value;
const result = str1 + str2;
const resultBox = document.getElementById('concat-result');
resultBox.innerHTML = `Combined string: "${result}"<br>Python: str1 + str2`;
}
function indexString() {
const str = document.getElementById('index-input').value;
const index = parseInt(document.getElementById('index-position').value);
const resultBox = document.getElementById('index-result');
if (index < 0 || index >= str.length) {
resultBox.innerHTML = `Error: Index ${index} is out of range (0 to ${str.length - 1})`;
return;
}
const result = str[index];
resultBox.innerHTML = `Character at index ${index}: "${result}"<br>Python: str[${index}]`;
}
function sliceString() {
const str = document.getElementById('slice-input').value;
const start = parseInt(document.getElementById('slice-start').value);
const end = parseInt(document.getElementById('slice-end').value);
const resultBox = document.getElementById('slice-result');
if (start < 0 || start > str.length) {
resultBox.innerHTML = `Error: Start index ${start} is out of range (0 to ${str.length})`;
return;
}
if (end < start || end > str.length) {
resultBox.innerHTML = `Error: End index ${end} is invalid (should be between ${start} and ${str.length})`;
return;
}
const result = str.slice(start, end);
resultBox.innerHTML = `Slice from index ${start} to ${end}: "${result}"<br>Python: str[${start}:${end}]`;
}
// Case Methods
function upperCaseString() {
const str = document.getElementById('upper-input').value;
const result = str.toUpperCase();
const resultBox = document.getElementById('upper-result');
resultBox.innerHTML = `Uppercase: "${result}"<br>Python: str.upper()`;
}
function lowerCaseString() {
const str = document.getElementById('lower-input').value;
const result = str.toLowerCase();
const resultBox = document.getElementById('lower-result');
resultBox.innerHTML = `Lowercase: "${result}"<br>Python: str.lower()`;
}
function titleCaseString() {
const str = document.getElementById('title-input').value;
// JavaScript doesn't have a direct title() equivalent, so implement manually
const result = str.toLowerCase().replace(/(?:^|\s)\S/g, function(a) {
return a.toUpperCase();
});
const resultBox = document.getElementById('title-result');
resultBox.innerHTML = `Title case: "${result}"<br>Python: str.title()`;
}
function capitalizeString() {
const str = document.getElementById('capitalize-input').value;
// JavaScript doesn't have a direct capitalize() equivalent, implement manually
const result = str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
const resultBox = document.getElementById('capitalize-result');
resultBox.innerHTML = `Capitalized: "${result}"<br>Python: str.capitalize()`;
}
// Search Methods
function findInString() {
const str = document.getElementById('find-input').value;
const substr = document.getElementById('find-substring').value;
const result = str.indexOf(substr);
const resultBox = document.getElementById('find-result');
if (result === -1) {
resultBox.innerHTML = `Substring "${substr}" not found.<br>Python: str.find("${substr}") returned -1`;
} else {
resultBox.innerHTML = `Substring "${substr}" found at index ${result}.<br>Python: str.find("${substr}")`;
}
}
function checkStartsWith() {
const str = document.getElementById('startswith-input').value;
const prefix = document.getElementById('startswith-prefix').value;
const result = str.startsWith(prefix);
const resultBox = document.getElementById('startswith-result');
resultBox.innerHTML = `Does "${str}" start with "${prefix}"? ${result}<br>Python: str.startswith("${prefix}")`;
}
function checkEndsWith() {
const str = document.getElementById('endswith-input').value;
const suffix = document.getElementById('endswith-suffix').value;
const result = str.endsWith(suffix);
const resultBox = document.getElementById('endswith-result');
resultBox.innerHTML = `Does "${str}" end with "${suffix}"? ${result}<br>Python: str.endswith("${suffix}")`;
}
// Modification Methods
function replaceInString() {
const str = document.getElementById('replace-input').value;
const oldText = document.getElementById('replace-old').value;
const newText = document.getElementById('replace-new').value;
const result = str.replace(oldText, newText);
const resultBox = document.getElementById('replace-result');
resultBox.innerHTML = `Result: "${result}"<br>Python: str.replace("${oldText}", "${newText}")`;
}
function stripString() {
const str = document.getElementById('strip-input').value;
const chars = document.getElementById('strip-chars').value;
let result;
if (chars) {
// JavaScript doesn't have direct strip() with chars, simulate it
let startIndex = 0;
let endIndex = str.length - 1;
// Find start index (first char not in the chars)
while (startIndex <= endIndex && chars.includes(str[startIndex])) {
startIndex++;
}
// Find end index (last char not in the chars)
while (endIndex >= startIndex && chars.includes(str[endIndex])) {
endIndex--;
}
result = str.slice(startIndex, endIndex + 1);
} else {
result = str.trim();
}
const resultBox = document.getElementById('strip-result');
if (chars) {
resultBox.innerHTML = `Result: "${result}"<br>Python: str.strip("${chars}")`;
} else {
resultBox.innerHTML = `Result: "${result}"<br>Python: str.strip()`;
}
}
function splitString() {
const str = document.getElementById('split-input').value;
const delimiter = document.getElementById('split-delimiter').value;
const result = str.split(delimiter);
const resultBox = document.getElementById('split-result');
resultBox.innerHTML = `Split into list: [${result.map(item => `"${item}"`).join(', ')}]<br>Python: str.split("${delimiter}")`;
}
function joinStrings() {
const strList = document.getElementById('join-input').value.split(',');
const joinChar = document.getElementById('join-char').value;
const result = strList.join(joinChar);
const resultBox = document.getElementById('join-result');
resultBox.innerHTML = `Joined string: "${result}"<br>Python: "${joinChar}".join([${strList.map(item => `"${item}"`).join(', ')}])`;
}
// Maya-Specific Examples
function generateNodeName() {
const prefix = document.getElementById('node-prefix').value;
const bodyPart = document.getElementById('node-bodypart').value;
const index = document.getElementById('node-index').value;
const type = document.getElementById('node-type').value;
// Format index with leading zero if needed
const formattedIndex = index < 10 ? `0${index}` : index;
const nodeName = `${prefix}${bodyPart}${formattedIndex}${type}`;
const resultBox = document.getElementById('maya-naming-result');
resultBox.innerHTML = `Maya node name: "${nodeName}"<br>Python: f"{prefix}{bodyPart}{str(index).zfill(2)}{type}"`;
}
function analyzeFilePath() {
const filePath = document.getElementById('filepath-input').value;
// Replace Windows backslashes with forward slashes
const normalizedPath = filePath.replace(/\\/g, '/');
// Split into directory and filename
const lastSlashIndex = normalizedPath.lastIndexOf('/');
const directory = normalizedPath.substring(0, lastSlashIndex);
const filename = normalizedPath.substring(lastSlashIndex + 1);
// Extract base name and extension
const lastDotIndex = filename.lastIndexOf('.');
const basename = filename.substring(0, lastDotIndex);
const extension = filename.substring(lastDotIndex + 1);
// Extract version if present (_v000 pattern)
let version = "None";
let versionNumber = "None";
let basePart = basename;
const versionMatch = basename.match(/(.*)_v(\d+)$/);
if (versionMatch) {
basePart = versionMatch[1];
version = `v${versionMatch[2]}`;
versionNumber = versionMatch[2];
}
// Create incremented version
let nextVersion = "None";
if (versionNumber !== "None") {
const numDigits = versionNumber.length;
const nextNum = parseInt(versionNumber) + 1;
nextVersion = `v${nextNum.toString().padStart(numDigits, '0')}`;
}
// Create next version path
let nextVersionPath = "None";
if (nextVersion !== "None") {
nextVersionPath = `${directory}/${basePart}_${nextVersion}.${extension}`;
}
const resultBox = document.getElementById('filepath-result');
resultBox.innerHTML = `Directory: ${directory}
Filename: ${filename}
Base Name: ${basename}
Extension: ${extension}
Clean Base: ${basePart}
Version: ${version}
Next Version: ${nextVersion}
Next Path: ${nextVersionPath}
# Python in Maya:
directory = "${directory}"
filename = "${filename}"
basename = "${basename}"
extension = "${extension}"
clean_base = "${basePart}"
version = "${version}"
next_version = "${nextVersion}"
next_path = "${nextVersionPath}"`;
}
// Initialize all examples on page load
document.addEventListener('DOMContentLoaded', function() {
concatStrings();
indexString();
sliceString();
upperCaseString();
lowerCaseString();
titleCaseString();
capitalizeString();
findInString();
checkStartsWith();
checkEndsWith();
replaceInString();
stripString();
splitString();
joinStrings();
generateNodeName();
analyzeFilePath();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=subbuadd/pystrings" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>