At My Fingertips

Documentation

In this activity you practice rotating and composing graphics.

Composing a Graphic

Here is the Taijitu, a famous symbol representing the concept of yin and yang!

yin yang

At first sight, this graphic looks non-trivial.

The two small circles stand out. But how is the rest built? You may have seen it, it's simpler than it might initially have looked: all you need is circles and semicircles (circular sectors of 180 degrees)!

circle Function

If you haven't already done so, add a circle function to your toolbox. Your function should have the following signature:

def circle(diameter: float, color: Color) -> Graphic

If you don't have that function yet, you may want to do the PyTamaro iconSimple Snowman activity to learn how to put a function in the toolbox.

Once you have a circle function in your toolbox, import it here:

Loading...

With this import statement, you told Python that the name circle refers to the circle function you had added to your toolbox. From now on, in this activity here, you can use that name to call that function.

Try it out! Let's show a black circle with a diameter of 100:

Loading...

semicircle Function

The second kind of graphic we need is a semi-circle. Write a function that creates one, by calling circular_sector with an angle of 180 degrees:

Loading...

Now let's create a black semicircle with a diameter of 100 and show it:

Loading...

Composing the Yin Yang

Now we are ready to construct the Yin Yang symbol! Look carefully at the symbol and think how you could compose it from circles and semicircles.

yin yang

Implement the yin_yang function below. You may find the imported functions beside, rotate, above, and overlay, and the colors black and white useful.

Loading...

Beautiful Code

You are done! You have a working yin_yang function!

Or are you?

The code we write is read by two different entities. The computer (or, more precisely, the Python interpreter, the program that reads and executes Python code) is relatively easy to satisfy. You can feed it code that looks horrible. And it happily executes it, as long as it follows the syntax and semantics of the Python language.

But besides the computer, there's also someone else who reads your code: humans! That includes you, and also your teammates! In the future, those people may have to understand your code to fix bugs, to improve its performance, or to add new features to it. And if you wrote correct but horrible code, those people (and that includes you!) will not be amused!

So, whenever we have a working function, we clean it up! We refactor it to make it easier to understand for humans. Programmers who write understandable code are cherished. But nobody wants to work with programmers who write hard-to-read code.

Cleaning Up

So, let's clean up your yin_yang function to make it easy to understand.

So, here are two different ways the function could be written. There are many others. But these two differ in their use of names for naming intermediate results.

No names -- one large expression

def yin_yang(diameter: float) -> Graphic:
    return overlay(
        above(
            overlay(
                circle(diameter / 6, black),
                circle(diameter / 2, white)
            ),
            overlay(
                circle(diameter / 6, white),
                circle(diameter / 2, black)
            )
        ),
        beside(
            rotate(90, semicircle(diameter, white)),
            rotate(-90, semicircle(diameter, black))
        )
    )

If you want to understand the above code, you have to pretty much read it all. It is nicely indented, and the entire structure of the yin yang graphic is visible in one place. But the structure is quite big. It probably makes sense to name some of the pieces, so that a reader (you, in the future, or some future teammate) doesn't need to infer what the pieces of the expression correspond to.

Names for intermediate parts

def yin_yang(diameter: float) -> Graphic:
    white_eye = overlay(
        circle(diameter / 6, black), 
        circle(diameter / 2, white)
    )
    black_eye = overlay(
        circle(diameter / 6, white), 
        circle(diameter / 2, black)
    )
    eyes = above(white_eye, black_eye)
    base = beside(
        rotate(90, semicircle(diameter, white)),
        rotate(-90, semicircle(diameter, black))
    )
    return overlay(eyes, base)

The above code extracts meaningful pieces of the large expression into smaller subexpressions, so it can introduce names for them. If we read an expressions like overlay(eyes, base), we can kind of imagine what it means, and we don't have to read overlay(10 lines of code,4 lines of code).

That's a benefit of naming things: we don't need to read much to have a reasonably good idea of what's going on. Of course, the names we pick need to be accurate. We wouldn't want to use overlay(honeybee, flower) to describe a yin yang!

Refactor Your Code

If your code has potential for improvement, refactor it now, to make it more readable.

Then, if you think you might want to reuse your yin_yang function in other activities (or in the playground, where you can be creative and compose whatever graphics you like), feel free to save it in your toolbox.

You also could save your semicircle function; it looks like a generally useful function that could come in handy in the future.

What You Learned

Isn't the yin yang symbol beautiful? Not just visually, but also in terms of its composition?

There are multiple ways to compose the symbol. Do you like the way in which you did it? Did you use names for various pieces? Did you inline everything into one "giant" expression? Or did you even create additional functions for creating the various pieces? You can always refactor between the various ways.

If your implementation is easy to understand, for you and for others you show it to, you have a good reason to feel proud!


This activity has been created by LuCE Research Lab and is licensed under CC BY-SA 4.0.

Yin Yang

Logo of PyTamaro

PyTamaro is a project created by the Lugano Computing Education Research Lab at the Software Institute of USI

Privacy PolicyPlatform Version c08406b (Wed, 20 Nov 2024 12:30:00 GMT)