import scene3d
scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.PURE_SKY)
scene.set_ground(length=20, width=20)
trunk1 = scene3d.Shapes.Cylinder(diameter=0.3, height=1.5, tessellation=8)
trunk1.set_color('#8B4513')
trunk1.set_position(-3, 0.75, 0)
scene.add(trunk1)
leaves1 = scene3d.Shapes.Sphere(diameter=2.0, segments=12)
leaves1.set_color('#228B22')
leaves1.set_position(-3, 2.0, 0)
scene.add(leaves1)
trunk2 = scene3d.Shapes.Cylinder(diameter=0.3, height=1.5, tessellation=8)
trunk2.set_color('#8B4513')
trunk2.set_position(3, 0.75, 0)
scene.add(trunk2)
leaves2 = scene3d.Shapes.Sphere(diameter=2.0, segments=12)
leaves2.set_color('#228B22')
leaves2.set_position(3, 2.0, 0)
scene.add(leaves2)Creating Your Own Functions
You’ve been calling functions all along — set_position(), set_color(), scene.add(). Each one packages up a bunch of steps under a single name so you don’t have to repeat them.
Now it’s your turn. In this lesson you’ll write your own functions using def. A function you define works exactly like the built-in ones — call it by name, pass in values, and it does the work.
The Problem — Repeated Code
The scene below contains two trees. Each tree is made from a cylinder (trunk) and a sphere (leaves). That’s six lines per tree — and they’re nearly identical. Adding a third tree means copying six more lines. A forest of ten trees? Sixty lines of nearly identical code.
The Solution — Define a Function
A function groups code under a name. You write the steps once, then call the name as many times as you need.
def make_tree(scene, x, z):
# steps that build one tree go hereRun the cell below. It produces the same two trees — but now adding a third is just one more line.
import scene3d
scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.PURE_SKY)
scene.set_ground(length=20, width=20)
def make_tree(scene, x, z):
trunk = scene3d.Shapes.Cylinder(diameter=0.3, height=1.5, tessellation=8)
trunk.set_color('#8B4513')
trunk.set_position(x, 0.75, z)
scene.add(trunk)
leaves = scene3d.Shapes.Sphere(diameter=2.0, segments=12)
leaves.set_color('#228B22')
leaves.set_position(x, 2.0, z)
scene.add(leaves)
make_tree(scene, -3, 0)
make_tree(scene, 3, 0)
make_tree(scene, 0, -3)How def Works
def make_tree(scene, x, z):
trunk = scene3d.Shapes.Cylinder(...)
...| Part | What it does |
|---|---|
def |
The keyword that defines a new function |
make_tree |
The name you give the function — use it to call it later |
(scene, x, z) |
Parameters — values passed in when the function is called |
: |
Marks the end of the def line |
| Indented body | The code that runs each time the function is called |
When you write make_tree(scene, -3, 0), Python replaces scene with your scene, x with -3, and z with 0 inside the function body.
Two rules to remember
- Define before calling. The
defblock must appear in your code before you call the function. - Indentation marks the body. Everything indented under
defis inside the function.
{ “question_type”: “multiple_choice”, “question”: “Which keyword do you use to define a new function in Python?”, “options”: [ { “key”: “a”, “text”: “function” }, { “key”: “b”, “text”: “define” }, { “key”: “c”, “text”: “def” }, { “key”: “d”, “text”: “new” } ], “answer”: “c”, “submitted_answer”: “” }
{ “question_type”: “true_false”, “question”: “You can call a function as many times as you like after defining it once.”, “answer”: “True”, “submitted_answer”: “” }
Adding Parameters to Customize Behavior
Right now every tree is the same height. Parameters let callers choose different values. Adding a height parameter — with a default value of 1.5 — lets you vary the tree without making it required:
def make_tree(scene, x, z, height=1.5):
...make_tree(scene, 0, 0) still works and uses the default height. make_tree(scene, 0, 0, height=3.0) overrides it with a taller tree.
Run the cell below to see three trees of different heights side by side.
import scene3d
scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.PURE_SKY)
scene.set_ground(length=20, width=20)
def make_tree(scene, x, z, height=1.5):
trunk = scene3d.Shapes.Cylinder(diameter=0.3, height=height, tessellation=8)
trunk.set_color('#8B4513')
trunk.set_position(x, height / 2, z)
scene.add(trunk)
leaf_diameter = height * 1.4
leaves = scene3d.Shapes.Sphere(diameter=leaf_diameter, segments=12)
leaves.set_color('#228B22')
leaves.set_position(x, height + leaf_diameter / 2, z)
scene.add(leaves)
make_tree(scene, -4, 0, height=1.0)
make_tree(scene, 0, 0, height=2.0)
make_tree(scene, 4, 0, height=3.5){ “question_type”: “multiple_choice”, “question”: “In the function definition ‘def make_tree(scene, x, z, height=1.5):’, what does height=1.5 mean?”, “options”: [ { “key”: “a”, “text”: “height must always equal 1.5” }, { “key”: “b”, “text”: “height is used as a variable name only” }, { “key”: “c”, “text”: “1.5 is the default value used when the caller doesn’t supply height” }, { “key”: “d”, “text”: “The function will error if height is not exactly 1.5” } ], “answer”: “c”, “submitted_answer”: “” }
Building a Forest — Functions Meet Loops
Functions become even more powerful when combined with loops. The scene below uses make_tree inside a for loop with random positions and heights, building an entire forest from a single function definition.
Run it a few times — a different forest appears each time!
import scene3d
import random
scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.PURE_SKY)
ground = scene.set_ground(length=30, width=30)
ground.set_material(scene3d.Material.Grass.Bright)
ground.set_tiling(8)
def make_tree(scene, x, z, height=1.5):
trunk = scene3d.Shapes.Cylinder(diameter=0.3, height=height, tessellation=8)
trunk.set_color('#8B4513')
trunk.set_position(x, height / 2, z)
scene.add(trunk)
leaf_diameter = height * 1.4
leaves = scene3d.Shapes.Sphere(diameter=leaf_diameter, segments=12)
leaves.set_color('#228B22')
leaves.set_position(x, height + leaf_diameter / 2, z)
scene.add(leaves)
for i in range(12):
x = random.uniform(-10, 10)
z = random.uniform(-10, 10)
h = random.uniform(1.0, 3.5)
make_tree(scene, x, z, height=h){ “question_type”: “freeform”, “question”: “In one sentence, describe the main benefit of grouping code into a function.”, “answer”: “write once reuse”, “submitted_answer”: “” }
Try It Yourself
Use the slider to control how many trees appear in the forest. Notice that no matter the count, the function handles all the placement — you only changed one number.
import scene3d
import random
TREE_COUNT = 8 #@param {type:"slider", min:1, max:25, step:1}
random.seed(99)
scene = scene3d.Scene()
scene.set_sky(scene3d.Sky.PURE_SKY)
ground = scene.set_ground(length=30, width=30)
ground.set_material(scene3d.Material.Grass.Bright)
ground.set_tiling(8)
def make_tree(scene, x, z, height=1.5):
trunk = scene3d.Shapes.Cylinder(diameter=0.3, height=height, tessellation=8)
trunk.set_color('#8B4513')
trunk.set_position(x, height / 2, z)
scene.add(trunk)
leaf_diameter = height * 1.4
leaves = scene3d.Shapes.Sphere(diameter=leaf_diameter, segments=12)
leaves.set_color('#228B22')
leaves.set_position(x, height + leaf_diameter / 2, z)
scene.add(leaves)
for i in range(TREE_COUNT):
x = random.uniform(-10, 10)
z = random.uniform(-10, 10)
h = random.uniform(1.0, 3.5)
make_tree(scene, x, z, height=h)Think about a 3D scene you’d like to build — a city with buildings, a reef with coral, a campsite with tents and campfires.
What function would you define? What would you name it, and what parameters would it take? Describe what goes inside the function and how you’d call it to populate your scene.