## Avoiding repetitions: the important stuff

Remember the rule about avoiding repetitions:

Rule # 3
  When writing computer programs, do not repeat yourself.
  I repeat: do not repeat yourself!

What we are going to see in this chapter is a way to avoid "reinventing the wheel".

### 1. Remember: three lefts can make a right

Remember when we introduced the `turn_right()` instruction:

    def turn_right():
        turn_left()
        turn_left()
        turn_left()

We did that to avoid having to type `turn_left()` three times in a row every time we wanted to instruct Reeborg to turn right. However, we still have a lot of repetition since almost every time we write a new program, we end up defining `turn_right()` again. There is, however, a way to avoid this. Create the following program and try to run it.

    from useful import turn_right

    turn_right()
    turn_off()

### 2. About useful

I have created for you a fake module named "useful" containing some newly `def`ined instructions. Rather than explaining what each new instruction does, here's a sample program with the corresponding screen capture.

    from useful import *

    turn_left()
    move()
    set_trace_style(1, 'red')
    turn_right()
    set_trace_style(2, 'blue')
    move()
    set_trace_style(1, 'green')
    climb_up_east()
    set_trace_style(2, 'blue')
    move()
    set_trace_style(1, 'orange')
    turn_around()
    set_trace_style(2, 'sea green')
    climb_up_west()
    set_trace_style(1, 'red')
    turn_around()
    set_trace_style(0, 'blue') # 0 = invisible
    repeat(move, 4)
    set_trace_style(1, 'green')
    climb_down_east()
    set_trace_style(2, 'blue')
    move()
    set_trace_style(1, 'black')
    turn_around()
    set_trace_style(2, 'red')
    climb_down_west()
    turn_off()

Rather than importing every new instruction one by one, as we did in the first example with `turn_right()`, we have use the "*" notation to indicate "all definitions". Before going any further, I should probably make a few comments:

1. For those that know about Python modules, "useful" is not a true module, but a fake one that will only work within Reeborg's world. You will not be allowed to import any "real" modules and use them in RUR programs. This has been done for safety reasons.
2. A new instruction, `set_trace_style()` has been used. I could have called it
   `set_leaking_oil_colour_and_quantity()`, which might have made more sense in Reeborg's world ... but not in general programming jargon. Roughly speaking, a program trace is a way to follow the sequence of instructions as they are executed. In general, you should have no use for this instruction ... but it can become useful in tracking bugs, or in examples like the one I used.
3. from and import are two Python keywords, as can be gathered from the colour used to write them.
4. In spite of their names, some of the instructions defined within "useful" can lead to unexpected results if the robot is not in the expected orientation to start with. Something similar can happen when you import "real" Python modules; you have to be aware of the assumptions that are made for proper use of the module. I will not tell you about the assumptions made within the fake module "useful". You can find out by trying to write various programs on your own.
5. You can normally read the Python (or C) code for real-life Python modules, if you try looking for it. This can be useful in the absence of documentation, or to learn about how more experienced programmers write their code.
6. Because of the restricted nature of the fake import module, some legitimate statements (for example, when the keyword import appear in a comment) may lead to an error being reported by rur-ple.

### 3. What if I want to use the same name.

Suppose you want to use the name "turn_right" to mean something other than what is defined within useful. There are a few ways to do this.

1. You can use the statement `import useful`. When you do this, you need to add `useful.` before the name of each instruction. For example
   `useful.turn_right()` and
   `turn_right()`
   represent two different commands. The first one is defined within the module "useful" whereas the second would have to be defined by yourself elsewhere. By prepending `useful.` before each instruction, a reader can immediately refer that these instructions are defined elsewhere. [We will see another meaning of having something like `useful.` added to the name of an instruction later when we talk about Object Oriented Programming (OOP).]
2. A second way of doing a similar thing is the following:

       # The following is useful for French speakers:
       from useful import turn_right as vire_a_droite

       # Use it:
       vire_a_droite()
       turn_off()

The word `as` is almost a Python keyword. It is very likely that it will become a keyword in a later version of Python. We will explain what is meant by this statement when we talk about variables.

### 4. Perhaps not so useful after all ...

If you consider the potential usefulness of the module "useful" in writing your own programs ... you might think that it is too limited to be useful after all. You can reflect that by writing the following:

    # Importing the module
    import useful as not_so_useful_after_all

    # Use the various instructions:
    not_so_useful_after_all.turn_right()
    not_so_useful_after_all.turn_around()
    turn_off()

In real life, the normal use of this type of `import` statement is more along the following lines:

    # Importing the module
    import module_with_very_very_very_long_name as short_name

    # Use the various instructions:
    short_name.instruction1()
    short_name.instruction2()

### 5. Why import at all?

It is often said that Python comes with batteries included. That is to say, Python includes many useful modules written by very smart people. These modules have been thoroughly tested to be free of bugs and written very efficiently. When you learn more about Python and you want to write your own "complicated" programs, it will be really worthwhile to first determine if any relevant module already exists and which could help you in your task. I will introduce you to a few useful modules in later lessons.

Important note to teachers: as alluded to above, the reason to restrict the usage of import statements is to avoid someone getting hold of an unsafe script and passing it along to an unsuspecting victim. Note that this can still be done in the Python editor window but, hopefully, by then students will know enough to check programs given by "friends" before trying them out. That being said, if you are familiar with Python it is fairly easy to introduce a small change in the source code of rur-ple to allow arbitrary import statements. This can be useful in a classroom setting. Please contact the author if you have a need to do this, and cannot figure it out on your own.

A touch of class. - - Random escapes.