**Make sure all programs are saved to your cs21/labs/02 directory! Files outside that directory will not be graded.**

`$ `**update21**
$ **cd ~/cs21/labs/02/**
$ **pwd**
/home/username/cs21/labs/02
$ **ls**
QUESTIONS-02.txt text2tri.py digipet.py minmax.py border.py

- Use a comment at the top of the file to describe the purpose of the program.
- Use variable names that describe the contents of the variables.
- Write your programs incrementally and test them as you go. This is really crucial to success: test, test again, and then test some more!
- Don't assume that if your program passes the sample tests we provide that it is completely correct. Come up with your own test cases and verify that the program is producing the right output on them.

- Python numbers and strings
- String indexing
- Accumulator pattern

Write a program, `border.py`

, that prints a rectangular border around text provided by the user. The border should consist of asteriks.

`$ `**python3 border.py**
Enter text: **Ascii Adventures Forever!**
*****************************
* Ascii Adventures Forever! *
*****************************
$ **python3 border.py**
Enter text: **Sharing is caring**
*********************
* Sharing is caring *
*********************
$ **python3 border.py**
Enter text: **A**
*****
* A *
*****

You can print a blank line with `print()`

.

Write a program, `text2tri.py`

, that turns an input string into a triangle. Each row of the triangle corresponds to a single letter of the input such that the first letter is repeated once, the second letter twice, and so on. In the examples below user input is shown in **bold**.

`$ `**python3 text2tri.py**
Enter text: **Swarthmore**
S
ww
aaa
rrrr
ttttt
hhhhhh
mmmmmmm
oooooooo
rrrrrrrrr
eeeeeeeeee
$ **python3 text2tri.py**
Enter text: **X/\/\/\W**
X
//
\\\
////
\\\\\
//////
\\\\\\\
WWWWWWWW

Write a program, `maxmin.py`

, that computes the maximum and minimum of a series of numbers. You should assume that all inputs are floats.

`$ `**python3 maxmin.py**
Enter the number of items in the series: **5**
Enter a number: **2**
Enter a number: **-3**
Enter a number: **6**
Enter a number: **11.2**
Enter a number: **-56**
min: -56
max: 11.2
$ **python3 maxmin.py**
Enter the number of items in the series: **3**
Enter a number: **-45**
Enter a number: **-2**
Enter a number: **-35**
min: -45.0
max: -2.0
$ **python3 maxmin.py**
Enter the number of items in the series: **5**
Enter a number: **1**
Enter a number: **1**
Enter a number: **1**
Enter a number: **1**
Enter a number: **1**
min: 1
max: 1

Note that you can use python3's min and max functions to compute the minimum and maximum. Below in an interactive example.

```
>>> min(-1, 4)
>>> -1
>>> max(-1, 4)
>>> 4
```

You can assume that the inputs will be between -100 and 100.

A straight-forward approach to solving this problem is to create two variables: one will keep track of the smallest number; the other will keep track of the largest number. Each iteration through the loop, you will update these variables.

What if we want to support any number, not just those between -100 and 100? What's the largest and smallest number we might encounter?

It turns out we can ask Python for the largest floating point number we can represent on our machine. Python stores its value in the variable **sys.float_info.max** from the **sys** module.

```
>>> import sys
>>> print(sys.float_info.max)
>>> 1.7976931348623157e+308
```

Thus, if we initialized our min value to **sys.float_info.max**, any valid number will be less than or equal to it. Similarly, if we initialize our max value to the negative of **sys.float_info.max**, any subsequent value will be greater than or equal to it.

You might be thinking that **1.7976931348623157e+308** is a funny-looking number. This number is so large, we need to represent it in a special way, namely with scientific notation. The number above corresponds to

1.7976931348623157 × 10^{308}

If we tried to write it out, it would have A LOT of zeros in it.

Similarly, we can get the tiniest positive number too.

```
>>> print(sys.float_info.min)
>>> 2.2250738585072014e-308
```

The above number corresponds to

2.2250738585072014 × 10^{−308}

And funny things can happen when we work with numbers that are too large for the computer handle. Look what happens when we try to get a bigger number:

```
>>> maxfloat = sys.float_info.max
>>> maxfloat * maxfloat
>>> inf
>>> maxfloat * 10
>>> inf
>>> maxfloat + 10
>>> 1.7976931348623157e+308
>>> maxfloat + 100
>>> 1.7976931348623157e+308
>>> maxfloat + 1000
>>> 1.7976931348623157e+308
>>> maxfloat * 1000
>>> inf
```

At a high level, computers are limited in the numbers they can represent because there is a limit on how many bits we have to represent them. The more bits available per float, the larger (or smaller) the numbers can be.

**Extra Challenge** For bragging rights, try to extend your program to work for all floating point values.

Write a program, `digipet.py`

, that allows you to care for a virtual pet. Each day you must feed your pet. Your pet starts with a weight of 100 pounds. You start with 100 food pellets. The user should specify how many days to simulate your virtual pet.

- Each day, your pet burns between 10 and 20 pounds.
- Every food pellet you give your pet causes it to gain 1.6 pounds.

Below is an example

`$ `**python3 digitpet.py**
Your pet weighs 100 pounds
You have 100 pellets
Enter the number of days: **3**
Day 1
Your pet lost 11 pounds and now weighs 89
How many pellets do you want to feed your pet? **10**
You fed your pet 10 pellets
Your pet gained 16.0 and now weighs 105.0 pounds
You have 90 pellets left
Day 2
Your pet lost 14 pounds and now weighs 91.0
How many pellets do you want to feed your pet? **34**
You fed your pet 34 pellets
Your pet gained 54.400000000000006 and now weighs 145.4 pounds
You have 56 pellets left
Day 3
Your pet lost 13 pounds and now weighs 132.4
How many pellets do you want to feed your pet? **0**
You fed your pet 0 pellets
Your pet gained 0.0 and now weighs 132.4 pounds
You have 56 pellets left

To complete this question, you need to be able to generate a random number between 10 and 20 inclusive. Happily, python3 gives us a function called **randrange()** which does exactly that. To use it, include the **random** module.

```
>>> import random
>>> random.randrange(9, 22)
>>> 17
>>> random.randrange(9, 22)
>>> 21
```

What numbers does **randrange** return? It works similarly to the **range(a,b)** function, which returns numbers between a and b-1. Try running **randrange** a bunch of times in Python3's interpreter to get a feel for how it works.

You may have noticed that you can feed your pet even when you run out of food! In this case, the number of fed pellets is greater than the total number of pellets. We will learn how to handle cases like this soon; for now it is okay.

`$ `**python3 digipet.py**
Your pet weighs 100 pounds
You have 100 pellets
Enter the number of days: **2**
Day 1
Your pet lost 16 pounds and now weighs 84
How many pellets do you want to feed your pet? **100**
You fed your pet 100 pellets
Your pet gained 160.0 and now weighs 244.0 pounds
You have 0 pellets left
Day 2
Your pet lost 16 pounds and now weighs 228.0
How many pellets do you want to feed your pet? **100**
You fed your pet 100 pellets
Your pet gained 160.0 and now weighs 388.0 pounds
You have -100 pellets left

**Extra challenge** (for bragging rights) Try to use the min() function to ensure you never feed your pet more pellets than you have.

Each lab has a short questionnaire at the end. Please edit the `QUESTIONS-02.txt`

file in your `cs21/labs/02`

directory and answer the questions in that file.

Don't forget to run `handin21`

to turn in your lab files! You may run `handin21`

*as many times as you want*. Each time it will turn in any *new* work. We recommend running `handin21`

after you complete each program *or* after you complete significant work on any one program.