# Jigsaw Puzzle (Parsonâ€™s Problem) Programming ExampleÂ¶

Rearrange the following statements so that a random DNA base is printed and its index in the string. Not all statements may be needed. Feel free to use/add intermediate variables.

```bases="ACTTGCTTGAC"
import math
import random
___ = random.randrange(n_bases)
___ = len(bases)
print("random base ", bases[___], "base index", ___)
```

{: .language-python}

# SolutionÂ¶

```import math
import random
bases = "ACTTGCTTGAC"
n_bases = len(bases)
idx = random.randrange(n_bases)
print("random base", bases[idx], "base index", idx)
```

{: .language-python} {: .solution} {: .challenge}

# When Is Help Available?Â¶

When a colleague of yours types `help(math)`, Python reports an error:

```NameError: name 'math' is not defined
```

{: .error}

What has your colleague forgotten to do?

# SolutionÂ¶

Importing the math module (`import math`) {: .solution} {: .challenge}

# Importing With AliasesÂ¶

1. Fill in the blanks so that the program below prints `90.0`.

2. Rewrite the program so that it uses `import` without `as`.

3. Which form do you find easier to read?

```import math as m
angle = ____.degrees(____.pi / 2)
print(____)
```

{: .language-python}

# SolutionÂ¶

```import math as m
angle = m.degrees(m.pi / 2)
print(angle)
```

{: .language-python}

can be written as

```import math
angle = math.degrees(math.pi / 2)
print(angle)
```

{: .language-python}

Since you just wrote the code and are familiar with it, you might actually find the first version easier to read. But when trying to read a huge piece of code written by someone else, or when getting back to your own huge piece of code after several months, non-abbreviated names are often easier, except where there are clear abbreviation conventions. {: .solution} {: .challenge}

# There Are Many Ways To Import Libraries!Â¶

Match the following print statements with the appropriate library calls.

Print commands:

1. `print("sin(pi/2) =", sin(pi/2))`

2. `print("sin(pi/2) =", m.sin(m.pi/2))`

3. `print("sin(pi/2) =", math.sin(math.pi/2))`

Library calls:

1. `from math import sin, pi`

2. `import math`

3. `import math as m`

4. `from math import *`

# SolutionÂ¶

1. Library calls 1 and 4. In order to directly refer to `sin` and `pi` without the library name as prefix, you need to use the `from ... import ...` statement. Whereas library call 1 specifically imports the two functions `sin` and `pi`, library call 4 imports all functions in the `math` module.

2. Library call 3. Here `sin` and `pi` are referred to with a shortened library name `m` instead of `math`. Library call 3 does exactly that using the `import ... as ...` syntax - it creates an alias for `math` in the form of the shortened name `m`.

3. Library call 2. Here `sin` and `pi` are referred to with the regular library name `math`, so the regular `import ...` call suffices. {: .solution} {: .challenge}

# Importing Specific ItemsÂ¶

1. Fill in the blanks so that the program below prints `90.0`.

2. Do you find this version easier to read than preceding ones?

3. Why wouldnâ€™t programmers always use this form of `import`?

```____ math import ____, ____
angle = degrees(pi / 2)
print(angle)
```

{: .language-python}

# SolutionÂ¶

```from math import degrees, pi
angle = degrees(pi / 2)
print(angle)
```

{: .language-python}

Most likely you find this version easier to read since itâ€™s less dense. The main reason not to use this form of import is to avoid name clashes. For instance, you wouldnâ€™t import `degrees` this way if you also wanted to use the name `degrees` for a variable or function of your own. Or if you were to also import a function named `degrees` from another library. {: .solution} {: .challenge}

1. Read the code below and try to identify what the errors are without running it.

2. Run the code, and read the error message. What type of error is it?

```from math import log
log(0)
```

{: .language-python}

# SolutionÂ¶

1. The logarithm of `x` is only defined for `x > 0`, so 0 is outside the domain of the function.

2. You get an error of type â€śValueErrorâ€ť, indicating that the function received an inappropriate argument value. The additional message â€śmath domain errorâ€ť makes it clearer what the problem is. {: .solution} {: .challenge}