PySAL is released in a few different *modules*. Following are some notes on these modules and their packages:

- PySAL Lib Module (https://pysal.org/lib/) – This is primarily support for the other modules. You may need to refer to it, but should not prepare a tutorial on this module directly.
- PySAL Explore Module (https://pysal.org/explore/) – A group of modules for statistical and visual data exploration. Any of these would be suitable. In particular, you might be interested in:
- esda (https://pysal.org/esda/index.html) – Spatial cluster analysis, including calculation and visualization of global and local Moran’s I. Also pay attention to the splot package: https://nbviewer.org/github/pysal/splot/blob/main/notebooks/esda_morans_viz.ipynb
- inequality (https://inequality.readthedocs.io/en/latest/) – Tools for spatial inequality analysis.
- segregation (https://pysal.org/segregation/) – Tools for spatial segregation analysis.
- spaghetti (https://pysal.org/spaghetti/) – Network analysis, including route planning (shortest path).

- PySAL Model Module (https://pysal.org/model/) – These are several packages for statistical analysis. In most cases, you will be best served if you already have familiarity with the specific analytical methods, e.g. through having taken GUS 5162. But if something is of interest to you, don’t let that stop you. In particular, I think the following packages will probably be fairly accessible even if you’ve not familiar with the analytical methods:
- spopt (https://pysal.org/spopt/) – Spatial optimization/regionalization, e.g., creating service areas.
- tobler(https://pysal.org/tobler/) – Areal allocation, dasymetric mapping, and hexgrids.

- PySAL Viz Module (https://pysal.org/viz/) – May be incorporated into other presentations, but these packages are too basic to support a tutorial on their own. I may present some of this information in other classes.

In many of the following exercises, you are asked to collect results in a list, string, or other data structure. The collector must be initialized as an empty list (`[]`

) or an empty string (`""`

) *before* the loop, and then each element added to the end of the list or string inside the loop.

For these exercises, begin by setting a variable to any word or short string:

```
test_string = "sample"
```

For some of these examples, you should use a string that has some numbers in it, such as:

```
test_string = "My phone number is 800.555.1212"
```

There are many functions which can do simple things like count the number of letters (`len`

) or counting the number of specific letters (`str.count()`

). Do *not* use these, as the purpose is to practice looping over strings.

- Count the number of letters.
- Count the number of “a”-s in the word.
- Count the number of “s”-s in the word.
- Count the number of spaces in the word.
- Count the number of characters that are
*not*lowercase letters. Import the`lowercase`

constant from the`string`

module to do this. - Count the number of characters that are
*not*letters (either upper or lowercase). - Count the number of letters in the string that are from the first half of the alphabet, A-M (case insensitve).
- Count the number of vowels (case insensitive). Use the string
`"AEIOU"`

for comparison. - Count the number of digits. Import the
`digits`

constant from the`string`

module to do this. - Build a string that contains only the digits, and no other characters.
- Build a string that has all the characters of the input string, but uppercases all the vowels.
- Build a string that has all the characters of the input string, but uppercases all the vowels and lowercases all other characters.

For these exercises, begin by pasting any large block of text into a string. The following is fake text, I suggest using something in a language that you can read.

```
test_string = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
```

Convert the string to a list of individual words using the `str.split()`

method.

- Count the number of words that begin with “a” (case insensitive).
- Count the number of words that begin with “b” (case insensitive).
- Count the number of words that end with “s” (case insensitive).
- Count the number of words that end with “it” (case insensitive).
- Count the number of words that begin with a capital letter.
- Count the number of one-letter words.
- Count the number of two-letter words.
- Count the number of words of five or more letters.
- Build a list that contains the number of letters in each word, using the
`len`

function. (**Example:**`"My paragraph"`

→`[2, 9]`

) - Build a list that contains each word in a sentence of the form
`"The word is ____."`

. - Build a list where each item is a sentence with the word, and the length of the word, in the form
`"____ has ____ letters."`

- Build a list where each item is a sentence saying what letter the word starts with, capitalized, in the form
`"____ starts with ____."`

- Build a list that contains only those words that begin with “a” (case insensitive).
- Build a list that contains only those words begin with a capital letter.
- Build a list that contains only those words that have four letters, but uppercase all the words in the list.
- Build a list that capitalizes all words in the input list.
- Build a list that contains all words in the input list, but capitalizes all words of four or more letters.

For these exercises, use the range function to generate a range of integers of any length (e.g. `range(20)`

).

- Count the number of even numbers. An even number is an integer that, when divided by two, has no remainder.
- Count the number of odd numbers. An odd number is an integer that, when divided by two, has a remainder of one.
- Add all the numbers in the range. Do
*not*use the sum function. Instead, iterate the range, and at each step add current value to the previously accumulated value. - Build a list that contains all the numbers plus 10.
- Build a list that contains all the numbers times two.
- Build a list that contains all the numbers converted to strings.
- Build a list that contains all the numbers plus 1 converted to strings.
- Build a list that contains all the numbers converted to floats.
- Assuming that the numbers are Celsius temperature measurements, build a list that converts all the numbers to Fahrenheit.
- Build a list containing the lagged value at each position, that is, the value of the
*previous*item in the range.**Do not use list slicing to accomplish this.**Iterate the range and figure out how to access the previous value at each step in the loop. If there is no previous value, use the value`None`

. - Build a list containing the second lagged value at each position, that is, the value of the item
*two steps earlier*in the range.**Do not use list slicing to accomplish this.**Iterate the range and figure out how to access the value of the second lag at each step in the loop. If there is no second lag, use the value`None`

. - Build a list that contains the change between values by subtracting the
*previous*value from the*current*value during each step in the loop. If there is no previous number, the change should be`None`

. - The Fibonacci sequence is constructed by adding the previous two terms in the sequence. The sequence starts with 0 and 1. Thus, the first few terms are 0, 1, 1, 2, 3, 5, 8, 13, … . Build a list of Fibonacci numbers by looping over the range, adding the first lag and the second lag.

For these exercises, you will build a list of the *triangle numbers*. A triangle number is the sum from 1 to *n* of a natural number:

```
1 = 1
1 + 2 = 3
1 + 2 + 3 = 6
1 + 2 + 3 + 4 = 10
1 + 2 + 3 + 4 + 5 = 15
etc.
```

Keep in mind that ranges begin at 0, so `range(3)`

generates 0, 1, 2 while you want the first numbers in the list to be 1, 3, 6. Account for the zero-based counting however you want to construct triangle numbers beginning with 1.

- Build a list of triangle numbers by iterating a range. Calculate each triangle number by using the
`sum`

function on an appropriate range object. - Build a list of triangle numbers by iterating a range. Calculate each number by adding, at each step in the loop, the
*current*value to the previously accumulated value. That is, if the current value is 5, the previous triangle number is 10, so the new triangle number is 15. - Build a list of triangle numbers by iterating a range using a nested loop. At each step in the loop, calculate the triangle number by iterating a new range for the current value. For example, when the outer loop is at step 4, iterate
`range(4)`

, adding each item in the range to get the triangle number.

The `print`

function takes multiple arguments and concatenates them:

```
a = 2
b = 3
print("The sum of", a, "and", b, "is", a + b)
```

```
The sum of 2 and 3 is 5
```

Notice that a space (`" "`

) is added between each argument, or you can specify a different “separator” with the `sep=`

parameter.

To add a period at the end, use the `end=`

parameter. Make sure to include a newline (`\n`

):

```
print("The sum of", a, "and", b, "is", a + b, end=".\n")
```

```
The sum of 2 and 3 is 5.
```

Since the plus (`+`

) sign can also be used for string concatenation, it is possible to build the output message in the following manner:

```
a = 2
b = 3
print("The sum of " + str(a) + " and " + str(b) + " is " + str(a + b) + ".")
```

Using commas to separate arguments is more compact and, I think, more readable. It also avoids having to wrap the numeric variables in a `str()`

conversion.

The `format`

function can be used with `print`

to output a message with embedded variables.

```
a = 2
b = 3
print("The sum of {} and {} is {}.".format(a, b, a + b))
```

```
The sum of 2 and 3 is 5.
```

Note that the braces can be given a positional index (`{0}`

, `{1}`

) or a keyword (`{name}`

, `{time}`

, etc., following normal rules for variable naming) which allows you to reuse a parameter at different positions within the string.

If you intend to reuse the message statement, it is useful to assign to a variable:

```
msg = "The sum of {} and {} is {}."
a = 2
b = 3
print(msg.format(a, b, a + b))
```

```
The sum of 2 and 3 is 5.
```

```
c = 8
d = 7
print(msg.format(c, d, c + d))
```

```
The sum of 8 and 7 is 15.
```

In the past, students doing online searches for Python string formatting have sometimes discovered another way to insert variable values into a string:

```
"The sum of %d and %d is %d" % (a, b, a + b)
```

This is considered **old style** formatting, and you should not use it in this course.

`print`

documentation`input`

documentation- Fancier Output Formatting — More extensive discussion of ways to format output messages using
`print`

,`format`

, and other functions.