diff --git a/docs/PythonIntro.zip b/docs/PythonIntro.zip deleted file mode 100644 index 66579ea..0000000 Binary files a/docs/PythonIntro.zip and /dev/null differ diff --git a/docs/Python_asASecondLanguage_overview.pdf b/docs/Python_asASecondLanguage_overview.pdf deleted file mode 100644 index 30b32dd..0000000 Binary files a/docs/Python_asASecondLanguage_overview.pdf and /dev/null differ diff --git a/docs/Python_intro-builtin_datatypes.pdf b/docs/Python_intro-builtin_datatypes.pdf deleted file mode 100644 index 623dad9..0000000 Binary files a/docs/Python_intro-builtin_datatypes.pdf and /dev/null differ diff --git a/docs/Python_intro-control_flow.pdf b/docs/Python_intro-control_flow.pdf deleted file mode 100644 index dd41130..0000000 Binary files a/docs/Python_intro-control_flow.pdf and /dev/null differ diff --git a/docs/Python_intro-dataContainers.pdf b/docs/Python_intro-dataContainers.pdf deleted file mode 100644 index ade13fc..0000000 Binary files a/docs/Python_intro-dataContainers.pdf and /dev/null differ diff --git a/docs/Python_intro-functions.pdf b/docs/Python_intro-functions.pdf deleted file mode 100644 index 6126eaa..0000000 Binary files a/docs/Python_intro-functions.pdf and /dev/null differ diff --git a/docs/Python_intro-io.pdf b/docs/Python_intro-io.pdf deleted file mode 100644 index 3e7cb09..0000000 Binary files a/docs/Python_intro-io.pdf and /dev/null differ diff --git a/docs/Python_intro-syntax.pdf b/docs/Python_intro-syntax.pdf deleted file mode 100644 index 94309f0..0000000 Binary files a/docs/Python_intro-syntax.pdf and /dev/null differ diff --git a/docs/Python_intro-userEnvironments.pdf b/docs/Python_intro-userEnvironments.pdf deleted file mode 100644 index 2e65f2b..0000000 Binary files a/docs/Python_intro-userEnvironments.pdf and /dev/null differ diff --git a/docs/Python_intro-variables_operators.pdf b/docs/Python_intro-variables_operators.pdf deleted file mode 100644 index 4e980ca..0000000 Binary files a/docs/Python_intro-variables_operators.pdf and /dev/null differ diff --git a/docs/python_install_miniforge.pdf b/docs/python_install_miniforge.pdf deleted file mode 100644 index 65d145b..0000000 Binary files a/docs/python_install_miniforge.pdf and /dev/null differ diff --git a/scripts/GJB_data_types_recap.ipynb b/scripts/GJB_data_types_recap.ipynb new file mode 100644 index 0000000..048de6b --- /dev/null +++ b/scripts/GJB_data_types_recap.ipynb @@ -0,0 +1,2170 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Python data types" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Acknowledgment\n", + "Geert-Jan Bex\n", + "\n", + "source: https://github.com/gjbex/training-material/tree/master/Python/Fundamentals\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Python has quite a number of built-in data types, i.e., data types that are part of the core language. However, the standard library implements quite a number of additional data types, many of which also simplify your task as a developer. We will not cover each and every method that are defined for these data structures, but only those that are most commonly used. As always, it is a good idea to read through the [documentation](https://docs.python.org/3/library/index.html) for more information." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For this tutorial, we will use a very simple data file that allows us to illustrate use cases for Python's data types. The data file is a text file, with three columns. It represents patients by listing their first name, their age, and their weight. The data types are `str`, `int`, and `float` respectively. Colums are separated by spaces." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "!notepad Data/patients.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use `try`-`except` to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\n", + "from traceback import print_exc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Tuples" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It would be convenient to have a function that reads throught the file, and returns the patients one at the time. But how to represent a patient so that it can be returned as a value from a function? We can represent a patient as a tuple with three fields. The first represents the patient's name, the second her age, the third her weight." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "patient = ('suzan', 15, 48.9)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The type of this data structure is `tuple`, and we can access the values of its fields by 0-based index. The number of fields can be determined using the `len` function." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tuple" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "type(patient)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'suzan'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "patient[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(patient)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similar to a `str` in Python, a `tuple` is immutable, i.e., it can not be modified after its creation. So no birthdays for our patients." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Traceback (most recent call last):\n", + " File \"\", line 2, in \n", + " patient[1] = 16\n", + "TypeError: 'tuple' object does not support item assignment\n" + ] + } + ], + "source": [ + "try:\n", + " patient[1] = 16\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A `tuple` seems a reasonable data type to represent our patients, so let's proceed with the function to read them." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def read_patients(file_name):\n", + " '''\n", + " Generator function that yields the patients in a file.\n", + " file_name: name of the data file\n", + " returns tuples representing the patients\n", + " '''\n", + " with open(file_name, 'r') as patients:\n", + " # read but ignore the column names, special use of underscore\n", + " # underscore considered a general purpose \"throwaway\" variable name to indicate \n", + " # that it is being deliberately ignored \n", + " _ = patients.readline()\n", + " # iterate over all the patient data\n", + " for line in patients:\n", + " # strip the line endings, and split on whitespace\n", + " data = line.rstrip().split()\n", + " # turn this function into a generator by yielding a tuple\n", + " # representing a patient; for convenience, do appropriate\n", + " # type conversion\n", + " yield (str(data[0]), int(data[1]), float(data[2]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `yield` statement interrupts the execution of the function, returning a value. When the function is called again, execution will resume from that same point in the function, retaining state." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's test the function by simply printing the results." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for patient in read_patients('Data/patients.txt'):\n", + " print(patient)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That seems to work quite well. Let's proceed with some data analytics." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Named tuples" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although this implementation works, it has a drawback. We have to remember that `patient[0]` is the name, `patient[1]` the age, and `patient[2]` the weight of the patient. This is error-prone, and may give rise to subtle bugs. It would be much more convenient if we could access the `tuple`'s fields by name, rather than by index. Python's standard library implements a convenient way to define named tuples through `typing.NameTuple`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import NamedTuple\n", + "\n", + "class Patient(NamedTuple):\n", + " name: str\n", + " age: int\n", + " weight: float" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will cover defining our own classes elsewhere, but this is quite staightforward. Note that `typing.NamedTuple` was introduced in Python 3.5, for earlier version of Python, you can use the somewhat more cumbersome `collections.namedtuple`. A named tuple of type `Patient` has three fields, `name`, `age`, and `weight`, which we declare using type hints, `str`, `int`, and `float` respectively. Let's redefine the tuple representing Suzan." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient = Patient('suzan', 15, 48.9)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The type of this data structure is `Patient`, and we can access the values of its fields by 0-based index, but also by name. The number of fields can be determined using the `len` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "type(patient)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient[0], patient.name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(patient)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Similar to Python's built-in `tuple`, a named tuple is immutable, i.e., it can not be modified after its creation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " patient.age = 16\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Modifying the function `read_patients` to return named tuples is trivial." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def read_patients(file_name):\n", + " '''\n", + " Generator function that yields the patients in a file.\n", + " file_name: name of the data file\n", + " returns named tuples representing the patients\n", + " '''\n", + " with open(file_name, 'r') as patients:\n", + " # read but ignore the column names\n", + " _ = patients.readline()\n", + " # iterate over all the patient data\n", + " for line in patients:\n", + " # strip the line endings, and split on whitespace\n", + " data = line.rstrip().split()\n", + " # turn this function into a generator by yielding a tuple\n", + " # representing a patient; for convenience, do appropriate\n", + " # type conversion\n", + " yield Patient(str(data[0]), int(data[1]), float(data[2]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To illustrate, let's read the patient, but only print their names." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for patient in read_patients('Data/patients.txt'):\n", + " print(patient.name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Lists" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A `list` is a very convenient data type, representing an ordered sequence. We can for instance create a list of names of our patients." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names = list()\n", + "for patient in read_patients('Data/patients.txt'):\n", + " patient_names.append(patient.name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We start off with an empty list, created using the `list()` function, and we append the name of each patient to it. The resulting list contains the patient names, in the order they have been read from the file, and added to the list `patient_names`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "List elements can be accessed by 0-based index, and the length of a list can be obtained using the `len` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(patient_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Trying to access an element using an invalid index, e.g., one that is larger than the length of the `list` raises an exception." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " print(patient_names[len(patient_names)])\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can iterate over the elements of a `list` using a `for`-loop." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for patient_name in patient_names:\n", + " print(patient_name.capitalize())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In contrast to a `tuple`, the elements of a list can be modified, for instance, if we want to change `'bob'` to `'robert'`, we can just do that." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[1] = 'robert'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for patient_name in patient_names:\n", + " print(patient_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Surreptitiously, we have already used a `list` when we used the `split` method on the lines of our data file. The inverse operation, converting a `list` of `str` type elements can be accomplished using the `join` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(patient_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that `join` is a method defined on a `str`, the separator, and that is argument must be an iterable over `str` values." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Indices can be negative, for instance the element at index `-1` would be the last element of the list, `-2` the second but last, and so on. Hence, if the list has $n$ elements, legal index values run from $-n$ to $n - 1$. Although that is a nice shortcut, it is also a good way to introduce subtle bugs in your code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[-1] == patient_names[len(patient_names) - 1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[0] == patient_names[-len(patient_names)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Modifying & querying lists" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Whereas the number of fields of a `tuple` is always the same, elements can be added to or removed from a list at any time. Besides the `append` method we have already used to build the list, there is the `insert` method to add elements anywhere in the list, and the `pop` method to remove elements." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.insert(2, 'kathy')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for patient_name in patient_names:\n", + " print(patient_name)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.pop(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Our `patient_names` list now has `'kathy'` as the third element, while `'elly'` is no longer an element." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(patient_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the `pop()` method without an index will remove and return the list's last element, `'john'` in this case." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.pop()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Checking list membership is easy using the `in` operator, for instance, `'robert'` is in our list, while `'mary'` isn't." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "'robert' in patient_names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "'mary' in patient_names" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `index` method will return... the index at which an element first occurs in a list, and raises an exception otherise." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.index('robert')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " patient_names.index('mary')\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the same element can occur multiple times in a list, for instance, we can add another `'alice'` at the end of the list." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.append('alice')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `index` method will only return the index of the first occurence. However, since it can optionally be called with a start, and and end index, we can also search from the end of the list." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.index('alice')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.index('alice', -1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `pop` method removes an element at a given index, the `remove` method removes an element by value. If we remove `'alice'` from the list, only the `'alice'` at the end of the list will remain. Removing a value that doesn't occur in the list will raise an exception." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(patient_names)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names.remove('alice')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just as for the `index` method, using -1 as a start index would remove the last `'alice'` from the `list`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(patient_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Aliasing versus copying" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It may be a bit counter-intuitive, but assigning a list to a new variable doesn't copy the list. The new variable refers to the same list as the original one. We assign `patient_names` to another variable, remove the first element, and check the value of both variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "other_patient_names = patient_names" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "other_patient_names.pop(0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(other_patient_names)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(patient_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `copy` method will create an actual copy of the original list." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "other_patient_names = patient_names.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "other_patient_names.pop()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(other_patient_names)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "', '.join(patient_names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Slicing" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can create sublists out of list by \"slicing\", i.e., indexing by a start index, and end index, and, optionally, a stride. For instance, we could select the first three elements of the list, or the second to the sixth element, but only every other element." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[0:3]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[1:6:2]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Both the start and end index can be left out, that means that the slice starts from the beginning, or runs up to the end of the list respectively. Combined with negative indices, this is quite expressive. Getting the first, or the last three elements of list is quite trivial that way." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[:3]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[-3:]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Leaving out both start and end index, and using a stride of -1 is a neat thrick to reverse a list." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patient_names[::-1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that slicing creates a new list, but that it is a shallow copy. This is important when list elements are mutable." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creating lists" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The simplest way to construct a list is by a literal enumeration of its elements." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "first_names = ['peter', 'sally', 'vaughan', 'sophie', 'patrick']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, new lists can be constructed from iterables by comprehension. For instance, a list of capitalized names can be constructed." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[name.capitalize() for name in first_names]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is also possible to select only certain elements for the new list by adding an `if` clause to the comprehension." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[name.capitalize() for name in first_names if name.startswith('p')]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Returning to our running example, we can combine this to select the names of the patients that are older than 35." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[patient.name for patient in read_patients('Data/patients.txt') if patient.age > 35]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the `list` function, we can also create a list of the patients in our data file using the generator." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "patients = list(read_patients('Data/patients.txt'))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# read_patients returns a named tuple\n", + "patients" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(patients[0].age)\n", + "print(patients[6].name)\n", + "print(patients[-1].weight)\n", + "\n", + "# can the age be updated?\n", + "patients[0].age = 88" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lists can be concatenated using the `+` operator, or extended throught the `extend` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "['alice', 'bob'] + ['carol', 'dave']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Which ages are represented in our group of patients? When we want to answer this question, we actually ask for a mathematical set containing the ages, each element of the set occurs only once. We could accomplish this using a `list` as well, but that would be pretty cumbersome." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_list = list()\n", + "for patient in read_patients('Data/patients.txt'):\n", + " if patient.age not in age_list:\n", + " age_list.append(patient.age)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using Python's built-in `set` type, this task is not only easier, but the data structure represents the mathematical concept we actually have in mind." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_set = set()\n", + "for patient in read_patients('Data/patients.txt'):\n", + " age_set.add(patient.age)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_set" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is even simpler using a set comprehension, similar to the list comprehension we've encountered before." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_set = {patient.age for patient in read_patients('Data/patients.txt')}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_set" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The number of elements of a `set` is obtained using the `len` function, and we can test membership using the `in` operator." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(age_set)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "40 in age_set" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "53 in age_set" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As opposed to a `list`, a `set` is not a sequence, i.e., it is not ordered, it has no first, second, or last element. This is of course the same for a mathematical set, which is obviously no coincidence." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Iterating over the elements of a `set` is done using a `for`-loop." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for age in age_set:\n", + " print(age)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Modifying sets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `add` method adds an element to an existing set. To remove an element, we can use the `pop()` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_set.pop()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that the element that is removed is random (well, implementation dependent, to be precise). To remove an element from the set, you can use either the `remove` or `discard` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_set.remove(41)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " age_set.remove(41)\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `discard` method will not raise an exception when we try to remove an element that is not in the set. To remove all elements from a `set`, we can use the `clear` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_set.clear()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(age_set)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Set operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All the mathematical operation you would expect on sets are indeed defined, e.g., union (`|`), intersection (`&`), difference (`-`), symmetric difference (`^`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set1 = {1, 2, 3, 4, 6, 12}\n", + "set2 = {1, 3, 5, 15}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set1 | set2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set1 & set2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set1 - set2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set2 - set1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set1 ^ set2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All operations create a new set, an method to perform these operations in place is implemented, mainly for performance reasons. For example, `difference_update` applied to `set1` would modify that set." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set1.difference_update(set2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "set1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Three Boolean methods are available as well,\n", + " * `s1.isdisjoint(s2)` will test whether the sets are disjoint,\n", + " * `s1.issubset(s2)` will check whether `s1` is a subset of `s2`, and\n", + " * `s1.issuperset(s2)` checks whether `s1` is a superset of `s2`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dictionaries" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A `dict` is a mapping from a set of keys to a map of values, each key maps onto exactly one value, but multiple keys may map the the same value. This corresponds to a mathematical relation called an injection. `dict`s are a very convenient data type to represent associations between objects." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "back to the running example. What if we want to know how many patient there are of each age? So with an age, we want to associate a count. We can represent this by a dictonary that has a patient's age as keys, and the number of patients at that age as values." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr = dict()\n", + "for patient in read_patients('Data/patients.txt'):\n", + " if patient.age not in age_distr:\n", + " age_distr[patient.age] = 0\n", + " age_distr[patient.age] += 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We start off with an empty `dict`, and iterate over the patients as usual. For each patient, we check whether her age is in the `dict` as a key using the `in` operator. If not, we associate the value 0 with that key. Next, we increment the value associated with the key.` " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can get the value associated with a key by using the latter as an index, and we can get the number of key/value pairs using the `len` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr[33]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(age_distr)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Trying to access a `dict` with a key not in the `dict` raises an exception." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " print(age_distr[-5])\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can iterate over the keys in a dictionary, and use that to access the corresponding value." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# using the f format\n", + "# https://www.datacamp.com/community/tutorials/f-string-formatting-in-python\n", + "for age in age_distr:\n", + " print(f'{age}: {age_distr[age]}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This pattern is so common that the `items` method is defined for `dict`s. When called, this method yields `tuple`s where the first field is the key, the second the value." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for age, count in age_distr.items():\n", + " print(f'{age}: {count}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that starting from Python 3.6, keys and item are returned in insertion order. For older version of Python, the order can and should not be relied on." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Modifying dictionaries" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "New items can be added to a `dict` at any time, or existing values can be updated by assignment." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr[20] = 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr[20] = 4" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "An item can be removed from the `dictt` using the `remove` method, which takes the key as an argument. The value associated with that key is returned. If we try to remove an item with a key that is not in the `dict`, an exception is raised." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "age_distr.pop(20)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " age_distr.pop(20)\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just like sets and lists, dictionaries can also be constructed using comprehensions. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Just like sets and lists, dictionaries can also be constructed using comprehensions. We will create some people with random ages." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "from random import randint\n", + "random.seed(1234)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "people = {name: randint(20, 40) for name in ['zoe', 'wolf', 'thomas']}\n", + "people" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "more_people = {name: randint(20, 40) for name in ['elsie', 'frank', 'thomas']}\n", + "more_people" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Two dictionaries can be merged using the `update` method, which modifies the `dict` in-place." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "people.update(more_people)\n", + "people" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The items of `more_people` have been added to `people`, overwriting the original value when an item with that key already existed." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Nesting data structures" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With the excpetion of our list of patients, `list` of `tupule`, all the example we consided so far had elements that were simple types like `str`, `int` or `float`. However, it is possible, and often useful to build more complicated data structures out of `list`, `set`, and `dict`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For example, we could represent a matrix as a `list` of `list`, where each element of the outer `list` represents a row of the matrix. (This is just for illustration purposes, for mathematical applications, you would use numpy arrays, both for performance and features.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "rows = 3\n", + "cols = 4\n", + "matrix = list()\n", + "for i in range(rows):\n", + " matrix.append(list())\n", + " for j in range(cols):\n", + " matrix[i].append(i*cols + j)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix[1][2]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix[0][3] = -17" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Shallow copying" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Shallow copies? Let's explore that here. We create a copy of our matrix, and modify it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "new_matrix = matrix.copy()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can add an extra row to `new_matrix`, and `matrix` is unaffected since we created a copy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "new_matrix.append([3, 9, 7, 5])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, we modify and element of `new_matrix`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "new_matrix[0][0] = 103" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "new_matrix" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is all as expected, but inspecting `matrix` may yield a surprise." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix[0][0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It seems that the elements of `matrix` and `new_matrix`, i.e., the first three rows, are the same `list` objects. However, `matrix` and `new_matrix` themselves are distinct objects. This is easy to verify using the `is` operator that tests object identify." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix[0] is new_matrix[0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "matrix is not new_matrix" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Clearly, the `copy` method produces a shallow copy of the original data structure. Although we illustrated this for `list`, the same is true for both `set` and `dict` as well." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Limitations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can store elements of type `list`, `set` and `dict` in lists without issues. For instance, we can create a `list` of `set`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_sets = list()\n", + "for size in range(5):\n", + " list_of_sets.append(set(range(size)))\n", + "list_of_sets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, not everything can be stored in a `set` or a `dict`. For instance, if we try to create a `set` of lists, an exception is raised." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " set_of_lists = set()\n", + " for size in range(5):\n", + " set_of_lists.add(list(range(size)))\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some types in Python are 'hashable', while others are not. For instance, a `float` has a `__hash__` function, while a `list` has not." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(17.3).__hash__()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " list_of_sets.__hash__()\n", + "except:\n", + " print_exc()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This implies that only values of types that have a `__hash__` method implemented, and are, by definition, 'hashable' can be stored in a `set`, or used as *keys* in a `dict`. Any type can occur as *value* in a `dict` though, regardless of whether it is hashable or not." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Smell" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you are using nested data structures, that might actually a code smell, i.e., an indicator that your code design could stand improvement. Quite often, it means that it is time to consider introducing classes to represent the concepts you are trying to model." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Choices, choices, choices..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How to pick the correct data structure? Of course, there are quite a number of considerations. However, as a rule of thumb, if you pick a data structure that corresponds to the mathemaical model you have in mind while programming, that is probably a good start.\n", + " * Tuples can represent elements of carthesian products of sets.\n", + " * Lists represent ordered sequences of objects.\n", + " * Sets repreesent... well, mathematical sets.\n", + " * Dictionaries represent mathematical relations, or associations." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sometimes, your code can be simplified by picking the right data type. For instance, if you find yourself representing something, say, the information on a patient, by a list, and for each patient, the same information is available, and you don't change it in your code, than you might want to replace the list by a tuple.\n", + "\n", + "Similarly, when you represent that information by a dictionary, you can replace it by a named tuple.\n", + "\n", + "If you use a list, but add some item only when it isn't an element yet, you may want to use a set." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Another consideration is performance, some operations are fast on certain data structures, slow and others, and vice versa. Take membership test for example, this is a lot faster on a set, than on a list. In fact, for large number of elements, the difference can be huge." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "s = set(range(1_000_000))\n", + "l = list(range(1_000_000))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%timeit 1_000_001 in s \n", + "1_000_001 in s " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%timeit 1_000_001 in l\n", + "1_000_001 in l" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# magic command\n", + "%lsmagic" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Other standard library data structures" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Python's standard library contains many additional data structures, some quite specialized. We will only discuss a few here that might prove useful. Again, it pays of to read through the documentation to familiarize yourself with what is available." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Arrays" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Although arrays are very useful data structures, the implementation in Python's standard library is not so great. However, they can be useful to get some extra performance if you can not use numpy for some reason, or if you require interoperatbility with C. As opposed to lists, array elements all have the same type, and that is specified when you crate the array. Although `array` supports methods such as `append`, `insert` and `pop`, you would probably want to avoid those for performance reasons." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from array import array" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "weights = array('d', (patient.weight for patient in read_patients('Data/patients.txt')))\n", + "weights" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Elements can be accessed by index, and can be modified. The length of an `array` can be determined using the `len` function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "weights[1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "weights[0] = 59.3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len(weights)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Contrary to what you might expect, the `+` operator represents array concatenation, rather than element-wise addition. Hence to do mathematics on arrays in Python, numpy is the way to go" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "weights + weights" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/scripts/MOCK_DATA.csv b/scripts/MOCK_DATA.csv new file mode 100644 index 0000000..c318778 --- /dev/null +++ b/scripts/MOCK_DATA.csv @@ -0,0 +1,1001 @@ +id,first_name,last_name,email,gender,ip_address,date,parts,unit cost +1,Lurette,Rounsefull,lrounsefull0@cbsnews.com,Female,208.52.245.134,4/11/2019,1,1425.64 +2,Peder,Heineking,pheineking1@mac.com,Male,216.60.184.211,5/15/2019,79,2666.57 +3,Haydon,Birdsall,hbirdsall2@spotify.com,Male,161.74.94.92,10/18/2019,27,2377.64 +4,Barbe,Mouse,bmouse3@elegantthemes.com,Female,97.202.107.43,5/16/2019,20,3375.08 +5,Sherwin,Wealthall,swealthall4@whitehouse.gov,Male,155.14.42.127,3/5/2019,77,4147.29 +6,Ase,Pringle,apringle5@sfgate.com,Male,147.34.186.244,10/19/2019,33,4551.61 +7,Sibylla,Weiss,sweiss6@icq.com,Female,196.247.130.201,3/7/2019,21,2154.9 +8,Richy,Dougal,rdougal7@yelp.com,Male,91.176.172.223,12/27/2018,97,3403.75 +9,Kelsey,Ludlamme,kludlamme8@cyberchimps.com,Male,121.112.184.219,5/2/2019,81,4930.75 +10,Fae,Driffe,fdriffe9@friendfeed.com,Female,219.51.51.253,4/7/2019,57,3100.78 +11,Dannye,Sleit,dsleita@independent.co.uk,Female,160.208.93.210,10/4/2019,88,4401.37 +12,Kessia,Gilkes,kgilkesb@w3.org,Female,30.178.57.187,8/26/2019,82,2369.86 +13,Rickie,Persich,rpersichc@mapquest.com,Male,50.235.20.153,9/13/2019,94,4557.41 +14,Margaretta,Shearn,mshearnd@buzzfeed.com,Female,172.102.242.250,3/14/2019,72,2948.22 +15,Malcolm,Winnard,mwinnarde@yale.edu,Male,185.241.158.149,5/15/2019,82,4723.48 +16,Lazarus,Summerlie,lsummerlief@comsenz.com,Male,111.172.107.99,11/8/2019,89,2845.05 +17,Bord,Cato,bcatog@edublogs.org,Male,177.53.70.102,4/2/2019,32,4933.24 +18,Weber,Guslon,wguslonh@go.com,Male,115.2.137.252,12/10/2018,94,4348.69 +19,Stearne,MacPadene,smacpadenei@pbs.org,Male,35.83.181.137,8/4/2019,82,4950.67 +20,Bekki,Remirez,bremirezj@arstechnica.com,Female,12.111.119.238,2/17/2019,62,1510.53 +21,Desiri,Gaskins,dgaskinsk@prlog.org,Female,43.30.140.105,9/8/2019,64,4641.51 +22,Mata,Beaten,mbeatenl@constantcontact.com,Male,13.90.195.102,4/6/2019,84,1942.72 +23,Mattias,Bullas,mbullasm@fastcompany.com,Male,37.242.45.155,7/21/2019,95,3321.2 +24,Sloan,Graveson,sgravesonn@mozilla.com,Male,124.94.155.193,9/28/2019,7,1786.92 +25,Isak,Juste,ijusteo@google.ru,Male,249.233.28.164,8/18/2019,34,1682.19 +26,Teri,Thomann,tthomannp@wp.com,Female,168.237.145.237,11/16/2019,18,4480.64 +27,Rhoda,Gotcher,rgotcherq@businessinsider.com,Female,23.141.180.40,4/1/2019,19,4514.47 +28,Helen-elizabeth,McEniry,hmceniryr@oakley.com,Female,43.143.23.204,12/14/2018,40,4146.98 +29,Aguie,Brecknall,abrecknalls@nifty.com,Male,69.49.176.116,1/19/2019,96,4720.87 +30,Wildon,Keenlyside,wkeenlysidet@blogtalkradio.com,Male,245.109.45.71,3/26/2019,22,1835.57 +31,Ynez,Lots,ylotsu@abc.net.au,Female,172.185.2.14,7/17/2019,68,4872.13 +32,Norman,Worgen,nworgenv@constantcontact.com,Male,143.221.2.185,3/17/2019,29,4768.51 +33,Ker,Bown,kbownw@bandcamp.com,Male,30.5.53.61,6/14/2019,22,3091.25 +34,Ivy,Nibloe,inibloex@noaa.gov,Female,121.242.246.184,7/31/2019,15,4048.07 +35,Coop,Waiting,cwaitingy@prlog.org,Male,215.155.212.35,1/31/2019,59,1388.34 +36,Philipa,Bigglestone,pbigglestonez@networkadvertising.org,Female,235.113.203.193,1/11/2019,49,2571.05 +37,Konstantine,Reavell,kreavell10@pcworld.com,Male,212.115.157.70,1/15/2019,32,1521.5 +38,Neddie,Peckham,npeckham11@shareasale.com,Male,165.199.0.54,11/10/2019,4,4159.67 +39,Veronique,Crocetti,vcrocetti12@bravesites.com,Female,155.94.241.75,11/27/2019,70,1682.83 +40,Stanford,Folk,sfolk13@walmart.com,Male,115.78.90.21,8/20/2019,21,1049.63 +41,Tamera,Bacchus,tbacchus14@techcrunch.com,Female,125.75.125.6,2/3/2019,44,3804.48 +42,Andromache,Hakonsson,ahakonsson15@ft.com,Female,216.82.36.186,8/3/2019,38,3643.39 +43,Elnora,Amos,eamos16@domainmarket.com,Female,233.33.105.19,11/12/2019,97,1234.57 +44,Andrus,Hegge,ahegge17@arstechnica.com,Male,48.49.214.246,9/21/2019,79,4728.49 +45,Grady,Rodell,grodell18@ox.ac.uk,Male,69.64.12.243,4/22/2019,64,3514.69 +46,Maryann,Shaddick,mshaddick19@boston.com,Female,145.192.46.176,8/7/2019,43,1944.22 +47,Gaelan,Kirtley,gkirtley1a@topsy.com,Male,145.162.10.133,9/14/2019,39,2598.76 +48,Denver,Kennicott,dkennicott1b@amazon.com,Male,179.116.133.53,12/18/2018,10,2243.1 +49,Bordy,Saw,bsaw1c@cmu.edu,Male,6.22.237.36,1/27/2019,80,2196.95 +50,Gwenette,Iston,giston1d@multiply.com,Female,211.116.16.113,3/29/2019,34,2230.26 +51,Hedvig,Simmers,hsimmers1e@uol.com.br,Female,155.181.252.255,8/23/2019,7,3711.71 +52,Jannel,Sarre,jsarre1f@tuttocitta.it,Female,127.187.194.109,6/4/2019,82,2641.84 +53,Rusty,Saffill,rsaffill1g@mozilla.com,Male,152.175.79.114,3/24/2019,63,4482.27 +54,Shelden,Brandin,sbrandin1h@jugem.jp,Male,218.156.254.18,9/29/2019,12,1487.3 +55,Rusty,Dumbare,rdumbare1i@purevolume.com,Male,49.252.90.82,3/2/2019,26,4880.92 +56,Agace,Davidovitz,adavidovitz1j@mtv.com,Female,187.52.194.143,4/21/2019,59,4803.16 +57,Ross,McGarva,rmcgarva1k@upenn.edu,Male,41.191.56.78,8/23/2019,97,4860.07 +58,Kayne,Maruszewski,kmaruszewski1l@stanford.edu,Male,41.228.104.199,7/18/2019,23,1358.8 +59,Stavros,Comar,scomar1m@google.ru,Male,5.91.47.215,6/20/2019,66,1423.4 +60,Ruperto,Proudlock,rproudlock1n@hostgator.com,Male,105.156.116.198,1/20/2019,28,4631.21 +61,Milka,Marvel,mmarvel1o@devhub.com,Female,9.251.162.16,5/26/2019,80,3446.13 +62,Zared,Pallesen,zpallesen1p@ted.com,Male,246.159.163.241,6/13/2019,25,2949.72 +63,Sharona,Muscat,smuscat1q@youtube.com,Female,192.207.68.239,1/17/2019,53,4522.67 +64,Annabella,Persitt,apersitt1r@china.com.cn,Female,5.217.19.64,7/26/2019,52,2113.55 +65,Tawsha,Constantine,tconstantine1s@4shared.com,Female,6.89.103.116,6/15/2019,38,2727.92 +66,Leonard,Pavlasek,lpavlasek1t@theglobeandmail.com,Male,42.64.175.217,2/16/2019,85,2694.45 +67,Kalvin,Caudle,kcaudle1u@baidu.com,Male,193.11.181.80,4/23/2019,18,2549.05 +68,Jessica,Cumbridge,jcumbridge1v@hugedomains.com,Female,238.81.101.205,12/18/2018,80,2877.37 +69,Iorgo,Hampshaw,ihampshaw1w@youtu.be,Male,35.99.25.88,4/15/2019,100,4485.79 +70,Sherlocke,Kerswell,skerswell1x@zdnet.com,Male,201.53.40.240,9/5/2019,6,4147.46 +71,Rikki,Blodg,rblodg1y@admin.ch,Male,233.254.145.162,9/20/2019,41,4950.16 +72,Leoine,MacInnes,lmacinnes1z@joomla.org,Female,76.138.109.238,7/23/2019,45,3870.58 +73,Leicester,O'Haire,lohaire20@nba.com,Male,51.179.242.230,8/7/2019,23,2243.91 +74,Bennett,Jankowski,bjankowski21@jugem.jp,Male,248.133.185.229,6/4/2019,67,2448.41 +75,Josias,Wardingley,jwardingley22@bigcartel.com,Male,128.111.46.189,8/22/2019,2,4954.97 +76,Farrand,Edon,fedon23@networkadvertising.org,Female,181.161.32.177,3/30/2019,95,3728.89 +77,Tirrell,Daugherty,tdaugherty24@miitbeian.gov.cn,Male,202.140.213.72,11/9/2019,36,3436.25 +78,Celeste,Odby,codby25@answers.com,Female,152.36.106.124,6/16/2019,12,1327.35 +79,Jory,Roomes,jroomes26@usa.gov,Male,124.197.56.246,7/2/2019,62,3910.3 +80,Saudra,Woodham,swoodham27@smh.com.au,Female,109.122.138.13,4/17/2019,22,3553.65 +81,Renaldo,Calow,rcalow28@cloudflare.com,Male,108.38.150.172,12/5/2018,98,3790.92 +82,Chrissie,Wynch,cwynch29@de.vu,Female,113.58.215.184,5/25/2019,54,3925.41 +83,Boris,Ilyas,bilyas2a@webeden.co.uk,Male,98.65.148.122,1/26/2019,4,2722.03 +84,Zach,McReynolds,zmcreynolds2b@about.com,Male,169.251.18.46,3/25/2019,33,2238.47 +85,Pip,Puttan,pputtan2c@multiply.com,Male,6.160.216.170,10/23/2019,20,1502.59 +86,Lenore,Shafto,lshafto2d@globo.com,Female,144.169.11.70,1/17/2019,5,2162.94 +87,Maggie,Dryden,mdryden2e@cpanel.net,Female,203.155.129.86,3/12/2019,76,3017.41 +88,Madeleine,Alflatt,malflatt2f@spotify.com,Female,38.43.105.230,6/3/2019,70,4950.07 +89,Jojo,Niblock,jniblock2g@usgs.gov,Female,241.182.83.206,6/20/2019,98,3224.06 +90,Chan,Lebbern,clebbern2h@about.me,Male,129.233.179.181,5/31/2019,14,3407.91 +91,Juanita,O'Neil,joneil2i@sina.com.cn,Female,196.212.243.128,4/21/2019,4,1238.45 +92,Albina,Nestoruk,anestoruk2j@rakuten.co.jp,Female,173.60.28.232,11/25/2019,2,3850.73 +93,Gerrard,Lowrance,glowrance2k@huffingtonpost.com,Male,65.158.65.49,5/30/2019,56,2495.36 +94,Enrique,Borrel,eborrel2l@slashdot.org,Male,234.74.144.119,11/11/2019,89,1230.11 +95,Sheppard,Millward,smillward2m@plala.or.jp,Male,30.207.143.30,9/13/2019,14,4656.55 +96,Karna,Zisneros,kzisneros2n@comcast.net,Female,207.85.89.67,4/30/2019,40,1087.58 +97,Mohandas,Abbitt,mabbitt2o@cocolog-nifty.com,Male,157.202.50.94,2/2/2019,18,4141.99 +98,Alena,McVee,amcvee2p@so-net.ne.jp,Female,35.120.251.203,9/28/2019,15,4863.32 +99,Lanita,Sommerlin,lsommerlin2q@mozilla.com,Female,63.103.18.73,2/17/2019,69,4424.01 +100,Celine,Huddlestone,chuddlestone2r@ask.com,Female,207.219.182.50,6/24/2019,92,4185.16 +101,Jan,Vorley,jvorley2s@bbc.co.uk,Male,24.122.66.16,10/7/2019,88,4856.43 +102,Gordon,Burness,gburness2t@wired.com,Male,251.54.167.76,7/28/2019,77,1249.9 +103,Doris,Dey,ddey2u@youtube.com,Female,105.167.122.156,5/18/2019,95,2541.59 +104,Colby,Ashurst,cashurst2v@wix.com,Male,93.195.66.138,9/14/2019,49,3987.84 +105,Phyllida,Brookson,pbrookson2w@apple.com,Female,15.169.21.114,4/8/2019,10,4565.43 +106,Jeramie,Crasswell,jcrasswell2x@posterous.com,Male,205.238.4.171,7/19/2019,10,1042.23 +107,Lynsey,Plum,lplum2y@blogtalkradio.com,Female,184.41.245.159,11/15/2019,27,1913.04 +108,Dorella,Dulanty,ddulanty2z@discuz.net,Female,29.143.190.208,3/15/2019,71,1939.76 +109,Ruthi,Rishworth,rrishworth30@liveinternet.ru,Female,107.240.252.87,11/14/2019,25,4378.32 +110,Petrina,Featherstonehaugh,pfeatherstonehaugh31@umich.edu,Female,139.60.87.163,5/3/2019,86,2273.95 +111,Karla,Dechelle,kdechelle32@google.cn,Female,147.220.216.41,11/22/2019,79,2940.0 +112,Joshia,Fishlock,jfishlock33@booking.com,Male,158.103.241.179,7/8/2019,68,3644.03 +113,Junia,Maryman,jmaryman34@jigsy.com,Female,216.105.242.205,5/15/2019,97,2466.85 +114,Mabelle,Warmisham,mwarmisham35@mysql.com,Female,246.108.73.60,2/5/2019,43,1904.03 +115,Phaidra,Fleet,pfleet36@1und1.de,Female,83.157.253.208,2/13/2019,21,1765.81 +116,Flo,Mardlin,fmardlin37@unicef.org,Female,31.252.115.185,12/11/2018,14,3875.57 +117,Crin,Aspinall,caspinall38@pen.io,Female,152.151.189.190,9/21/2019,76,3615.12 +118,Lorrie,Carnaman,lcarnaman39@sina.com.cn,Male,182.12.111.81,2/1/2019,66,1537.87 +119,Barnabas,Denslow,bdenslow3a@dell.com,Male,109.193.202.177,10/17/2019,71,1352.18 +120,Bennett,Saffen,bsaffen3b@cloudflare.com,Male,180.151.92.220,3/8/2019,19,3352.34 +121,Jonell,Menauteau,jmenauteau3c@yellowbook.com,Female,49.115.246.26,9/25/2019,26,4823.26 +122,Alicia,Jakubovicz,ajakubovicz3d@nps.gov,Female,239.158.188.213,3/27/2019,32,1051.47 +123,Nikolai,Raselles,nraselles3e@histats.com,Male,94.104.99.187,5/13/2019,43,1043.08 +124,Nikolaos,Loder,nloder3f@google.it,Male,19.118.58.253,3/17/2019,73,1254.57 +125,Sheffield,Muncey,smuncey3g@elpais.com,Male,77.244.5.146,7/28/2019,67,1704.55 +126,Marni,Cowin,mcowin3h@google.com.br,Female,61.232.91.222,7/8/2019,50,1367.66 +127,Storm,Kennedy,skennedy3i@wikispaces.com,Female,191.12.223.90,7/31/2019,77,3871.16 +128,Trent,Gutierrez,tgutierrez3j@sourceforge.net,Male,113.242.15.190,8/10/2019,81,4352.61 +129,Dodi,Tiller,dtiller3k@dailymail.co.uk,Female,0.240.169.55,11/21/2019,35,4607.1 +130,Vivie,Sture,vsture3l@yelp.com,Female,46.11.195.152,10/27/2019,82,2166.72 +131,Nerissa,Giddins,ngiddins3m@whitehouse.gov,Female,25.100.68.103,3/11/2019,81,4326.19 +132,Emalee,Huckerby,ehuckerby3n@europa.eu,Female,249.239.20.180,2/14/2019,15,1607.1 +133,Cesare,Deave,cdeave3o@google.es,Male,215.226.177.3,12/16/2018,64,3602.38 +134,Britni,Neagle,bneagle3p@is.gd,Female,238.87.102.252,5/1/2019,95,3254.36 +135,Andrej,Gandrich,agandrich3q@addtoany.com,Male,122.104.65.90,8/14/2019,41,3220.23 +136,Cody,Worssam,cworssam3r@chronoengine.com,Male,221.63.128.0,11/11/2019,7,4570.98 +137,Mord,Bradford,mbradford3s@utexas.edu,Male,168.172.15.29,2/8/2019,52,2842.69 +138,Madeline,Golledge,mgolledge3t@japanpost.jp,Female,180.54.218.245,8/1/2019,31,2426.19 +139,Clarie,Tunn,ctunn3u@sun.com,Female,170.49.242.95,3/30/2019,6,2375.77 +140,Seana,Gatherell,sgatherell3v@myspace.com,Female,229.46.37.246,7/1/2019,83,3626.95 +141,Veronica,Fielder,vfielder3w@hugedomains.com,Female,211.136.81.248,10/5/2019,76,4578.69 +142,Kris,Searby,ksearby3x@constantcontact.com,Male,75.40.234.246,5/14/2019,79,3491.43 +143,Dorita,Henze,dhenze3y@mozilla.com,Female,19.91.34.111,3/5/2019,23,3869.59 +144,Ada,Sydall,asydall3z@netlog.com,Female,63.122.73.224,9/28/2019,5,3118.74 +145,Josias,Vanichkov,jvanichkov40@amazon.co.jp,Male,111.18.27.20,3/11/2019,82,1807.86 +146,Payton,Chesney,pchesney41@forbes.com,Male,253.128.22.165,6/1/2019,93,1101.65 +147,Arabele,Marcome,amarcome42@bbb.org,Female,25.78.95.237,8/25/2019,20,3268.49 +148,Dick,Egre,degre43@discovery.com,Male,136.113.116.45,3/3/2019,35,3221.24 +149,Charleen,Eckh,ceckh44@shareasale.com,Female,251.215.112.50,6/30/2019,47,3524.18 +150,Minne,Lawfull,mlawfull45@shinystat.com,Female,15.159.68.230,7/31/2019,56,3915.18 +151,Timi,Pelchat,tpelchat46@issuu.com,Female,218.157.149.25,11/17/2019,53,1224.92 +152,Gabrila,Goosnell,ggoosnell47@hugedomains.com,Female,79.133.249.98,12/28/2018,30,4687.86 +153,Casie,Brimm,cbrimm48@4shared.com,Female,252.229.161.4,2/15/2019,98,1455.37 +154,Leeland,Dewi,ldewi49@multiply.com,Male,81.68.121.138,3/25/2019,63,4518.04 +155,Pascal,Garred,pgarred4a@facebook.com,Male,223.70.91.166,5/3/2019,71,2996.67 +156,Lazaro,Manktelow,lmanktelow4b@wikia.com,Male,185.80.62.190,7/21/2019,82,1094.16 +157,Sandi,Montgomery,smontgomery4c@java.com,Female,190.222.21.13,11/17/2019,21,2832.31 +158,Valentine,Jimes,vjimes4d@about.com,Female,74.198.243.183,5/1/2019,53,1644.56 +159,Erika,Ferraresi,eferraresi4e@google.fr,Female,54.193.54.25,5/19/2019,21,4436.52 +160,Nerta,Zaczek,nzaczek4f@spotify.com,Female,108.17.93.214,2/22/2019,81,2156.82 +161,Lucita,Harte,lharte4g@nasa.gov,Female,193.242.177.185,12/21/2018,64,3544.36 +162,Jedidiah,Danielsohn,jdanielsohn4h@accuweather.com,Male,245.98.253.52,9/16/2019,1,2115.11 +163,Lorettalorna,Quarrie,lquarrie4i@fc2.com,Female,76.173.212.93,6/13/2019,4,1466.75 +164,Rich,Tryhorn,rtryhorn4j@moonfruit.com,Male,143.167.201.182,10/7/2019,1,1661.04 +165,Gardie,Karlqvist,gkarlqvist4k@so-net.ne.jp,Male,249.11.192.35,8/12/2019,6,3746.95 +166,Xylia,Penna,xpenna4l@dailymotion.com,Female,180.58.51.110,11/28/2019,61,3441.57 +167,Axel,Renackowna,arenackowna4m@tripod.com,Male,146.67.140.217,3/7/2019,78,3550.93 +168,Chen,Fulton,cfulton4n@columbia.edu,Male,146.169.34.152,4/2/2019,74,2383.26 +169,Alon,Cufley,acufley4o@photobucket.com,Male,125.231.215.140,4/16/2019,65,1732.78 +170,Koo,Gumm,kgumm4p@php.net,Female,243.153.77.38,3/21/2019,48,3721.4 +171,Korey,Weatherdon,kweatherdon4q@blogger.com,Male,240.168.248.218,3/12/2019,77,3795.59 +172,Lena,Stannus,lstannus4r@lulu.com,Female,109.85.91.216,12/5/2018,46,2634.33 +173,Elijah,Westney,ewestney4s@noaa.gov,Male,158.146.220.98,8/7/2019,27,4530.75 +174,Eachelle,Schiefersten,eschiefersten4t@symantec.com,Female,54.128.102.166,9/15/2019,87,2940.88 +175,Georgeanne,Gotthard.sf,ggotthardsf4u@geocities.com,Female,86.43.67.105,1/9/2019,37,2319.01 +176,Frazier,Feldbrin,ffeldbrin4v@joomla.org,Male,184.234.191.22,10/14/2019,23,4596.74 +177,Bancroft,Alvarez,balvarez4w@cisco.com,Male,226.3.76.213,7/28/2019,21,3413.13 +178,Ricky,Lyles,rlyles4x@abc.net.au,Male,156.11.73.17,11/28/2019,6,1870.07 +179,Lorettalorna,Bomfield,lbomfield4y@virginia.edu,Female,37.210.36.178,6/20/2019,66,1127.34 +180,Catrina,Ruse,cruse4z@exblog.jp,Female,81.216.141.90,12/5/2018,34,2485.16 +181,Loleta,Pawels,lpawels50@merriam-webster.com,Female,176.42.193.141,6/10/2019,84,4221.89 +182,Hedvige,Commings,hcommings51@domainmarket.com,Female,138.3.249.198,1/29/2019,8,3910.06 +183,Dmitri,McCrory,dmccrory52@mit.edu,Male,135.37.103.219,7/28/2019,64,2804.83 +184,Hendrika,Shawyer,hshawyer53@xinhuanet.com,Female,16.30.34.147,2/20/2019,65,1706.29 +185,Lorilee,Dunlop,ldunlop54@ed.gov,Female,111.241.90.104,5/10/2019,75,4965.63 +186,Jerad,Faunch,jfaunch55@blogtalkradio.com,Male,139.35.31.167,3/18/2019,93,4404.83 +187,Gualterio,Eary,geary56@illinois.edu,Male,59.170.22.192,10/2/2019,49,3569.07 +188,Barby,Jikylls,bjikylls57@deviantart.com,Female,22.44.213.16,4/7/2019,75,4908.44 +189,Jabez,Mathiot,jmathiot58@w3.org,Male,93.194.63.80,5/5/2019,64,2744.04 +190,Worthy,Edland,wedland59@barnesandnoble.com,Male,4.66.208.56,11/12/2019,51,4272.28 +191,Doralyn,Braunstein,dbraunstein5a@youtube.com,Female,68.179.11.250,3/1/2019,37,3713.51 +192,Mallory,Eyres,meyres5b@google.com.hk,Female,222.214.3.63,7/22/2019,57,3522.06 +193,Louie,Dunkley,ldunkley5c@cdc.gov,Male,154.18.175.128,7/10/2019,51,2901.79 +194,Elbert,Kenvin,ekenvin5d@ftc.gov,Male,206.116.235.21,2/23/2019,75,4198.55 +195,Sean,Hankin,shankin5e@virginia.edu,Female,32.170.127.155,7/7/2019,76,4284.24 +196,Tamiko,O'Fogarty,tofogarty5f@comsenz.com,Female,249.124.65.230,2/27/2019,97,1816.59 +197,Dana,Caress,dcaress5g@bandcamp.com,Female,63.163.104.0,6/11/2019,70,4546.28 +198,Starla,Bicksteth,sbicksteth5h@deviantart.com,Female,93.41.109.63,3/6/2019,75,1536.56 +199,Olly,Chalmers,ochalmers5i@nature.com,Male,206.17.239.226,6/1/2019,99,2617.06 +200,Ermengarde,Laible,elaible5j@alibaba.com,Female,232.255.191.98,4/14/2019,7,2122.32 +201,Melloney,Stalf,mstalf5k@constantcontact.com,Female,254.159.238.133,3/11/2019,17,1829.95 +202,Aggy,Sandry,asandry5l@chicagotribune.com,Female,88.162.78.17,4/23/2019,82,1228.42 +203,Tuesday,Brunning,tbrunning5m@microsoft.com,Female,24.185.56.166,12/2/2018,25,2420.45 +204,Graehme,Marconi,gmarconi5n@forbes.com,Male,134.166.130.121,1/15/2019,29,3650.99 +205,Susi,Casillas,scasillas5o@jimdo.com,Female,130.75.119.191,4/6/2019,26,3164.59 +206,Bunny,Bollands,bbollands5p@privacy.gov.au,Female,73.155.139.92,7/20/2019,94,1459.89 +207,Corrine,Bythway,cbythway5q@ucsd.edu,Female,152.20.150.152,12/30/2018,74,1997.35 +208,Dannye,Adshede,dadshede5r@netlog.com,Female,210.46.12.79,8/9/2019,28,2915.74 +209,Gerald,Waiton,gwaiton5s@1und1.de,Male,47.243.251.9,5/18/2019,66,3698.92 +210,Belia,Hatherley,bhatherley5t@dot.gov,Female,3.253.140.62,10/2/2019,54,1089.69 +211,Terrell,Witherup,twitherup5u@ibm.com,Male,125.43.97.27,5/20/2019,97,3331.73 +212,Vic,Kliner,vkliner5v@cargocollective.com,Male,91.117.26.173,1/22/2019,12,1020.32 +213,Mayor,Drover,mdrover5w@comsenz.com,Male,165.45.244.175,9/18/2019,83,1282.01 +214,Didi,Kanwell,dkanwell5x@mysql.com,Female,249.71.28.189,1/25/2019,39,3401.56 +215,Lothario,Heyworth,lheyworth5y@patch.com,Male,204.254.193.144,6/27/2019,14,2392.22 +216,Adi,Bertome,abertome5z@washingtonpost.com,Female,247.98.53.39,3/19/2019,67,1188.17 +217,Zebadiah,Kryzhov,zkryzhov60@columbia.edu,Male,126.42.169.163,11/28/2019,85,2177.47 +218,Putnam,Wallworke,pwallworke61@sourceforge.net,Male,54.55.143.193,4/5/2019,72,4454.14 +219,Amery,Hitchens,ahitchens62@harvard.edu,Male,48.224.217.2,6/13/2019,64,3615.62 +220,Joana,Davitti,jdavitti63@ebay.co.uk,Female,62.165.254.131,3/4/2019,80,3629.81 +221,Kathleen,Tuer,ktuer64@biblegateway.com,Female,5.70.130.77,3/11/2019,13,1608.46 +222,Renaldo,Campbell-Dunlop,rcampbelldunlop65@skyrock.com,Male,26.131.233.63,12/29/2018,50,3202.62 +223,Titus,Ault,tault66@elpais.com,Male,165.158.147.201,7/2/2019,84,4835.57 +224,Gamaliel,Kilfedder,gkilfedder67@hostgator.com,Male,84.168.17.247,12/23/2018,9,4909.15 +225,Stewart,Boylund,sboylund68@liveinternet.ru,Male,225.118.153.204,6/28/2019,11,3319.59 +226,Jo,Kitchiner,jkitchiner69@skype.com,Female,59.124.146.200,2/6/2019,67,1600.09 +227,Elvis,Fosken,efosken6a@pcworld.com,Male,205.87.85.15,9/9/2019,6,3922.34 +228,Cammie,Danson,cdanson6b@narod.ru,Female,56.105.230.103,2/13/2019,65,1885.94 +229,Fabiano,Garaghan,fgaraghan6c@ezinearticles.com,Male,78.123.49.176,7/20/2019,51,3114.09 +230,Ailina,Givens,agivens6d@cbsnews.com,Female,60.180.138.180,7/5/2019,89,4535.53 +231,Armstrong,Dunkerly,adunkerly6e@independent.co.uk,Male,90.216.21.184,2/26/2019,14,1990.77 +232,Catharine,Matityahu,cmatityahu6f@alibaba.com,Female,57.63.241.97,3/10/2019,95,3363.25 +233,Sile,Glassman,sglassman6g@google.com.au,Female,69.8.60.158,9/2/2019,51,1557.41 +234,Benyamin,Scantleberry,bscantleberry6h@constantcontact.com,Male,130.141.87.136,2/28/2019,73,2950.29 +235,Mendel,Whether,mwhether6i@google.com,Male,241.33.68.87,8/7/2019,82,1090.67 +236,Marcos,Everitt,meveritt6j@yelp.com,Male,233.19.226.38,3/31/2019,37,1052.69 +237,Missie,Eastment,meastment6k@statcounter.com,Female,70.194.212.197,12/20/2018,78,4585.45 +238,Tim,Godfray,tgodfray6l@ucla.edu,Male,200.47.142.40,2/15/2019,5,1682.26 +239,Aguste,Pinney,apinney6m@posterous.com,Male,230.75.22.90,5/30/2019,41,2301.61 +240,Matthias,Francesconi,mfrancesconi6n@biglobe.ne.jp,Male,105.93.88.19,12/8/2018,67,4462.69 +241,Donna,Luckes,dluckes6o@over-blog.com,Female,213.3.126.62,7/2/2019,16,2107.3 +242,Nathanial,Spurden,nspurden6p@microsoft.com,Male,230.177.142.225,3/28/2019,78,1795.33 +243,Stanford,Keets,skeets6q@sbwire.com,Male,192.100.251.103,5/30/2019,60,1912.38 +244,Joly,Mont,jmont6r@technorati.com,Female,14.164.142.106,4/29/2019,23,4036.1 +245,Tyrus,Reasce,treasce6s@ibm.com,Male,12.231.0.1,12/15/2018,60,2707.42 +246,Lee,MacKeogh,lmackeogh6t@woothemes.com,Male,182.53.212.225,12/26/2018,49,1052.96 +247,Valeria,Le Hucquet,vlehucquet6u@cisco.com,Female,155.224.213.71,1/8/2019,67,1292.01 +248,Jillana,Breddy,jbreddy6v@fc2.com,Female,97.42.41.207,1/27/2019,79,2603.53 +249,Alic,Bergeau,abergeau6w@fema.gov,Male,247.140.30.46,10/2/2019,61,1209.85 +250,Cairistiona,Meredith,cmeredith6x@hhs.gov,Female,70.70.142.81,4/12/2019,17,3084.34 +251,Baird,Hollerin,bhollerin6y@issuu.com,Male,22.99.57.132,9/29/2019,50,2427.97 +252,Leonard,Caldecot,lcaldecot6z@vistaprint.com,Male,181.234.61.189,1/17/2019,4,4714.6 +253,Frants,Cochrane,fcochrane70@usgs.gov,Male,243.153.97.44,10/25/2019,7,2131.81 +254,Gertrud,Enticknap,genticknap71@csmonitor.com,Female,252.82.226.210,5/21/2019,11,2407.13 +255,Sullivan,Chattington,schattington72@pinterest.com,Male,155.193.236.102,1/10/2019,82,4204.53 +256,Taite,Sighard,tsighard73@dell.com,Male,201.139.42.108,7/13/2019,40,3983.56 +257,Rozina,Stannas,rstannas74@eventbrite.com,Female,175.179.96.178,1/6/2019,67,4645.75 +258,Sanson,Trevon,strevon75@patch.com,Male,40.224.2.112,5/22/2019,69,4383.12 +259,Torrey,Gilhoolie,tgilhoolie76@cdc.gov,Male,210.149.121.27,6/3/2019,44,2232.38 +260,Lauri,Lackeye,llackeye77@ted.com,Female,104.17.18.94,6/14/2019,21,3534.19 +261,Rica,Vineall,rvineall78@craigslist.org,Female,164.92.184.86,7/29/2019,67,2725.57 +262,Dane,Youell,dyouell79@flavors.me,Male,33.252.240.196,12/2/2018,78,2150.98 +263,Tricia,Singyard,tsingyard7a@facebook.com,Female,117.214.88.252,3/29/2019,46,1692.77 +264,Adrea,Rubinsohn,arubinsohn7b@sakura.ne.jp,Female,27.195.5.14,9/8/2019,72,3230.72 +265,Dotti,Brader,dbrader7c@addthis.com,Female,13.85.47.30,12/26/2018,100,2732.26 +266,Gabi,Fackrell,gfackrell7d@scientificamerican.com,Female,58.145.63.14,8/11/2019,95,1238.44 +267,Price,Moger,pmoger7e@deviantart.com,Male,19.116.110.91,8/15/2019,23,1473.89 +268,Jayme,Wakelin,jwakelin7f@cisco.com,Male,26.252.180.229,10/5/2019,56,4366.22 +269,Maurizio,Dunsmuir,mdunsmuir7g@clickbank.net,Male,120.22.85.145,11/3/2019,31,1877.99 +270,Carlos,Edmands,cedmands7h@redcross.org,Male,20.67.51.110,6/14/2019,79,1238.13 +271,Johan,McGinly,jmcginly7i@amazonaws.com,Male,12.205.191.101,3/20/2019,49,4095.82 +272,Albrecht,Rotchell,arotchell7j@google.es,Male,60.170.217.205,9/28/2019,92,2894.61 +273,Eli,De Lacey,edelacey7k@goo.ne.jp,Male,55.7.194.20,11/10/2019,78,4537.32 +274,Sutherlan,Mill,smill7l@i2i.jp,Male,130.65.164.97,1/16/2019,31,1681.32 +275,Nathalie,Willder,nwillder7m@usnews.com,Female,69.170.87.110,5/5/2019,1,1024.53 +276,Rem,Iczokvitz,riczokvitz7n@harvard.edu,Male,7.203.57.167,4/4/2019,39,3672.82 +277,Lorens,Denyukin,ldenyukin7o@uol.com.br,Male,203.70.155.205,2/14/2019,41,3600.8 +278,Mag,Pigden,mpigden7p@psu.edu,Female,239.194.157.251,6/14/2019,47,3599.97 +279,Petronia,Carvill,pcarvill7q@apple.com,Female,151.29.121.135,8/16/2019,68,4879.68 +280,Felicity,Capewell,fcapewell7r@patch.com,Female,176.136.185.249,9/14/2019,75,2448.16 +281,Hartwell,Zellner,hzellner7s@wordpress.org,Male,210.182.89.221,5/26/2019,68,4758.87 +282,Marcela,Geggie,mgeggie7t@samsung.com,Female,118.65.180.139,2/10/2019,15,4222.62 +283,Keith,Loxston,kloxston7u@etsy.com,Male,30.75.222.61,3/31/2019,90,1964.35 +284,Mattheus,Guinn,mguinn7v@virginia.edu,Male,157.141.233.64,2/5/2019,20,1509.77 +285,Cristy,Van den Bosch,cvandenbosch7w@yandex.ru,Female,106.186.220.48,2/10/2019,57,2650.92 +286,Pansie,Pull,ppull7x@tripod.com,Female,133.223.218.112,3/12/2019,16,1844.52 +287,Hyacinthie,Bools,hbools7y@phpbb.com,Female,6.136.111.144,6/24/2019,88,3753.3 +288,Cosimo,Humphris,chumphris7z@ftc.gov,Male,42.252.197.80,1/8/2019,5,1335.74 +289,Raquela,Ledbetter,rledbetter80@imdb.com,Female,25.84.71.62,12/13/2018,39,4474.51 +290,Domingo,McKelvey,dmckelvey81@globo.com,Male,139.34.201.250,9/6/2019,40,4039.82 +291,Britta,Grzesiak,bgrzesiak82@google.fr,Female,254.24.80.245,7/7/2019,73,1052.79 +292,Palmer,Gliddon,pgliddon83@example.com,Male,60.248.224.227,12/27/2018,33,4273.36 +293,Millard,Feore,mfeore84@mlb.com,Male,129.50.148.247,4/3/2019,60,2015.88 +294,Lanie,Blasgen,lblasgen85@ocn.ne.jp,Female,124.254.122.231,10/6/2019,35,1212.04 +295,Sherry,Jamrowicz,sjamrowicz86@newyorker.com,Female,8.187.192.111,6/12/2019,57,2819.04 +296,Payton,Loxton,ploxton87@ted.com,Male,20.185.112.233,5/16/2019,9,4976.7 +297,Anderea,Blandford,ablandford88@tinypic.com,Female,30.186.15.181,2/3/2019,54,3962.4 +298,Adele,Goldstein,agoldstein89@csmonitor.com,Female,101.24.151.157,8/29/2019,47,1300.26 +299,Christiana,Kybbye,ckybbye8a@soup.io,Female,164.124.255.193,8/24/2019,35,4524.75 +300,Bettine,Bryden,bbryden8b@tinyurl.com,Female,71.23.174.26,4/21/2019,27,3413.85 +301,Halsey,Deeble,hdeeble8c@gizmodo.com,Male,17.234.31.127,8/30/2019,74,2872.84 +302,Peggi,Gallier,pgallier8d@aol.com,Female,34.161.21.167,3/28/2019,26,2530.19 +303,Oby,Lemanu,olemanu8e@skyrock.com,Male,123.215.166.71,10/24/2019,90,2590.72 +304,Kelly,Limbert,klimbert8f@123-reg.co.uk,Male,225.87.194.99,7/15/2019,71,3252.4 +305,Edmon,Pittham,epittham8g@wufoo.com,Male,206.168.11.133,11/1/2019,84,4290.32 +306,Nicola,Hazelby,nhazelby8h@nih.gov,Male,248.203.87.61,8/14/2019,33,4439.66 +307,Norry,Cheesworth,ncheesworth8i@spotify.com,Male,188.191.145.160,9/14/2019,19,3777.37 +308,Madeleine,Colchett,mcolchett8j@goo.ne.jp,Female,49.89.233.117,10/26/2019,97,3215.79 +309,Alyse,Rilston,arilston8k@friendfeed.com,Female,178.80.192.158,4/26/2019,10,3704.99 +310,Aubrey,Rodrigues,arodrigues8l@clickbank.net,Female,110.27.123.138,2/26/2019,82,3312.78 +311,Wade,Fitzgerald,wfitzgerald8m@blogspot.com,Male,83.93.6.27,4/14/2019,18,4200.81 +312,Bar,Aspall,baspall8n@jimdo.com,Male,220.44.202.201,6/14/2019,31,3252.11 +313,Martynne,Jurczik,mjurczik8o@homestead.com,Female,45.95.32.123,4/16/2019,64,3091.17 +314,Rem,Binion,rbinion8p@spiegel.de,Male,194.45.225.156,10/13/2019,32,1460.2 +315,Brocky,Picker,bpicker8q@usda.gov,Male,43.227.235.110,6/26/2019,13,2705.18 +316,Caspar,Frankowski,cfrankowski8r@baidu.com,Male,77.43.200.240,4/9/2019,65,3908.27 +317,Fernanda,Jerman,fjerman8s@qq.com,Female,251.97.23.5,12/2/2018,98,2644.07 +318,Kirbie,Hickford,khickford8t@phoca.cz,Female,222.19.145.98,2/18/2019,75,2101.99 +319,Justen,Simonsson,jsimonsson8u@goodreads.com,Male,50.143.144.122,5/18/2019,23,3668.84 +320,Base,Quainton,bquainton8v@quantcast.com,Male,210.105.216.149,9/25/2019,17,3690.64 +321,Evonne,Biss,ebiss8w@blogspot.com,Female,151.218.87.78,6/20/2019,54,2157.7 +322,Desmund,Naris,dnaris8x@cafepress.com,Male,158.117.9.15,4/8/2019,55,3607.48 +323,Briant,Pulley,bpulley8y@rediff.com,Male,226.108.222.137,7/8/2019,4,2048.56 +324,Neddy,Wannop,nwannop8z@cisco.com,Male,183.31.92.122,8/27/2019,59,3925.77 +325,Trip,Eberst,teberst90@so-net.ne.jp,Male,147.174.43.177,3/9/2019,54,3125.57 +326,Feodor,Ccomini,fccomini91@patch.com,Male,101.243.251.93,9/13/2019,9,1769.13 +327,Lazar,Krinks,lkrinks92@infoseek.co.jp,Male,21.83.214.146,10/20/2019,24,4619.45 +328,Tate,Kedslie,tkedslie93@businesswire.com,Female,141.169.231.230,5/30/2019,49,1552.68 +329,Jessee,Boggon,jboggon94@kickstarter.com,Male,203.194.131.251,11/9/2019,24,1485.03 +330,Doralyn,Durrad,ddurrad95@google.co.jp,Female,240.121.195.82,7/8/2019,86,2176.49 +331,Jesse,Thynn,jthynn96@usnews.com,Male,199.184.188.96,12/29/2018,33,2828.35 +332,Emlyn,Redparth,eredparth97@naver.com,Female,23.58.23.190,9/1/2019,55,1076.4 +333,Gusella,Dimsdale,gdimsdale98@fema.gov,Female,126.167.16.255,5/27/2019,98,3454.61 +334,Dunn,Rentalll,drentalll99@japanpost.jp,Male,222.206.129.103,7/25/2019,85,1144.19 +335,Hyacintha,Coltan,hcoltan9a@creativecommons.org,Female,109.55.166.241,4/4/2019,87,1786.85 +336,Hyacinthe,Matyatin,hmatyatin9b@1und1.de,Female,110.109.78.10,7/3/2019,93,1671.35 +337,Adrian,Sollowaye,asollowaye9c@sitemeter.com,Male,33.129.1.150,11/4/2019,88,3482.58 +338,Arlina,Merriment,amerriment9d@census.gov,Female,236.177.140.9,11/17/2019,95,1747.4 +339,Anne-marie,Fakes,afakes9e@wix.com,Female,61.10.72.218,12/17/2018,67,1347.14 +340,Chico,Curgenuer,ccurgenuer9f@jugem.jp,Male,70.238.241.201,5/12/2019,90,4320.01 +341,Lonee,Roggerone,lroggerone9g@bizjournals.com,Female,176.243.54.186,4/28/2019,89,3039.36 +342,Kendell,Howett,khowett9h@fema.gov,Male,199.214.110.115,3/29/2019,12,2789.57 +343,Agatha,Dolligon,adolligon9i@canalblog.com,Female,34.170.13.241,12/20/2018,92,4743.08 +344,Ky,Fedder,kfedder9j@blogtalkradio.com,Male,163.0.64.234,6/29/2019,25,3252.69 +345,Wat,Kelsell,wkelsell9k@utexas.edu,Male,214.250.242.115,8/21/2019,70,2043.76 +346,Emyle,MacKean,emackean9l@networksolutions.com,Female,92.255.128.207,6/30/2019,1,3104.96 +347,Jeanette,Uridge,juridge9m@ucoz.com,Female,19.150.66.177,1/5/2019,64,4984.27 +348,Lilia,Vann,lvann9n@google.it,Female,89.252.120.154,10/16/2019,75,2663.58 +349,Cecile,Bromley,cbromley9o@unesco.org,Female,123.37.220.84,7/20/2019,54,2929.23 +350,Laureen,Twiddle,ltwiddle9p@narod.ru,Female,216.255.144.65,10/16/2019,19,1270.83 +351,Judas,de Clerc,jdeclerc9q@123-reg.co.uk,Male,70.252.28.9,7/19/2019,52,2346.55 +352,Ardeen,Loveman,aloveman9r@ow.ly,Female,156.219.46.63,2/10/2019,22,2964.62 +353,Raychel,Bilbie,rbilbie9s@cbslocal.com,Female,17.168.95.135,7/30/2019,77,2114.06 +354,Aylmer,Ortsmann,aortsmann9t@wufoo.com,Male,38.11.85.41,7/7/2019,93,3751.57 +355,Cassey,Ivanilov,civanilov9u@infoseek.co.jp,Female,55.185.103.167,8/19/2019,31,2292.8 +356,Hedwiga,Mabbitt,hmabbitt9v@hostgator.com,Female,138.225.43.83,5/18/2019,34,3855.85 +357,Andy,Selwin,aselwin9w@php.net,Female,125.221.82.185,11/12/2019,33,3992.33 +358,Alfonso,Waiton,awaiton9x@cam.ac.uk,Male,229.52.201.138,12/12/2018,79,4822.9 +359,Falito,Waugh,fwaugh9y@behance.net,Male,139.179.83.249,2/9/2019,58,4262.13 +360,Goldia,Devennie,gdevennie9z@globo.com,Female,201.225.234.254,6/29/2019,57,4846.5 +361,Charmaine,Craney,ccraneya0@tinypic.com,Female,225.240.75.169,7/12/2019,84,1316.62 +362,Zeke,Laidlow,zlaidlowa1@ehow.com,Male,166.40.176.121,7/4/2019,35,3356.21 +363,Brok,Drayton,bdraytona2@livejournal.com,Male,144.40.40.68,8/13/2019,11,4276.45 +364,Yorke,Stickins,ystickinsa3@joomla.org,Male,43.66.244.157,9/2/2019,69,4537.3 +365,Niven,Carlow,ncarlowa4@berkeley.edu,Male,172.206.45.58,7/5/2019,65,3926.86 +366,Dexter,Roycraft,droycrafta5@bbb.org,Male,77.45.212.134,7/21/2019,55,3035.99 +367,Nicoline,Maryin,nmaryina6@google.com.au,Female,47.168.8.172,8/1/2019,41,4917.76 +368,Ryon,Manuaud,rmanuauda7@domainmarket.com,Male,47.123.90.232,2/9/2019,74,2439.17 +369,Yehudi,Paylie,ypayliea8@domainmarket.com,Male,191.251.55.194,1/27/2019,6,1923.42 +370,Griffith,Tincey,gtinceya9@oaic.gov.au,Male,25.66.148.134,9/12/2019,39,2655.81 +371,Rafa,McLeman,rmclemanaa@mac.com,Female,230.203.148.84,5/6/2019,15,1870.44 +372,Ethel,Deuss,edeussab@hp.com,Female,28.53.103.241,5/16/2019,32,1469.62 +373,Vasily,Sockell,vsockellac@istockphoto.com,Male,56.222.178.227,3/11/2019,69,1735.2 +374,Lorenza,Adelsberg,ladelsbergad@fda.gov,Female,11.94.242.174,1/22/2019,86,3213.96 +375,Colas,Wakerley,cwakerleyae@hostgator.com,Male,145.79.64.143,10/18/2019,32,3929.61 +376,Corbie,Suthworth,csuthworthaf@so-net.ne.jp,Male,185.110.156.111,11/20/2019,59,1791.8 +377,Raviv,Burdon,rburdonag@google.cn,Male,199.130.230.228,8/31/2019,56,2672.48 +378,Willabella,Braybrook,wbraybrookah@wired.com,Female,21.168.228.152,8/23/2019,81,3055.15 +379,Stavro,Culley,sculleyai@rambler.ru,Male,200.89.13.168,7/13/2019,53,4163.02 +380,Even,Scargill,escargillaj@boston.com,Male,239.83.129.85,4/1/2019,3,3610.96 +381,Estell,Feltham,efelthamak@amazon.com,Female,15.107.128.8,12/17/2018,47,4775.21 +382,Babette,Vel,bvelal@spotify.com,Female,175.148.241.38,1/10/2019,41,3884.25 +383,Artair,Sonschein,asonscheinam@paginegialle.it,Male,127.94.90.52,9/23/2019,34,3579.98 +384,Pegeen,Taynton,ptayntonan@mozilla.org,Female,237.12.237.200,8/17/2019,83,4949.73 +385,Rubina,Yarnley,ryarnleyao@bravesites.com,Female,163.161.0.128,2/1/2019,48,2608.0 +386,Imojean,Swadlen,iswadlenap@behance.net,Female,187.101.162.242,11/26/2019,25,3891.41 +387,Remington,Hunnam,rhunnamaq@xrea.com,Male,155.26.3.155,3/2/2019,98,4085.69 +388,Cart,Symson,csymsonar@arstechnica.com,Male,65.122.8.87,12/12/2018,10,1780.3 +389,Kate,Fitzsimons,kfitzsimonsas@i2i.jp,Female,43.231.183.143,9/5/2019,8,4589.81 +390,Derril,Rimmington,drimmingtonat@homestead.com,Male,6.22.197.94,5/8/2019,63,3112.81 +391,Alyson,McCue,amccueau@wikia.com,Female,23.46.105.252,8/28/2019,70,3955.82 +392,Magdalen,Huncoot,mhuncootav@spiegel.de,Female,148.37.230.51,10/31/2019,2,4091.18 +393,Quincey,Tumilson,qtumilsonaw@webeden.co.uk,Male,56.32.172.37,4/8/2019,42,1930.92 +394,Patrick,Causer,pcauserax@ucsd.edu,Male,246.121.43.120,5/6/2019,93,4121.69 +395,Nadia,Vannuccini,nvannucciniay@ifeng.com,Female,136.227.239.1,6/28/2019,9,2309.55 +396,Grethel,Briggs,gbriggsaz@opensource.org,Female,74.158.54.139,12/18/2018,93,1324.43 +397,Carmelina,Witson,cwitsonb0@slate.com,Female,0.189.23.96,9/17/2019,95,2043.81 +398,Stanford,Gariff,sgariffb1@latimes.com,Male,30.67.52.138,11/28/2019,23,3754.58 +399,Broddie,Dunster,bdunsterb2@businesswire.com,Male,195.171.91.125,5/13/2019,35,1781.96 +400,Brigit,Brownsworth,bbrownsworthb3@yale.edu,Female,235.56.89.121,5/7/2019,11,2976.14 +401,Hillary,Daughtrey,hdaughtreyb4@zimbio.com,Male,171.99.161.95,3/31/2019,14,4683.28 +402,Rubetta,Ryding,rrydingb5@facebook.com,Female,121.209.254.88,2/16/2019,48,3181.31 +403,Darill,Giffin,dgiffinb6@so-net.ne.jp,Male,76.229.144.119,12/1/2019,20,1267.15 +404,Meredith,Leghorn,mleghornb7@google.co.jp,Female,88.130.30.36,3/6/2019,73,1165.58 +405,Godfrey,Kleinhandler,gkleinhandlerb8@auda.org.au,Male,202.128.125.132,2/14/2019,50,4151.4 +406,Andie,Tootell,atootellb9@netscape.com,Male,145.145.81.122,6/12/2019,41,1126.15 +407,Roselia,Craise,rcraiseba@java.com,Female,200.79.82.15,6/21/2019,56,4562.67 +408,Conny,Saice,csaicebb@baidu.com,Male,242.82.15.36,11/6/2019,20,4226.99 +409,Keary,Hartrick,khartrickbc@independent.co.uk,Male,189.126.222.123,12/13/2018,86,3150.61 +410,Salli,Scotchmer,sscotchmerbd@cloudflare.com,Female,229.204.119.25,1/15/2019,85,4684.69 +411,Verena,Everington,veveringtonbe@delicious.com,Female,49.206.228.25,4/25/2019,67,2869.88 +412,Bambi,Berzon,bberzonbf@dailymotion.com,Female,47.88.180.96,10/26/2019,67,4843.29 +413,Barbara,Kovacs,bkovacsbg@deliciousdays.com,Female,116.1.242.72,4/20/2019,43,2218.64 +414,Laurice,Adrianello,ladrianellobh@nbcnews.com,Female,69.69.82.208,6/21/2019,91,3331.25 +415,Nadine,Stenning,nstenningbi@tripadvisor.com,Female,105.204.235.18,9/2/2019,13,2037.16 +416,Cristina,Milsap,cmilsapbj@t-online.de,Female,36.13.98.63,12/4/2018,51,2933.37 +417,Kaleb,Easby,keasbybk@howstuffworks.com,Male,59.120.45.235,12/11/2018,4,1277.52 +418,Alister,Kyberd,akyberdbl@wsj.com,Male,184.221.78.151,5/1/2019,85,3931.28 +419,Roma,Uvedale,ruvedalebm@jigsy.com,Male,127.113.15.154,7/21/2019,71,4158.48 +420,Chrisse,Briggs,cbriggsbn@godaddy.com,Male,36.183.171.148,7/26/2019,63,1042.39 +421,Armin,Fidelus,afidelusbo@sogou.com,Male,207.188.30.35,1/13/2019,52,2565.26 +422,Helena,Harlow,hharlowbp@archive.org,Female,125.154.161.88,7/31/2019,11,3388.81 +423,Judy,Stone Fewings,jstonefewingsbq@youtube.com,Female,220.36.160.104,10/2/2019,54,2051.64 +424,Eddi,Gritsaev,egritsaevbr@sphinn.com,Female,36.194.183.230,6/1/2019,60,3020.44 +425,Royal,Juares,rjuaresbs@craigslist.org,Male,84.222.181.156,5/30/2019,30,2382.04 +426,Violette,Kopje,vkopjebt@blogs.com,Female,12.135.203.81,5/12/2019,61,3565.51 +427,Lesli,Franses,lfransesbu@histats.com,Female,124.138.107.148,11/22/2019,71,2644.08 +428,Alric,Barehead,abareheadbv@stumbleupon.com,Male,220.251.223.254,12/17/2018,6,2989.17 +429,Karin,Rosingdall,krosingdallbw@ucoz.ru,Female,83.135.106.197,8/9/2019,89,1199.79 +430,Margaretta,Hartles,mhartlesbx@google.com.br,Female,146.47.193.138,10/15/2019,82,1786.77 +431,Broderic,Adenot,badenotby@upenn.edu,Male,131.77.120.209,9/22/2019,15,4020.02 +432,Konstanze,Scintsbury,kscintsburybz@eepurl.com,Female,187.225.93.97,9/12/2019,91,3882.0 +433,Heriberto,Branchett,hbranchettc0@google.ca,Male,47.131.19.61,9/10/2019,30,3830.84 +434,Dulcy,Moxham,dmoxhamc1@pinterest.com,Female,139.65.244.96,3/31/2019,48,1930.97 +435,Kakalina,Pellamont,kpellamontc2@51.la,Female,46.138.21.69,3/29/2019,53,2265.45 +436,Durward,McAlester,dmcalesterc3@wisc.edu,Male,43.93.21.201,4/1/2019,19,4312.73 +437,Alfy,Dawby,adawbyc4@alibaba.com,Female,60.254.119.60,7/12/2019,53,1447.77 +438,Rafferty,Cullabine,rcullabinec5@acquirethisname.com,Male,107.140.224.21,8/31/2019,10,4627.05 +439,Catlaina,Laurenty,claurentyc6@tripod.com,Female,72.146.104.69,5/8/2019,77,1050.26 +440,Yves,Kinnock,ykinnockc7@narod.ru,Male,212.80.251.121,9/24/2019,26,4289.62 +441,Rustie,Runham,rrunhamc8@google.cn,Male,14.208.111.115,3/30/2019,17,3840.32 +442,Shannon,Teece,steecec9@issuu.com,Female,224.215.224.129,11/26/2019,87,3028.32 +443,Tawsha,Huggons,thuggonsca@oakley.com,Female,28.182.47.108,12/9/2018,80,3985.84 +444,Jozef,Ropcke,jropckecb@washington.edu,Male,71.34.133.206,10/5/2019,51,2177.5 +445,Brittany,Treadgold,btreadgoldcc@dell.com,Female,70.179.135.39,10/6/2019,35,1239.98 +446,Reynolds,Dungay,rdungaycd@taobao.com,Male,198.198.184.105,3/17/2019,84,1401.56 +447,Deeyn,MacNeely,dmacneelyce@google.nl,Female,129.131.12.166,9/24/2019,67,2584.15 +448,Opalina,McAndrew,omcandrewcf@imgur.com,Female,170.144.235.40,9/27/2019,32,1990.03 +449,Annabell,Bowne,abownecg@tamu.edu,Female,15.103.10.164,11/4/2019,82,4979.86 +450,Shepherd,Toye,stoyech@oakley.com,Male,28.94.51.150,5/4/2019,79,3581.94 +451,Dolorita,Rowatt,drowattci@yale.edu,Female,199.209.35.59,1/7/2019,46,2901.35 +452,Gale,Fenich,gfenichcj@seattletimes.com,Female,117.140.18.113,2/2/2019,95,1402.56 +453,Salvidor,Ruperti,srupertick@mashable.com,Male,253.18.192.61,6/10/2019,83,4161.11 +454,Griffie,Colthard,gcolthardcl@google.com.br,Male,125.41.227.143,5/28/2019,72,2219.96 +455,York,Rittmeyer,yrittmeyercm@redcross.org,Male,117.143.157.105,12/25/2018,69,2618.72 +456,Sarene,Brantzen,sbrantzencn@dion.ne.jp,Female,243.21.1.226,1/14/2019,99,1604.26 +457,Maximilien,Jouhan,mjouhanco@dailymotion.com,Male,135.19.146.201,8/12/2019,22,2904.57 +458,Valma,Chipping,vchippingcp@last.fm,Female,106.227.96.134,12/11/2018,21,2367.02 +459,Delmar,Kaas,dkaascq@histats.com,Male,149.43.164.167,8/29/2019,33,1178.21 +460,Dalli,MacBain,dmacbaincr@tripod.com,Male,179.253.105.225,6/28/2019,57,4678.73 +461,Griz,Macquire,gmacquirecs@google.cn,Male,131.224.85.128,8/28/2019,22,1605.86 +462,Far,Ogden,fogdenct@reverbnation.com,Male,164.236.27.67,12/10/2018,46,3121.44 +463,Eleen,Norree,enorreecu@telegraph.co.uk,Female,172.69.9.125,4/6/2019,18,4440.78 +464,Franzen,Izkoveski,fizkoveskicv@issuu.com,Male,92.192.132.174,9/19/2019,12,2651.29 +465,Rhiamon,Saladino,rsaladinocw@wix.com,Female,123.91.96.42,4/10/2019,88,4982.0 +466,Franny,Grinin,fgrinincx@booking.com,Male,43.0.247.215,3/26/2019,89,3774.54 +467,Colin,O'Donohue,codonohuecy@go.com,Male,88.162.185.175,10/22/2019,3,3491.68 +468,Wendye,Compson,wcompsoncz@hud.gov,Female,136.150.155.64,11/13/2019,74,4538.45 +469,Dyane,Raithmill,draithmilld0@ted.com,Female,235.21.43.42,5/16/2019,17,3995.57 +470,Lacie,Dumper,ldumperd1@ycombinator.com,Female,211.130.88.136,5/5/2019,21,4467.62 +471,Talbert,Jurca,tjurcad2@soup.io,Male,110.180.63.75,4/11/2019,72,1047.55 +472,Blondelle,Ingerfield,bingerfieldd3@bbc.co.uk,Female,21.57.56.111,10/18/2019,36,4305.36 +473,Huntington,Keele,hkeeled4@wired.com,Male,29.115.183.130,1/18/2019,90,3988.22 +474,Merle,Lissenden,mlissendend5@google.ru,Male,181.207.215.130,9/9/2019,14,3780.87 +475,Ahmed,Lowthorpe,alowthorped6@fotki.com,Male,170.252.164.227,7/24/2019,56,1887.16 +476,Melli,Monsey,mmonseyd7@house.gov,Female,226.80.98.178,5/13/2019,14,2671.62 +477,Shelly,Flay,sflayd8@epa.gov,Female,77.216.133.212,7/25/2019,13,4660.94 +478,Ryun,Maffey,rmaffeyd9@discovery.com,Male,130.172.183.105,12/18/2018,45,3261.01 +479,Archer,Monksfield,amonksfieldda@google.com.br,Male,182.48.50.111,8/2/2019,52,3036.93 +480,Rosemonde,Wragg,rwraggdb@icq.com,Female,195.223.97.213,8/25/2019,56,1193.62 +481,Halsey,Robbeke,hrobbekedc@cnet.com,Male,232.48.110.118,2/3/2019,42,1298.35 +482,Paten,Paslow,ppaslowdd@instagram.com,Male,29.24.97.210,5/13/2019,98,2545.85 +483,Dora,Ghidoli,dghidolide@digg.com,Female,58.13.173.228,8/13/2019,89,2796.74 +484,Arlene,Dronsfield,adronsfielddf@t.co,Female,79.160.187.181,3/18/2019,55,2539.18 +485,Blakelee,Lipp,blippdg@sakura.ne.jp,Female,19.124.37.230,8/29/2019,1,4628.15 +486,Cecelia,Grinham,cgrinhamdh@twitter.com,Female,234.55.104.182,2/3/2019,48,1693.35 +487,Onofredo,Andreazzi,oandreazzidi@google.ca,Male,117.52.172.57,7/29/2019,53,2615.64 +488,Kiley,Burdekin,kburdekindj@shop-pro.jp,Female,201.52.16.189,8/24/2019,95,3929.48 +489,Bink,Kestin,bkestindk@chron.com,Male,100.111.135.87,7/13/2019,21,1958.77 +490,Mitch,Cagan,mcagandl@pagesperso-orange.fr,Male,25.244.113.46,10/16/2019,82,2492.12 +491,Charlton,Hughes,chughesdm@dmoz.org,Male,29.138.111.115,11/12/2019,10,3339.82 +492,Doria,Ivatts,divattsdn@nih.gov,Female,242.17.53.201,5/29/2019,72,2228.99 +493,Coriss,Lathan,clathando@domainmarket.com,Female,25.75.179.134,10/4/2019,23,4848.67 +494,Elmore,Reside,eresidedp@diigo.com,Male,79.112.126.164,9/21/2019,59,1610.62 +495,Ezekiel,Scherer,eschererdq@telegraph.co.uk,Male,79.39.63.134,8/28/2019,69,1597.98 +496,Werner,Cobson,wcobsondr@artisteer.com,Male,227.194.178.190,3/13/2019,53,4233.49 +497,Randee,Ornillos,rornillosds@youtube.com,Female,67.192.57.128,12/22/2018,59,2404.97 +498,Gottfried,Carloni,gcarlonidt@google.ca,Male,176.184.59.246,7/25/2019,33,4007.86 +499,Findlay,Ferrieroi,fferrieroidu@edublogs.org,Male,164.15.3.146,6/15/2019,29,1439.89 +500,Anestassia,Caldron,acaldrondv@imdb.com,Female,73.5.249.139,12/5/2018,77,4450.98 +501,Ignazio,Prinnett,iprinnettdw@merriam-webster.com,Male,254.189.253.253,5/26/2019,53,3955.94 +502,Debi,Sedgebeer,dsedgebeerdx@msn.com,Female,90.91.234.210,11/26/2019,96,1951.45 +503,Beverlee,Colliard,bcolliarddy@stanford.edu,Female,112.73.182.216,8/1/2019,60,4097.93 +504,Cinnamon,McFadin,cmcfadindz@blogs.com,Female,149.198.138.102,4/3/2019,80,3719.88 +505,Walden,Bruinemann,wbruinemanne0@360.cn,Male,21.212.132.5,11/7/2019,92,2275.38 +506,Quinton,Glanfield,qglanfielde1@amazon.de,Male,213.175.246.203,12/13/2018,8,4630.05 +507,Cello,Potkins,cpotkinse2@github.com,Male,135.169.51.63,3/16/2019,63,2813.83 +508,Percival,Coley,pcoleye3@photobucket.com,Male,205.135.254.197,1/14/2019,93,3766.81 +509,Brockie,Siddens,bsiddense4@usda.gov,Male,166.107.18.144,7/26/2019,11,4226.07 +510,Emmerich,Eglise,eeglisee5@istockphoto.com,Male,39.239.19.196,11/3/2019,23,1444.76 +511,Theo,Olivetta,tolivettae6@yellowpages.com,Male,135.95.4.136,8/1/2019,59,3670.72 +512,Gabie,Blasius,gblasiuse7@vistaprint.com,Male,176.138.63.24,3/12/2019,100,3276.6 +513,Tiebold,Wharmby,twharmbye8@chicagotribune.com,Male,204.219.78.122,6/13/2019,73,3542.76 +514,Tann,Duke,tdukee9@irs.gov,Male,153.153.136.24,3/14/2019,70,2338.35 +515,Westley,Ottery,wotteryea@soundcloud.com,Male,35.239.11.15,9/18/2019,61,2876.26 +516,Noll,Birkmyre,nbirkmyreeb@histats.com,Male,45.218.226.8,5/4/2019,3,3180.04 +517,Angelle,Canizares,acanizaresec@usgs.gov,Female,79.98.22.161,11/16/2019,57,1414.53 +518,Maddy,Rawlins,mrawlinsed@ocn.ne.jp,Female,194.212.205.87,8/24/2019,9,2037.3 +519,Gonzales,Digle,gdigleee@tinyurl.com,Male,188.81.253.229,2/11/2019,31,1096.61 +520,Matias,Arrighetti,marrighettief@jimdo.com,Male,119.210.95.197,10/13/2019,59,1525.12 +521,Ag,Almon,aalmoneg@discuz.net,Female,211.209.145.71,5/9/2019,5,1832.58 +522,Romona,Keppel,rkeppeleh@auda.org.au,Female,180.44.222.236,12/5/2018,69,1470.18 +523,Aeriel,Seear,aseearei@over-blog.com,Female,132.233.16.148,6/8/2019,20,4592.62 +524,Terri,Trulocke,ttrulockeej@clickbank.net,Female,138.176.80.221,10/1/2019,5,1787.96 +525,Linn,Stonestreet,lstonestreetek@un.org,Male,74.243.5.94,11/27/2019,31,1779.4 +526,Dmitri,Coode,dcoodeel@ameblo.jp,Male,201.81.71.70,1/25/2019,94,1400.26 +527,Alane,Sabattier,asabattierem@scribd.com,Female,32.109.38.132,10/10/2019,10,1416.04 +528,Sadye,Esplin,sesplinen@tiny.cc,Female,76.85.72.29,3/14/2019,45,3626.01 +529,Alexia,Iorizzo,aiorizzoeo@themeforest.net,Female,172.234.209.31,7/10/2019,46,4064.06 +530,Gayelord,Kalewe,gkaleweep@over-blog.com,Male,83.169.129.240,9/10/2019,53,1508.96 +531,Clive,Stuchbery,cstuchberyeq@dell.com,Male,9.182.133.41,12/29/2018,21,4980.91 +532,Derron,Lober,dloberer@epa.gov,Male,184.138.78.88,2/14/2019,24,2245.42 +533,Aleda,Addison,aaddisones@wsj.com,Female,181.181.179.67,6/17/2019,81,4493.79 +534,Marshall,Ugolotti,mugolottiet@aboutads.info,Male,159.50.251.20,7/3/2019,35,1104.16 +535,Garold,Moxon,gmoxoneu@slashdot.org,Male,117.142.41.149,10/7/2019,34,2523.56 +536,Fee,Colleer,fcolleerev@state.gov,Male,207.42.100.89,4/12/2019,87,4816.8 +537,Smitty,Smallridge,ssmallridgeew@spotify.com,Male,132.67.213.163,2/26/2019,84,3814.0 +538,Ber,Pettegre,bpettegreex@google.ru,Male,8.176.93.49,9/6/2019,67,3272.53 +539,Tybi,Brown,tbrowney@ibm.com,Female,100.73.19.52,3/7/2019,76,1088.01 +540,Roxanne,Rigler,rriglerez@weebly.com,Female,29.96.199.117,4/1/2019,65,2694.03 +541,Alphonse,Astlett,aastlettf0@hatena.ne.jp,Male,244.194.52.149,7/29/2019,47,1467.11 +542,Calvin,Finn,cfinnf1@ucoz.com,Male,199.41.9.21,12/30/2018,7,1828.33 +543,Broddie,Brandts,bbrandtsf2@answers.com,Male,100.8.254.225,10/29/2019,64,1792.68 +544,Herrick,Chadderton,hchaddertonf3@wired.com,Male,187.66.85.223,3/1/2019,38,3230.59 +545,Teodoor,Benny,tbennyf4@home.pl,Male,6.177.43.100,4/29/2019,13,2503.4 +546,Karl,Wrintmore,kwrintmoref5@apple.com,Male,73.104.69.176,8/7/2019,97,2688.4 +547,Alexandra,Testo,atestof6@loc.gov,Female,15.230.156.211,6/9/2019,84,4522.93 +548,Colin,Giorgietto,cgiorgiettof7@nymag.com,Male,13.75.177.91,2/21/2019,3,3730.12 +549,Talbot,McNickle,tmcnicklef8@wp.com,Male,44.250.27.152,3/18/2019,30,2209.95 +550,Cassandre,Hayle,chaylef9@newyorker.com,Female,116.81.18.95,11/21/2019,10,3204.22 +551,Tommi,Bilney,tbilneyfa@prweb.com,Female,61.67.100.120,10/16/2019,79,3613.66 +552,Larisa,Pollok,lpollokfb@loc.gov,Female,79.115.80.86,9/30/2019,29,1901.41 +553,Deb,Dorkins,ddorkinsfc@xrea.com,Female,26.52.68.180,10/15/2019,99,4906.29 +554,Johanna,Kainz,jkainzfd@chronoengine.com,Female,142.73.143.215,8/18/2019,4,1226.42 +555,Gasparo,Handrek,ghandrekfe@vinaora.com,Male,21.21.61.211,10/16/2019,91,1731.15 +556,Elwyn,Zahor,ezahorff@washingtonpost.com,Male,184.132.148.138,1/5/2019,55,1626.51 +557,Devina,De Vaar,ddevaarfg@miibeian.gov.cn,Female,195.180.225.61,7/12/2019,2,4095.24 +558,Ikey,Verner,ivernerfh@msu.edu,Male,175.129.187.1,8/8/2019,10,1643.3 +559,Shae,Potteril,spotterilfi@cyberchimps.com,Male,135.218.100.211,9/30/2019,43,2747.3 +560,Kim,Kittel,kkittelfj@buzzfeed.com,Male,224.125.75.142,12/12/2018,17,4109.17 +561,Alexei,Morecomb,amorecombfk@independent.co.uk,Male,172.224.245.105,12/9/2018,33,2899.08 +562,Cathryn,Finnan,cfinnanfl@ask.com,Female,27.110.235.165,5/28/2019,94,4841.66 +563,Maryjane,Duffus,mduffusfm@eventbrite.com,Female,3.255.15.114,10/22/2019,54,1514.19 +564,Violetta,Reisk,vreiskfn@typepad.com,Female,39.227.35.28,4/18/2019,92,4609.62 +565,Vicky,Lots,vlotsfo@cisco.com,Female,231.114.228.254,7/16/2019,5,2747.65 +566,Odilia,Shemmans,oshemmansfp@phpbb.com,Female,173.16.238.214,7/15/2019,64,2509.13 +567,Doralynn,Borne,dbornefq@vistaprint.com,Female,182.193.106.25,9/27/2019,58,2388.86 +568,Gallagher,Tinsey,gtinseyfr@wsj.com,Male,222.169.135.174,8/26/2019,9,2587.26 +569,Ulberto,Hellyar,uhellyarfs@yellowbook.com,Male,248.76.37.74,7/15/2019,30,1922.6 +570,Carilyn,Skones,cskonesft@liveinternet.ru,Female,156.207.111.147,5/19/2019,37,4692.05 +571,Sarine,Rubinovitch,srubinovitchfu@networksolutions.com,Female,80.120.49.55,8/19/2019,20,1594.95 +572,Jemmy,Marlowe,jmarlowefv@engadget.com,Female,75.14.237.58,4/14/2019,51,1904.61 +573,Gaby,Demelt,gdemeltfw@infoseek.co.jp,Male,229.88.216.80,2/3/2019,51,1648.97 +574,Jacob,Lamberton,jlambertonfx@hugedomains.com,Male,47.215.55.112,11/23/2019,98,2245.77 +575,Emile,Bullivent,ebulliventfy@is.gd,Male,222.149.227.61,1/14/2019,28,2610.31 +576,Reidar,Gierardi,rgierardifz@flickr.com,Male,137.20.90.27,7/14/2019,44,1963.44 +577,Dwain,De Mars,ddemarsg0@theglobeandmail.com,Male,29.126.92.147,5/8/2019,83,2977.28 +578,Seth,Hebron,shebrong1@github.io,Male,97.93.183.184,2/17/2019,17,2725.06 +579,Shep,Rabjohn,srabjohng2@sfgate.com,Male,118.230.96.220,4/5/2019,75,4150.25 +580,Georgine,Martill,gmartillg3@who.int,Female,89.160.34.190,1/8/2019,37,4712.71 +581,Theodora,Mitchenson,tmitchensong4@delicious.com,Female,140.245.239.155,4/11/2019,58,1505.59 +582,Geri,Reedman,greedmang5@mac.com,Male,149.218.213.221,6/22/2019,29,3919.37 +583,Hamel,Ruddick,hruddickg6@uiuc.edu,Male,74.103.5.12,3/19/2019,32,2242.44 +584,Marylou,Baggott,mbaggottg7@goo.gl,Female,67.211.254.135,11/7/2019,35,4631.99 +585,Ignacius,Croisdall,icroisdallg8@imdb.com,Male,194.136.32.103,4/9/2019,22,4505.82 +586,Agnes,Pentercost,apentercostg9@yolasite.com,Female,201.109.22.156,4/7/2019,6,2659.75 +587,Phillipe,O'Henery,poheneryga@baidu.com,Male,169.210.213.194,4/28/2019,100,3089.16 +588,Mersey,Bilston,mbilstongb@mozilla.org,Female,212.118.21.202,6/6/2019,47,1546.62 +589,Carie,Pawelski,cpawelskigc@examiner.com,Female,185.32.131.13,12/23/2018,13,1607.17 +590,Cassandra,Zywicki,czywickigd@ask.com,Female,58.164.239.126,10/6/2019,86,3316.82 +591,Myrtia,Avrasin,mavrasinge@tripod.com,Female,23.46.205.131,6/2/2019,28,1376.97 +592,Stanford,Greatrakes,sgreatrakesgf@europa.eu,Male,110.99.123.217,12/31/2018,89,4653.75 +593,Giulietta,Hinkens,ghinkensgg@list-manage.com,Female,146.42.27.152,3/17/2019,90,4663.89 +594,Dame,Eam,deamgh@jalbum.net,Male,93.210.79.222,12/3/2018,99,4955.03 +595,Claresta,Spradbery,cspradberygi@wunderground.com,Female,177.74.189.41,5/7/2019,69,2660.67 +596,Charisse,Janos,cjanosgj@yellowbook.com,Female,107.1.160.123,11/30/2019,27,3260.09 +597,Mufi,Letterick,mletterickgk@apache.org,Female,230.153.229.231,6/16/2019,59,2986.56 +598,Fabe,Sabberton,fsabbertongl@mapquest.com,Male,219.168.121.194,7/18/2019,70,3658.28 +599,Nikolas,Gildersleaves,ngildersleavesgm@ox.ac.uk,Male,162.123.231.93,7/20/2019,78,1233.59 +600,Justin,Vigours,jvigoursgn@sourceforge.net,Male,154.142.42.26,6/28/2019,31,4990.95 +601,Kile,Le Clercq,kleclercqgo@indiatimes.com,Male,239.28.13.21,12/13/2018,84,1001.19 +602,Isidoro,Tregonna,itregonnagp@webeden.co.uk,Male,171.67.239.44,1/16/2019,41,4417.17 +603,Mab,Ironside,mironsidegq@google.cn,Female,42.162.241.202,7/23/2019,91,2259.53 +604,Dimitry,Manass,dmanassgr@51.la,Male,45.173.17.98,1/25/2019,46,1586.27 +605,Rossy,Arden,rardengs@bigcartel.com,Male,214.115.174.58,4/28/2019,51,1823.4 +606,Daniele,Barnard,dbarnardgt@so-net.ne.jp,Female,135.128.233.112,2/1/2019,71,3995.81 +607,Helene,Westphalen,hwestphalengu@addthis.com,Female,106.111.55.197,11/15/2019,95,2675.0 +608,Zeke,Mixer,zmixergv@europa.eu,Male,70.187.67.163,2/1/2019,26,1019.63 +609,Modesta,Cock,mcockgw@berkeley.edu,Female,16.132.149.179,1/19/2019,79,2922.43 +610,Bard,Vieyra,bvieyragx@shinystat.com,Male,192.107.97.186,10/5/2019,17,4998.16 +611,Boote,Geall,bgeallgy@networksolutions.com,Male,54.164.158.9,1/1/2019,95,3385.89 +612,Ninnetta,Loveman,nlovemangz@histats.com,Female,25.150.239.54,9/19/2019,24,3487.97 +613,Sigismund,Fitzer,sfitzerh0@163.com,Male,93.203.46.222,9/7/2019,26,3405.11 +614,Perren,Haquin,phaquinh1@networkadvertising.org,Male,27.195.139.40,7/13/2019,95,4472.37 +615,Ramsay,Galland,rgallandh2@sohu.com,Male,64.157.166.62,2/15/2019,30,3256.71 +616,Silva,Strete,sstreteh3@yellowpages.com,Female,28.120.167.41,10/30/2019,67,4109.49 +617,Dee dee,Poate,dpoateh4@github.io,Female,169.234.44.240,1/26/2019,87,2487.52 +618,Bianca,Martell,bmartellh5@bloomberg.com,Female,17.155.34.89,12/5/2018,88,2523.49 +619,Alan,Wallwork,awallworkh6@bloglines.com,Male,136.41.225.203,11/17/2019,32,2593.63 +620,Alysa,Lembrick,alembrickh7@github.io,Female,4.186.245.140,3/12/2019,42,4087.94 +621,Yoshiko,Alans,yalansh8@list-manage.com,Female,113.124.38.19,1/8/2019,5,3091.72 +622,Chelsy,Watford,cwatfordh9@yellowpages.com,Female,10.18.35.232,5/4/2019,86,4661.23 +623,Bill,Gotthard,bgotthardha@moonfruit.com,Male,169.67.131.116,5/21/2019,11,1287.77 +624,Cad,Kirtlan,ckirtlanhb@xrea.com,Male,40.152.181.2,1/24/2019,24,3155.78 +625,Ahmed,McClenan,amcclenanhc@webmd.com,Male,20.99.191.248,8/13/2019,36,3301.08 +626,Tobit,Barthelemy,tbarthelemyhd@bizjournals.com,Male,35.143.211.133,9/10/2019,98,1382.31 +627,Kacie,Lurner,klurnerhe@illinois.edu,Female,4.70.92.52,3/14/2019,58,3754.13 +628,Keith,Skeech,kskeechhf@pbs.org,Male,14.243.98.120,8/22/2019,99,2840.36 +629,Loy,Brettoner,lbrettonerhg@marriott.com,Male,244.228.186.208,5/28/2019,83,1322.53 +630,Ring,Keppy,rkeppyhh@mediafire.com,Male,63.223.185.137,10/29/2019,49,3414.88 +631,Jennee,Saltsberg,jsaltsberghi@angelfire.com,Female,168.154.55.70,2/20/2019,89,1792.13 +632,Leslie,Sunley,lsunleyhj@furl.net,Female,142.154.216.195,1/14/2019,85,1049.36 +633,Serge,Brightman,sbrightmanhk@nsw.gov.au,Male,218.24.194.199,8/25/2019,17,3821.08 +634,Thadeus,Janosevic,tjanosevichl@auda.org.au,Male,117.42.23.253,6/4/2019,12,3771.8 +635,Spense,Ribchester,sribchesterhm@google.cn,Male,60.125.96.255,3/20/2019,10,4152.59 +636,Cordelia,Petrashov,cpetrashovhn@jalbum.net,Female,4.255.192.99,5/3/2019,42,4778.71 +637,Rhea,Jest,rjestho@hao123.com,Female,60.250.169.224,11/1/2019,88,3984.23 +638,Patricia,Feehery,pfeeheryhp@dot.gov,Female,238.226.108.19,1/3/2019,72,2436.71 +639,Griffie,Haswell,ghaswellhq@linkedin.com,Male,141.208.249.19,3/30/2019,54,4591.33 +640,Isahella,Brockett,ibrocketthr@webnode.com,Female,187.222.253.93,8/18/2019,40,2025.08 +641,Rhea,Castiglioni,rcastiglionihs@cpanel.net,Female,59.223.205.19,3/28/2019,8,4878.09 +642,Stu,Gladman,sgladmanht@yandex.ru,Male,148.174.89.129,2/7/2019,6,4658.63 +643,Meade,Penn,mpennhu@tinypic.com,Female,159.237.205.132,7/14/2019,67,1741.76 +644,Analise,Teesdale,ateesdalehv@istockphoto.com,Female,112.255.159.227,4/27/2019,43,4943.97 +645,Gabbie,Gawith,ggawithhw@bing.com,Male,156.88.177.49,9/1/2019,30,2127.26 +646,Fancie,Matura,fmaturahx@prweb.com,Female,245.199.208.176,10/14/2019,48,3611.12 +647,Oneida,Klee,okleehy@merriam-webster.com,Female,76.241.235.4,4/24/2019,75,3574.83 +648,Patty,Deadman,pdeadmanhz@deviantart.com,Female,119.238.140.122,12/3/2018,78,4990.77 +649,Rica,Habbershon,rhabbershoni0@imdb.com,Female,235.54.40.9,8/21/2019,72,4008.1 +650,Dominick,Morphey,dmorpheyi1@state.gov,Male,26.182.126.198,9/27/2019,32,2803.47 +651,Lin,Elvey,lelveyi2@qq.com,Female,217.142.5.50,5/2/2019,75,1382.58 +652,Candra,Ellershaw,cellershawi3@liveinternet.ru,Female,37.103.239.8,11/5/2019,64,1785.17 +653,Petr,Blamey,pblameyi4@cornell.edu,Male,102.165.209.59,11/16/2019,23,4146.8 +654,Starlene,Shoebrook,sshoebrooki5@un.org,Female,168.143.167.147,3/14/2019,4,4991.14 +655,Rochelle,Inggall,ringgalli6@biglobe.ne.jp,Female,102.127.212.247,9/12/2019,81,1583.69 +656,Ezmeralda,Jubert,ejuberti7@icio.us,Female,81.4.17.157,7/22/2019,52,4205.34 +657,Berny,Crufts,bcruftsi8@jigsy.com,Female,244.211.38.231,1/6/2019,46,4968.82 +658,Philis,Hitzke,phitzkei9@google.es,Female,206.218.221.24,10/5/2019,21,2082.32 +659,Dacey,Beck,dbeckia@netscape.com,Female,52.22.157.97,4/17/2019,22,3785.01 +660,Lammond,Esmead,lesmeadib@slate.com,Male,216.172.89.83,4/11/2019,87,4186.81 +661,Bevin,Pattullo,bpattulloic@yelp.com,Male,96.237.177.242,9/30/2019,9,3862.46 +662,Abbie,Melsom,amelsomid@businesswire.com,Female,226.28.218.124,8/28/2019,98,4520.86 +663,Hilarius,Weagener,hweagenerie@google.nl,Male,6.108.117.111,9/10/2019,80,4920.12 +664,Onida,Dewberry,odewberryif@chron.com,Female,95.189.17.251,7/12/2019,27,1206.75 +665,Sawyer,Behne,sbehneig@who.int,Male,232.40.190.187,6/26/2019,92,2730.93 +666,Ingaborg,Benoit,ibenoitih@diigo.com,Female,45.171.74.30,2/26/2019,79,3169.39 +667,Christyna,Beardow,cbeardowii@hibu.com,Female,212.112.66.197,8/15/2019,22,1664.25 +668,Chrysa,Bouda,cboudaij@posterous.com,Female,182.254.214.92,6/20/2019,58,4842.58 +669,Skell,Janny,sjannyik@statcounter.com,Male,117.115.79.57,8/25/2019,64,3147.82 +670,Willie,Gisbye,wgisbyeil@smh.com.au,Male,163.74.14.6,12/24/2018,60,2181.71 +671,Loydie,MacGiolla Pheadair,lmacgiollapheadairim@ftc.gov,Male,66.165.25.118,12/24/2018,17,4234.43 +672,Millisent,Warwick,mwarwickin@google.co.uk,Female,11.125.80.152,5/27/2019,57,2770.04 +673,Lutero,Campelli,lcampelliio@alibaba.com,Male,218.66.248.154,10/4/2019,29,4169.81 +674,Waverly,Kroch,wkrochip@google.co.uk,Male,117.138.8.158,10/6/2019,55,2248.55 +675,Jorge,Tipple,jtippleiq@google.cn,Male,75.32.226.30,1/5/2019,20,2316.81 +676,Rycca,Markham,rmarkhamir@posterous.com,Female,108.165.80.206,4/1/2019,37,3733.9 +677,Kendell,Tabourel,ktabourelis@ucsd.edu,Male,31.106.135.186,1/27/2019,41,2767.65 +678,Xymenes,Christofol,xchristofolit@slashdot.org,Male,205.98.142.54,4/17/2019,75,3761.36 +679,Willamina,Gluyas,wgluyasiu@patch.com,Female,208.141.12.123,9/10/2019,62,4055.56 +680,Missy,Chaudron,mchaudroniv@ox.ac.uk,Female,253.225.93.169,5/17/2019,54,3188.83 +681,Harrie,Levee,hleveeiw@dropbox.com,Female,104.60.96.6,9/4/2019,73,3779.89 +682,Nickie,Awdry,nawdryix@deviantart.com,Female,186.254.251.36,1/3/2019,76,2909.63 +683,Wash,Mapletoft,wmapletoftiy@baidu.com,Male,176.231.204.160,2/12/2019,3,1072.43 +684,Thea,Crankshaw,tcrankshawiz@bluehost.com,Female,240.218.215.50,12/5/2018,41,2503.95 +685,Bryna,Clemmen,bclemmenj0@slate.com,Female,117.149.65.242,6/24/2019,33,2635.47 +686,Fiann,Dipple,fdipplej1@usda.gov,Female,13.222.48.15,5/1/2019,97,4530.95 +687,Hilliary,Nowell,hnowellj2@jigsy.com,Female,237.64.236.63,9/8/2019,4,3931.64 +688,Francene,Perfitt,fperfittj3@upenn.edu,Female,35.17.66.62,3/5/2019,24,4353.24 +689,Adair,Foucher,afoucherj4@google.com,Male,184.228.99.56,5/7/2019,75,3261.23 +690,Evyn,Cristou,ecristouj5@xrea.com,Male,114.91.151.161,7/17/2019,95,3655.93 +691,Carleton,Mooreed,cmooreedj6@walmart.com,Male,17.30.55.141,8/31/2019,66,1486.95 +692,Ashley,Wallage,awallagej7@dyndns.org,Male,214.116.89.237,5/6/2019,17,3179.86 +693,Corney,Healeas,chealeasj8@phoca.cz,Male,36.170.221.28,12/24/2018,29,3068.73 +694,Marabel,Abbado,mabbadoj9@google.nl,Female,56.208.153.166,4/15/2019,4,4988.67 +695,Barr,Gregr,bgregrja@mozilla.com,Male,118.210.102.100,5/28/2019,31,2310.92 +696,Ulrika,Verni,uvernijb@hhs.gov,Female,252.208.223.205,3/13/2019,34,4254.15 +697,Carri,McWilliam,cmcwilliamjc@unblog.fr,Female,244.144.133.38,2/26/2019,57,4082.44 +698,Ciro,Burnet,cburnetjd@simplemachines.org,Male,56.117.3.236,11/7/2019,71,2943.82 +699,Eryn,Lindblom,elindblomje@paginegialle.it,Female,218.110.190.80,10/26/2019,98,3327.13 +700,Tandi,Jenney,tjenneyjf@sciencedirect.com,Female,61.111.94.217,8/9/2019,63,3161.01 +701,Karissa,McGeachy,kmcgeachyjg@themeforest.net,Female,97.151.85.120,3/15/2019,75,2793.19 +702,Daisie,Gosling,dgoslingjh@yale.edu,Female,80.132.185.177,12/24/2018,99,2564.95 +703,Web,Waters,wwatersji@icio.us,Male,138.42.236.158,11/26/2019,12,3133.25 +704,Beulah,Saltrese,bsaltresejj@rakuten.co.jp,Female,111.246.77.69,5/10/2019,85,1562.53 +705,Shea,Bansal,sbansaljk@timesonline.co.uk,Male,45.157.189.79,6/13/2019,64,4095.48 +706,Granger,Maddyson,gmaddysonjl@cdbaby.com,Male,4.174.208.225,10/22/2019,90,2312.31 +707,Frederic,Ferras,fferrasjm@europa.eu,Male,93.89.74.109,4/21/2019,1,2688.0 +708,Terri-jo,Blockwell,tblockwelljn@diigo.com,Female,139.206.39.244,10/28/2019,77,2032.65 +709,Portia,Messum,pmessumjo@cpanel.net,Female,205.8.231.154,7/5/2019,7,3703.36 +710,Fay,Bleakley,fbleakleyjp@fema.gov,Female,51.78.72.116,11/14/2019,97,4827.37 +711,Blayne,Marnane,bmarnanejq@nasa.gov,Male,254.10.160.105,11/17/2019,59,4393.22 +712,Brooke,Dreinan,bdreinanjr@yandex.ru,Male,101.190.49.170,7/13/2019,91,3896.42 +713,Dannie,Butten,dbuttenjs@w3.org,Male,254.183.249.58,7/3/2019,49,4087.49 +714,Niki,Gooch,ngoochjt@huffingtonpost.com,Male,14.126.59.16,2/13/2019,81,3541.85 +715,Penny,Bovis,pbovisju@macromedia.com,Female,194.73.1.154,9/15/2019,22,3343.77 +716,Agna,Wellings,awellingsjv@economist.com,Female,18.191.109.188,6/20/2019,59,3995.96 +717,Kelsi,Binestead,kbinesteadjw@weibo.com,Female,209.183.105.9,6/22/2019,10,2251.08 +718,Lucio,MacLennan,lmaclennanjx@oracle.com,Male,138.238.128.41,6/18/2019,76,4327.17 +719,Leonora,Shailer,lshailerjy@illinois.edu,Female,119.146.115.106,12/20/2018,29,4657.75 +720,Fonsie,O'Doogan,fodooganjz@cbsnews.com,Male,130.108.253.158,8/21/2019,94,1870.33 +721,Stearne,Claire,sclairek0@booking.com,Male,131.59.84.18,4/11/2019,98,3369.19 +722,Maye,Howis,mhowisk1@buzzfeed.com,Female,22.69.128.140,9/8/2019,85,1974.16 +723,Orton,Kiffe,okiffek2@github.com,Male,81.226.255.158,10/22/2019,52,3864.03 +724,Barty,Leadbeater,bleadbeaterk3@amazon.de,Male,208.66.100.248,4/24/2019,28,4214.56 +725,Sidnee,Coxhead,scoxheadk4@cam.ac.uk,Male,62.75.3.110,2/16/2019,8,4882.21 +726,Worden,Quan,wquank5@telegraph.co.uk,Male,86.238.192.197,3/13/2019,3,4136.64 +727,Brad,Marlor,bmarlork6@chron.com,Male,205.102.239.46,1/10/2019,27,3958.67 +728,Jefferson,Fanning,jfanningk7@google.de,Male,139.239.121.50,10/19/2019,26,3356.51 +729,North,Leidecker,nleideckerk8@nyu.edu,Male,240.19.0.156,4/1/2019,27,4866.45 +730,Chrissy,Rounsefull,crounsefullk9@topsy.com,Female,181.133.238.56,12/31/2018,19,1456.66 +731,Jennine,D'eathe,jdeatheka@ow.ly,Female,82.172.76.47,10/8/2019,87,1326.34 +732,Nedda,Hyland,nhylandkb@unesco.org,Female,85.174.186.120,10/9/2019,67,4967.34 +733,Ripley,Bavester,rbavesterkc@facebook.com,Male,200.70.120.11,7/30/2019,67,3364.31 +734,Amandi,Angrove,aangrovekd@hud.gov,Female,51.90.237.193,10/18/2019,98,3962.5 +735,Jandy,Fritchley,jfritchleyke@youtu.be,Female,236.202.35.177,11/17/2019,79,4641.47 +736,Kevin,Tozer,ktozerkf@godaddy.com,Male,92.185.81.191,9/20/2019,75,2652.18 +737,Erinna,Bucke,ebuckekg@hugedomains.com,Female,134.19.86.195,1/16/2019,19,4117.83 +738,Melania,Margach,mmargachkh@pagesperso-orange.fr,Female,57.86.172.205,1/22/2019,34,4369.1 +739,Darryl,Besset,dbessetki@canalblog.com,Female,150.168.219.97,10/15/2019,85,2449.44 +740,Urbano,Loy,uloykj@vistaprint.com,Male,192.95.90.230,1/29/2019,66,1697.74 +741,Shanan,Titcombe,stitcombekk@addtoany.com,Male,78.104.122.110,1/2/2019,31,2712.55 +742,North,Kropp,nkroppkl@huffingtonpost.com,Male,123.193.124.129,7/19/2019,32,2129.1 +743,Dario,Mennithorp,dmennithorpkm@nifty.com,Male,10.142.173.99,11/4/2019,64,2962.06 +744,Sally,Clerk,sclerkkn@youtu.be,Female,67.123.50.70,11/27/2019,32,4948.27 +745,Phillida,Grishkov,pgrishkovko@hatena.ne.jp,Female,105.59.57.150,5/19/2019,78,2513.36 +746,Warren,Gauthorpp,wgauthorppkp@dailymotion.com,Male,109.33.209.101,3/24/2019,74,3859.6 +747,Yurik,McArthur,ymcarthurkq@time.com,Male,177.53.197.246,6/4/2019,25,1927.47 +748,Lucine,Pritchett,lpritchettkr@adobe.com,Female,214.120.212.72,5/5/2019,44,3376.03 +749,Reeba,Facchini,rfacchiniks@fotki.com,Female,62.203.183.86,3/16/2019,29,2413.06 +750,Marys,MacGaughey,mmacgaugheykt@blogger.com,Female,241.223.207.143,7/28/2019,84,2694.2 +751,Abdul,Rollett,arollettku@intel.com,Male,224.183.67.157,5/16/2019,100,3327.64 +752,Lorry,Wolstenholme,lwolstenholmekv@facebook.com,Female,54.19.245.157,4/24/2019,43,4692.53 +753,Kore,Illingworth,killingworthkw@1und1.de,Female,4.3.169.154,11/2/2019,94,2378.36 +754,Mikel,Welbrock,mwelbrockkx@so-net.ne.jp,Male,94.86.96.2,5/16/2019,74,3938.38 +755,Debby,Largan,dlarganky@mozilla.org,Female,99.67.157.53,10/14/2019,62,2417.72 +756,Brana,Wabe,bwabekz@eepurl.com,Female,243.219.60.35,9/27/2019,36,3520.16 +757,Dyana,Dagworthy,ddagworthyl0@statcounter.com,Female,248.115.199.134,1/29/2019,10,1238.39 +758,Jobi,McAndie,jmcandiel1@alibaba.com,Female,76.175.25.123,9/8/2019,27,2305.18 +759,Karlene,Jery,kjeryl2@va.gov,Female,135.147.68.149,10/20/2019,58,1166.14 +760,Reinhold,Lepoidevin,rlepoidevinl3@baidu.com,Male,31.102.77.143,11/13/2019,22,2344.24 +761,Quent,Screen,qscreenl4@opera.com,Male,12.112.10.35,2/10/2019,53,4842.57 +762,Samuel,Lindberg,slindbergl5@github.io,Male,168.90.162.31,12/12/2018,89,1308.19 +763,Haleigh,Raubenheimer,hraubenheimerl6@quantcast.com,Female,105.212.55.253,1/14/2019,37,3535.98 +764,Shela,Croutear,scroutearl7@istockphoto.com,Female,91.117.195.180,2/8/2019,38,3265.27 +765,Kellyann,Capron,kcapronl8@example.com,Female,124.152.40.23,5/29/2019,50,4056.87 +766,Garey,enzley,genzleyl9@latimes.com,Male,90.152.83.190,9/28/2019,97,1906.66 +767,Mick,Schroter,mschroterla@google.fr,Male,7.60.95.15,5/31/2019,3,1395.4 +768,Alfy,Amdohr,aamdohrlb@google.com,Male,224.77.126.110,3/1/2019,50,4548.48 +769,Mirabelle,Staresmeare,mstaresmearelc@netvibes.com,Female,11.204.171.148,1/11/2019,55,4544.46 +770,Opal,Fincken,ofinckenld@paypal.com,Female,163.158.79.29,9/30/2019,16,4021.93 +771,Donielle,Philliphs,dphilliphsle@g.co,Female,141.55.105.178,7/20/2019,49,1131.35 +772,Stephie,Whitaker,swhitakerlf@skyrock.com,Female,225.117.77.187,3/27/2019,10,4871.35 +773,Elisa,Reddell,ereddelllg@cargocollective.com,Female,74.40.71.217,9/11/2019,9,4241.01 +774,Lars,Bunner,lbunnerlh@si.edu,Male,169.187.187.173,3/18/2019,30,4554.14 +775,Travers,Prinnett,tprinnettli@artisteer.com,Male,105.11.246.207,5/19/2019,60,1589.02 +776,Laurens,Held,lheldlj@delicious.com,Male,124.146.44.210,8/19/2019,96,2202.45 +777,Francesco,Florence,fflorencelk@army.mil,Male,220.136.205.22,7/26/2019,20,3108.6 +778,Lorenzo,Sandhill,lsandhillll@cbc.ca,Male,59.175.249.79,9/30/2019,75,1913.25 +779,Eddy,Duchart,educhartlm@blinklist.com,Male,45.9.255.250,9/3/2019,23,2272.21 +780,Melisse,Corpe,mcorpeln@biblegateway.com,Female,177.26.210.63,10/20/2019,52,4203.4 +781,Clementia,Raggett,craggettlo@wikispaces.com,Female,66.66.204.21,10/17/2019,35,3945.21 +782,Constantine,Spaducci,cspaduccilp@upenn.edu,Male,63.181.82.150,8/21/2019,46,2543.36 +783,Durant,Andreix,dandreixlq@desdev.cn,Male,196.76.252.7,9/20/2019,14,4613.73 +784,Dilan,Jesty,djestylr@nature.com,Male,121.131.244.90,3/19/2019,89,4665.71 +785,Geralda,Zotto,gzottols@samsung.com,Female,203.26.209.205,4/15/2019,76,2964.31 +786,Greg,Goodings,ggoodingslt@instagram.com,Male,64.38.244.127,9/12/2019,92,4711.1 +787,Bailey,Stuchberry,bstuchberrylu@indiatimes.com,Male,26.71.81.206,12/16/2018,30,1848.55 +788,Mata,Wilkowski,mwilkowskilv@google.co.uk,Male,155.242.58.56,11/26/2019,85,4335.11 +789,Hamnet,Phillpotts,hphillpottslw@paypal.com,Male,7.182.159.232,6/16/2019,71,1440.95 +790,Dimitry,Capeloff,dcapelofflx@pinterest.com,Male,109.227.224.121,7/10/2019,80,3282.33 +791,Rafaello,Coggles,rcogglesly@prweb.com,Male,111.224.235.85,12/10/2018,16,4340.53 +792,Judith,Witul,jwitullz@issuu.com,Female,175.239.78.176,3/2/2019,1,4375.79 +793,Addy,Symson,asymsonm0@xing.com,Female,21.208.246.221,2/11/2019,82,1009.31 +794,Joey,Troak,jtroakm1@hhs.gov,Male,134.87.130.194,1/28/2019,60,1454.05 +795,Goldi,Currell,gcurrellm2@xinhuanet.com,Female,93.106.48.19,10/16/2019,65,1228.04 +796,Joaquin,Teodori,jteodorim3@github.com,Male,240.116.96.102,7/31/2019,71,1091.62 +797,Rollo,Embling,remblingm4@un.org,Male,56.201.58.245,3/29/2019,20,2170.46 +798,Mina,Blondel,mblondelm5@weibo.com,Female,98.87.116.35,7/18/2019,58,1320.41 +799,Meridel,Aries,mariesm6@technorati.com,Female,142.95.106.58,11/15/2019,87,2705.6 +800,Bret,Perrelle,bperrellem7@360.cn,Male,118.67.219.42,6/16/2019,87,3500.22 +801,Augustine,Hamments,ahammentsm8@oracle.com,Male,55.61.38.103,3/26/2019,8,1526.07 +802,Billie,Roo,broom9@tuttocitta.it,Female,219.152.107.102,3/14/2019,97,3539.6 +803,Susann,Pargiter,spargiterma@umich.edu,Female,147.205.25.119,6/27/2019,22,1160.81 +804,Glennis,Penella,gpenellamb@posterous.com,Female,192.52.234.179,11/2/2019,36,2548.63 +805,Mozelle,Densumbe,mdensumbemc@phpbb.com,Female,72.69.188.204,7/10/2019,51,4208.3 +806,Bernarr,Congrave,bcongravemd@gizmodo.com,Male,54.147.238.56,6/24/2019,10,3573.77 +807,Humfrid,Glauber,hglauberme@adobe.com,Male,88.115.210.97,2/26/2019,18,1504.77 +808,Suzie,Awmack,sawmackmf@com.com,Female,25.246.10.228,9/22/2019,58,1734.63 +809,Tanitansy,McDill,tmcdillmg@apache.org,Female,176.212.121.232,9/10/2019,91,3442.09 +810,Astrid,O'Henery,aohenerymh@cnbc.com,Female,114.120.10.56,5/9/2019,8,3084.41 +811,Pepita,Estrella,pestrellami@1688.com,Female,32.233.56.52,11/12/2019,14,4239.8 +812,Cornie,Jennaway,cjennawaymj@amazon.de,Male,193.210.211.129,6/10/2019,19,3412.2 +813,Barbette,Rudgard,brudgardmk@myspace.com,Female,176.253.137.53,2/4/2019,1,1136.15 +814,Timofei,Donner,tdonnerml@ed.gov,Male,123.83.191.246,3/26/2019,1,1133.51 +815,Vasily,Jeary,vjearymm@nationalgeographic.com,Male,98.99.97.55,5/7/2019,92,1187.51 +816,Jamey,Windsor,jwindsormn@nih.gov,Male,196.125.95.56,6/29/2019,71,3115.9 +817,Evangelina,Gorrie,egorriemo@theglobeandmail.com,Female,35.130.99.82,1/14/2019,79,2252.03 +818,Odie,Titchmarsh,otitchmarshmp@sina.com.cn,Male,172.30.187.143,6/12/2019,63,3327.2 +819,Hestia,Fresson,hfressonmq@hp.com,Female,195.31.239.116,7/16/2019,39,3541.73 +820,Mortimer,Bestwerthick,mbestwerthickmr@microsoft.com,Male,217.124.4.132,10/24/2019,19,4855.38 +821,Chaunce,Hechlin,chechlinms@goo.ne.jp,Male,197.140.52.246,7/29/2019,1,2219.75 +822,Odella,Casson,ocassonmt@sciencedaily.com,Female,40.211.128.59,3/16/2019,93,3085.53 +823,Shellysheldon,Pallent,spallentmu@youtu.be,Male,153.196.220.186,2/19/2019,19,2695.0 +824,Emelyne,Childes,echildesmv@livejournal.com,Female,126.181.2.21,11/6/2019,13,1095.75 +825,Fred,Calf,fcalfmw@chicagotribune.com,Female,240.193.197.180,11/17/2019,79,3914.36 +826,Dag,Mulliss,dmullissmx@4shared.com,Male,238.137.20.149,8/6/2019,4,3539.27 +827,Georgeanna,Pitcock,gpitcockmy@comsenz.com,Female,102.167.151.225,10/12/2019,84,4585.02 +828,Sunny,Panther,spanthermz@unicef.org,Male,151.172.118.190,1/12/2019,91,4343.08 +829,Belita,Alderson,baldersonn0@blogtalkradio.com,Female,137.76.226.221,1/10/2019,42,3569.01 +830,Ame,Forte,aforten1@sourceforge.net,Female,147.157.177.133,1/8/2019,21,1365.56 +831,Timmie,Rodden,troddenn2@businessweek.com,Male,130.254.151.248,3/26/2019,96,1881.36 +832,Ole,Schafer,oschafern3@about.com,Male,127.222.178.16,3/17/2019,17,2401.6 +833,Patty,Cooling,pcoolingn4@seesaa.net,Female,61.215.62.193,2/11/2019,48,2474.66 +834,Collin,Stute,cstuten5@goo.ne.jp,Male,130.45.80.94,9/10/2019,4,3847.7 +835,Yorgo,Swancott,yswancottn6@intel.com,Male,219.62.66.145,2/25/2019,65,2423.66 +836,Ron,Routley,rroutleyn7@spotify.com,Male,56.197.234.81,8/23/2019,33,2148.92 +837,Stefania,McSkin,smcskinn8@dot.gov,Female,98.31.14.146,3/16/2019,62,1990.6 +838,Salem,Lergan,slergann9@usnews.com,Male,15.104.246.221,6/13/2019,38,2449.21 +839,Dunstan,Kenzie,dkenziena@networksolutions.com,Male,87.134.108.52,11/9/2019,44,4224.03 +840,Hunt,Ledamun,hledamunnb@yahoo.com,Male,176.159.246.215,3/10/2019,86,3822.13 +841,Farrand,Callam,fcallamnc@paypal.com,Female,226.107.7.0,8/27/2019,74,2378.51 +842,Nada,Catlin,ncatlinnd@furl.net,Female,47.100.217.78,9/6/2019,80,4344.19 +843,Carlita,Glavis,cglavisne@thetimes.co.uk,Female,51.186.12.78,12/12/2018,10,1226.08 +844,Lianna,McColm,lmccolmnf@smh.com.au,Female,11.59.43.151,12/24/2018,75,2920.03 +845,Darill,Klempke,dklempkeng@bloomberg.com,Male,130.161.53.81,10/30/2019,26,1470.72 +846,Laughton,Whithalgh,lwhithalghnh@booking.com,Male,245.52.162.163,5/13/2019,95,3958.01 +847,Cammie,Izhakov,cizhakovni@admin.ch,Female,124.164.33.27,4/7/2019,43,2040.2 +848,Marline,Duddell,mduddellnj@opensource.org,Female,170.97.255.200,6/14/2019,35,2449.64 +849,Hillier,Caulder,hcauldernk@npr.org,Male,83.220.85.148,8/30/2019,1,3069.76 +850,Coral,Raffles,crafflesnl@friendfeed.com,Female,149.92.2.58,1/20/2019,13,1301.57 +851,Barb,Dudny,bdudnynm@fc2.com,Female,243.249.246.96,2/19/2019,2,4053.62 +852,Arch,Bente,abentenn@mapy.cz,Male,229.210.219.135,9/9/2019,41,4556.35 +853,Alix,Sheriff,asheriffno@jigsy.com,Female,203.28.108.229,1/30/2019,70,2074.89 +854,Vaughn,Schwaiger,vschwaigernp@webmd.com,Male,112.58.20.107,5/25/2019,5,2348.46 +855,Stearn,Linggood,slinggoodnq@multiply.com,Male,247.71.219.146,11/23/2019,5,3348.25 +856,Doralin,Kleinschmidt,dkleinschmidtnr@ca.gov,Female,30.114.11.63,9/21/2019,29,3475.53 +857,Ali,Treweke,atrewekens@xrea.com,Female,181.217.116.253,1/19/2019,50,4184.66 +858,Brandon,Ogger,boggernt@example.com,Male,19.9.219.173,12/21/2018,53,3270.85 +859,Garth,Sterre,gsterrenu@sina.com.cn,Male,7.170.103.142,12/30/2018,60,4285.48 +860,Elberta,Stooke,estookenv@goo.gl,Female,104.12.213.185,4/7/2019,60,1570.75 +861,Winfield,Peacock,wpeacocknw@liveinternet.ru,Male,214.134.25.83,2/21/2019,76,4428.25 +862,Ernest,Allabarton,eallabartonnx@home.pl,Male,148.170.100.93,4/25/2019,54,2410.98 +863,Florette,Pendle,fpendleny@google.co.uk,Female,163.75.98.87,3/3/2019,25,1877.39 +864,Enrica,Smogur,esmogurnz@jiathis.com,Female,212.86.14.17,10/30/2019,90,1736.18 +865,Selle,Meece,smeeceo0@va.gov,Female,216.204.181.172,12/31/2018,9,4254.26 +866,Leighton,Behninck,lbehnincko1@ted.com,Male,128.137.145.34,7/28/2019,8,4817.49 +867,Dallis,Kildahl,dkildahlo2@ucsd.edu,Male,57.50.158.153,11/29/2019,80,3940.06 +868,Carr,McKeachie,cmckeachieo3@cbsnews.com,Male,155.169.255.5,10/25/2019,92,1248.52 +869,Gwendolin,Twinborough,gtwinborougho4@engadget.com,Female,126.69.215.135,10/31/2019,60,1790.54 +870,Katha,Mains,kmainso5@wired.com,Female,108.80.188.101,9/5/2019,90,1953.27 +871,Anabella,Hawkridge,ahawkridgeo6@elegantthemes.com,Female,194.91.70.106,11/7/2019,33,1067.92 +872,Carney,Moxon,cmoxono7@about.me,Male,243.35.248.83,5/25/2019,46,3541.93 +873,Cynthy,Minette,cminetteo8@unesco.org,Female,198.115.128.127,11/13/2019,17,1202.6 +874,Humfrey,Doogue,hdoogueo9@businesswire.com,Male,118.100.123.208,9/24/2019,21,1883.88 +875,Rosabella,Frowen,rfrowenoa@who.int,Female,168.21.241.150,3/26/2019,12,3747.05 +876,Inger,Benoiton,ibenoitonob@bing.com,Female,62.18.91.144,2/5/2019,55,3668.36 +877,Aldus,McHardy,amchardyoc@google.com,Male,217.43.238.237,2/7/2019,25,3733.76 +878,Thea,Klemke,tklemkeod@aboutads.info,Female,13.193.63.194,9/1/2019,15,2199.75 +879,Nathaniel,Alesio,nalesiooe@prweb.com,Male,45.77.38.94,8/21/2019,88,1398.05 +880,Jo-ann,Thring,jthringof@plala.or.jp,Female,67.45.206.82,3/28/2019,23,1119.69 +881,Betteann,Andreone,bandreoneog@google.it,Female,28.46.236.211,9/21/2019,68,2637.19 +882,Leland,Boulding,lbouldingoh@booking.com,Male,223.0.133.33,6/26/2019,95,1645.04 +883,Rosalia,Sieve,rsieveoi@opera.com,Female,146.244.116.76,11/14/2019,20,3684.84 +884,Pietra,Lillyman,plillymanoj@sphinn.com,Female,241.84.132.180,1/28/2019,100,4262.03 +885,Cosme,Guest,cguestok@chronoengine.com,Male,200.190.189.24,4/16/2019,70,2178.29 +886,Wallie,Telega,wtelegaol@ebay.com,Male,121.243.189.159,4/30/2019,52,1182.3 +887,Lishe,Skillett,lskillettom@umn.edu,Female,195.58.225.2,3/5/2019,71,2012.1 +888,Arleta,Manley,amanleyon@linkedin.com,Female,51.84.250.183,10/15/2019,15,4912.75 +889,Ravi,Willder,rwillderoo@clickbank.net,Male,172.59.196.252,11/3/2019,61,1209.86 +890,Averell,Towner,atownerop@twitpic.com,Male,39.252.161.23,5/12/2019,64,4531.62 +891,Patrice,Dedman,pdedmanoq@marriott.com,Male,210.154.94.25,6/13/2019,74,4735.98 +892,Shem,Girtin,sgirtinor@is.gd,Male,104.118.74.161,11/10/2019,100,4267.43 +893,Francyne,Bransby,fbransbyos@g.co,Female,44.30.38.123,2/4/2019,46,4181.62 +894,Christye,Farbrace,cfarbraceot@hibu.com,Female,112.150.190.191,2/16/2019,23,2095.36 +895,Nadean,Given,ngivenou@spiegel.de,Female,151.241.243.171,4/25/2019,81,2443.82 +896,Cesya,Clutheram,cclutheramov@smh.com.au,Female,165.200.216.167,7/4/2019,31,3937.84 +897,Bax,Goodwins,bgoodwinsow@nhs.uk,Male,11.52.15.206,4/9/2019,91,2252.61 +898,Lewiss,Lamblot,llamblotox@hubpages.com,Male,47.131.77.115,8/30/2019,24,2400.36 +899,Red,Wick,rwickoy@photobucket.com,Male,83.184.219.168,10/21/2019,15,4178.01 +900,Salvatore,Pimblett,spimblettoz@cmu.edu,Male,167.151.230.214,5/15/2019,42,1341.9 +901,Hughie,Bryceson,hbrycesonp0@princeton.edu,Male,196.234.12.37,6/21/2019,62,1336.58 +902,Clayson,Hankinson,chankinsonp1@over-blog.com,Male,23.197.178.40,8/12/2019,99,1615.05 +903,Lilas,Liccardo,lliccardop2@wisc.edu,Female,122.30.29.218,11/8/2019,18,2646.47 +904,Orville,Durrant,odurrantp3@clickbank.net,Male,72.40.168.148,8/12/2019,37,1473.73 +905,Orrin,Skelly,oskellyp4@a8.net,Male,105.220.135.4,5/6/2019,50,1525.97 +906,Tallou,Sandyford,tsandyfordp5@homestead.com,Female,227.225.220.181,2/6/2019,58,4786.43 +907,Quincy,Roseman,qrosemanp6@biglobe.ne.jp,Male,54.163.190.213,7/1/2019,24,4037.23 +908,Tabbie,Kiraly,tkiralyp7@newsvine.com,Male,224.190.131.109,3/13/2019,100,1323.77 +909,Sandy,Matskevich,smatskevichp8@simplemachines.org,Female,2.231.87.52,12/29/2018,82,3517.0 +910,Duane,Dye,ddyep9@nasa.gov,Male,104.68.110.228,10/11/2019,72,3764.03 +911,Vassily,McNeill,vmcneillpa@eepurl.com,Male,224.20.3.98,5/2/2019,93,2130.67 +912,Donalt,Astlet,dastletpb@chron.com,Male,114.210.201.171,5/7/2019,75,2025.04 +913,Nickey,Stobie,nstobiepc@icio.us,Male,185.166.110.244,4/16/2019,71,1045.07 +914,Alejandra,Evenett,aevenettpd@spotify.com,Female,53.71.229.172,3/31/2019,68,3272.6 +915,Malia,Turpey,mturpeype@slashdot.org,Female,100.204.158.195,7/24/2019,23,1887.0 +916,Sancho,Coy,scoypf@unicef.org,Male,172.2.26.180,7/3/2019,57,3139.02 +917,Gabey,Skoyles,gskoylespg@epa.gov,Female,194.148.9.101,3/13/2019,84,2292.4 +918,Bertrando,Ivankin,bivankinph@fda.gov,Male,118.157.82.229,9/22/2019,3,1287.51 +919,Tannie,MacCosty,tmaccostypi@digg.com,Male,72.202.202.95,12/24/2018,82,2588.07 +920,Ranee,Bessent,rbessentpj@imgur.com,Female,127.24.169.67,11/10/2019,54,3444.15 +921,Tiffanie,Trawin,ttrawinpk@marketwatch.com,Female,17.85.226.126,5/24/2019,65,2725.46 +922,Almeria,Gillan,agillanpl@geocities.com,Female,122.181.145.74,11/21/2019,9,4518.15 +923,Myron,Cornuau,mcornuaupm@fema.gov,Male,119.235.159.166,8/23/2019,71,2151.88 +924,Julie,Garmston,jgarmstonpn@istockphoto.com,Female,239.238.200.150,1/14/2019,64,2838.43 +925,Piggy,Gobel,pgobelpo@fastcompany.com,Male,118.158.61.149,2/6/2019,34,3108.47 +926,Gib,Featherstone,gfeatherstonepp@infoseek.co.jp,Male,90.82.112.24,7/12/2019,72,1446.28 +927,Ezri,Roome,eroomepq@bandcamp.com,Male,162.179.9.53,11/8/2019,89,4420.45 +928,Mattias,Bilbie,mbilbiepr@jugem.jp,Male,26.98.219.102,6/29/2019,53,3055.7 +929,Tremain,Puleston,tpulestonps@newsvine.com,Male,57.241.217.97,2/19/2019,74,4113.34 +930,Penrod,Human,phumanpt@amazon.co.jp,Male,191.23.222.227,8/12/2019,14,3914.95 +931,Helyn,Ladell,hladellpu@a8.net,Female,20.100.134.221,4/17/2019,94,2293.8 +932,Enid,Rough,eroughpv@imageshack.us,Female,107.222.42.7,6/17/2019,21,1914.06 +933,Eloise,Rumbold,erumboldpw@meetup.com,Female,43.79.13.253,12/16/2018,59,4639.52 +934,Sol,Merricks,smerrickspx@ow.ly,Male,123.39.195.179,11/1/2019,57,2899.49 +935,Mahmud,Keeney,mkeeneypy@wikispaces.com,Male,72.102.171.49,3/11/2019,6,4225.54 +936,Asia,Bartlosz,abartloszpz@mtv.com,Female,243.106.58.70,12/21/2018,69,1884.34 +937,Christian,Stirman,cstirmanq0@discuz.net,Female,107.80.178.46,8/29/2019,55,2956.9 +938,Alfredo,Adnams,aadnamsq1@washington.edu,Male,37.204.15.227,12/6/2018,15,2349.12 +939,Rudy,Diggins,rdigginsq2@nsw.gov.au,Male,136.105.142.55,10/22/2019,56,4720.66 +940,Valaria,Paulus,vpaulusq3@etsy.com,Female,109.100.3.110,1/2/2019,26,1610.79 +941,Conny,Roels,croelsq4@mozilla.com,Female,208.213.210.29,1/31/2019,54,4096.32 +942,Bucky,Kennan,bkennanq5@pinterest.com,Male,172.225.189.229,8/19/2019,87,4628.59 +943,Iago,Samwyse,isamwyseq6@github.io,Male,89.18.109.205,11/10/2019,60,4746.45 +944,Pietrek,Gori,pgoriq7@reverbnation.com,Male,92.121.178.154,11/5/2019,33,1692.9 +945,Tabina,Kears,tkearsq8@theglobeandmail.com,Female,144.45.170.150,10/3/2019,52,3611.17 +946,Wendye,Sollis,wsollisq9@walmart.com,Female,238.248.64.91,5/1/2019,5,3395.62 +947,Rafferty,Waycot,rwaycotqa@yellowbook.com,Male,56.12.230.243,10/22/2019,65,3819.8 +948,Bendix,Heamus,bheamusqb@adobe.com,Male,249.250.105.13,1/13/2019,1,3871.34 +949,Elfrieda,Gierardi,egierardiqc@uiuc.edu,Female,70.40.147.33,5/15/2019,33,3013.33 +950,Malachi,Sweet,msweetqd@soup.io,Male,45.89.78.169,12/12/2018,80,3668.82 +951,Lanae,Pollendine,lpollendineqe@nasa.gov,Female,95.61.177.183,2/13/2019,1,4889.44 +952,Ryley,Lawry,rlawryqf@scientificamerican.com,Male,125.229.131.211,1/14/2019,2,3286.34 +953,Terri-jo,Jamblin,tjamblinqg@epa.gov,Female,188.157.97.186,6/5/2019,47,2943.87 +954,Leland,Hildred,lhildredqh@scribd.com,Male,225.216.250.143,6/17/2019,56,4864.96 +955,Gabe,Olyff,golyffqi@nba.com,Male,132.213.9.245,4/23/2019,98,1702.76 +956,Madelena,Astling,mastlingqj@samsung.com,Female,30.58.29.118,12/18/2018,84,4673.11 +957,Reinaldo,Kitchingman,rkitchingmanqk@csmonitor.com,Male,188.111.118.234,5/23/2019,75,4450.61 +958,Padgett,Spacey,pspaceyql@google.de,Male,36.237.235.122,11/27/2019,56,1279.87 +959,Rachel,Chezelle,rchezelleqm@domainmarket.com,Female,96.79.189.100,11/24/2019,91,3136.13 +960,Pollyanna,Eggerton,peggertonqn@nsw.gov.au,Female,18.201.58.237,12/19/2018,20,3493.5 +961,Marris,Wincott,mwincottqo@bandcamp.com,Female,184.31.11.215,6/12/2019,8,1515.01 +962,Shae,Mair,smairqp@friendfeed.com,Male,62.3.75.126,5/26/2019,17,1886.62 +963,Rik,Citrine,rcitrineqq@ameblo.jp,Male,185.79.147.211,7/2/2019,34,4809.78 +964,Clare,Bohey,cboheyqr@wunderground.com,Female,107.176.103.42,5/11/2019,88,4309.81 +965,Hayes,Brushfield,hbrushfieldqs@i2i.jp,Male,2.5.51.42,11/26/2019,76,1551.99 +966,Misty,Domico,mdomicoqt@google.pl,Female,39.47.212.202,12/6/2018,70,4670.57 +967,Arthur,Elstub,aelstubqu@independent.co.uk,Male,176.248.255.191,12/30/2018,46,2705.52 +968,Berkeley,Hapgood,bhapgoodqv@technorati.com,Male,178.208.39.27,10/14/2019,22,3380.97 +969,Brose,Kynton,bkyntonqw@arstechnica.com,Male,46.20.210.218,3/5/2019,56,4943.64 +970,Tarah,Deguara,tdeguaraqx@netvibes.com,Female,218.157.37.87,10/15/2019,52,4735.44 +971,Lorie,Tooting,ltootingqy@e-recht24.de,Female,180.29.70.96,5/13/2019,2,3053.29 +972,Consuela,Lyndon,clyndonqz@nature.com,Female,33.99.22.111,10/26/2019,16,1782.96 +973,Heloise,Loges,hlogesr0@ebay.co.uk,Female,65.91.147.32,8/6/2019,91,3905.33 +974,Lamond,Hamnet,lhamnetr1@tripod.com,Male,59.5.218.194,3/21/2019,78,3783.64 +975,Matilda,Clemencet,mclemencetr2@livejournal.com,Female,50.223.87.130,10/4/2019,23,2543.68 +976,Bayard,Roskruge,broskruger3@sitemeter.com,Male,69.240.99.87,7/3/2019,80,1587.29 +977,Benn,Jirak,bjirakr4@delicious.com,Male,128.35.209.194,12/2/2018,44,3277.87 +978,Nahum,Attle,nattler5@tiny.cc,Male,112.43.114.140,6/8/2019,7,2273.81 +979,Evangeline,Ribey,eribeyr6@google.fr,Female,81.105.199.64,3/29/2019,67,4510.15 +980,Ryann,Ellul,rellulr7@ning.com,Female,240.217.190.216,12/13/2018,84,1668.81 +981,Ermina,Venn,evennr8@de.vu,Female,133.154.240.217,2/13/2019,97,1524.47 +982,Toby,Durward,tdurwardr9@state.tx.us,Male,121.122.162.100,6/18/2019,93,2462.12 +983,Frederic,Scraney,fscraneyra@gnu.org,Male,169.185.152.85,9/1/2019,5,4899.03 +984,Marty,Phebey,mphebeyrb@tripadvisor.com,Male,168.107.107.230,12/6/2018,84,4793.66 +985,Harris,Lockney,hlockneyrc@nifty.com,Male,93.129.49.110,8/4/2019,49,1798.63 +986,Eugen,Leverton,elevertonrd@instagram.com,Male,159.232.54.24,9/21/2019,60,3305.1 +987,Gabie,Beardwood,gbeardwoodre@theatlantic.com,Male,20.18.125.82,1/24/2019,5,1946.11 +988,Myrwyn,Pesterfield,mpesterfieldrf@scientificamerican.com,Male,145.133.177.91,8/13/2019,25,3808.27 +989,Mercy,Chadd,mchaddrg@51.la,Female,185.164.11.233,6/3/2019,40,4001.54 +990,Cornelle,Conford,cconfordrh@behance.net,Female,21.225.190.101,1/23/2019,37,3044.81 +991,Maynord,Till,mtillri@youtube.com,Male,152.132.239.240,7/13/2019,100,1128.62 +992,Evelin,Dmitrichenko,edmitrichenkorj@weibo.com,Male,209.57.214.249,7/17/2019,97,1964.24 +993,Quincy,Rupel,qrupelrk@github.io,Male,64.185.162.129,7/17/2019,98,3247.38 +994,Althea,Ternault,aternaultrl@hao123.com,Female,67.166.119.252,9/5/2019,71,1679.32 +995,Tracy,Usmar,tusmarrm@archive.org,Female,218.147.181.108,4/29/2019,13,4937.95 +996,Frank,Thebeaud,fthebeaudrn@phpbb.com,Male,80.246.35.156,3/21/2019,91,3229.53 +997,Kerk,Feathersby,kfeathersbyro@i2i.jp,Male,216.252.23.125,4/2/2019,38,2610.64 +998,Brigid,Worvell,bworvellrp@cnn.com,Female,48.50.178.158,5/19/2019,35,1974.9 +999,Ike,Van der Merwe,ivandermerwerq@craigslist.org,Male,103.61.116.181,8/14/2019,56,2115.14 +1000,Mark,Dallison,mdallisonrr@cdc.gov,Male,187.245.203.40,8/8/2019,73,1286.22 diff --git a/scripts/MOCK_DATA_out.csv b/scripts/MOCK_DATA_out.csv new file mode 100644 index 0000000..613a3d3 --- /dev/null +++ b/scripts/MOCK_DATA_out.csv @@ -0,0 +1,1001 @@ +id,first_name,last_name,email,gender,ip_address,date,parts,unit cost +1,Lurette,Rounsefull,lrounsefull0@cbsnews.com,Female,208.52.245.134,4/11/2019,1,1425.64 +2,Peder,Heineking,pheineking1@mac.com,Male,216.60.184.211,5/15/2019,79,2666.57 +3,Haydon,Birdsall,hbirdsall2@spotify.com,Male,161.74.94.92,10/18/2019,27,2377.64 +4,Barbe,Mouse,bmouse3@elegantthemes.com,Female,97.202.107.43,5/16/2019,20,3375.08 +5,Sherwin,Wealthall,swealthall4@whitehouse.gov,Male,155.14.42.127,3/5/2019,77,4147.29 +6,Ase,Pringle,apringle5@sfgate.com,Male,147.34.186.244,10/19/2019,33,4551.61 +7,Sibylla,Weiss,sweiss6@icq.com,Female,196.247.130.201,3/7/2019,21,2154.9 +8,Richy,Dougal,rdougal7@yelp.com,Male,91.176.172.223,12/27/2018,97,3403.75 +9,Kelsey,Ludlamme,kludlamme8@cyberchimps.com,Male,121.112.184.219,5/2/2019,81,4930.75 +10,Fae,Driffe,fdriffe9@friendfeed.com,Female,219.51.51.253,4/7/2019,57,3100.78 +11,Dannye,Sleit,dsleita@independent.co.uk,Female,160.208.93.210,10/4/2019,88,4401.37 +12,Kessia,Gilkes,kgilkesb@w3.org,Female,30.178.57.187,8/26/2019,82,2369.86 +13,Rickie,Persich,rpersichc@mapquest.com,Male,50.235.20.153,9/13/2019,94,4557.41 +14,Margaretta,Shearn,mshearnd@buzzfeed.com,Female,172.102.242.250,3/14/2019,72,2948.22 +15,Malcolm,Winnard,mwinnarde@yale.edu,Male,185.241.158.149,5/15/2019,82,4723.48 +16,Lazarus,Summerlie,lsummerlief@comsenz.com,Male,111.172.107.99,11/8/2019,89,2845.05 +17,Bord,Cato,bcatog@edublogs.org,Male,177.53.70.102,4/2/2019,32,4933.24 +18,Weber,Guslon,wguslonh@go.com,Male,115.2.137.252,12/10/2018,94,4348.69 +19,Stearne,MacPadene,smacpadenei@pbs.org,Male,35.83.181.137,8/4/2019,82,4950.67 +20,Bekki,Remirez,bremirezj@arstechnica.com,Female,12.111.119.238,2/17/2019,62,1510.53 +21,Desiri,Gaskins,dgaskinsk@prlog.org,Female,43.30.140.105,9/8/2019,64,4641.51 +22,Mata,Beaten,mbeatenl@constantcontact.com,Male,13.90.195.102,4/6/2019,84,1942.72 +23,Mattias,Bullas,mbullasm@fastcompany.com,Male,37.242.45.155,7/21/2019,95,3321.2 +24,Sloan,Graveson,sgravesonn@mozilla.com,Male,124.94.155.193,9/28/2019,7,1786.92 +25,Isak,Juste,ijusteo@google.ru,Male,249.233.28.164,8/18/2019,34,1682.19 +26,Teri,Thomann,tthomannp@wp.com,Female,168.237.145.237,11/16/2019,18,4480.64 +27,Rhoda,Gotcher,rgotcherq@businessinsider.com,Female,23.141.180.40,4/1/2019,19,4514.47 +28,Helen-elizabeth,McEniry,hmceniryr@oakley.com,Female,43.143.23.204,12/14/2018,40,4146.98 +29,Aguie,Brecknall,abrecknalls@nifty.com,Male,69.49.176.116,1/19/2019,96,4720.87 +30,Wildon,Keenlyside,wkeenlysidet@blogtalkradio.com,Male,245.109.45.71,3/26/2019,22,1835.57 +31,Ynez,Lots,ylotsu@abc.net.au,Female,172.185.2.14,7/17/2019,68,4872.13 +32,Norman,Worgen,nworgenv@constantcontact.com,Male,143.221.2.185,3/17/2019,29,4768.51 +33,Ker,Bown,kbownw@bandcamp.com,Male,30.5.53.61,6/14/2019,22,3091.25 +34,Ivy,Nibloe,inibloex@noaa.gov,Female,121.242.246.184,7/31/2019,15,4048.07 +35,Coop,Waiting,cwaitingy@prlog.org,Male,215.155.212.35,1/31/2019,59,1388.34 +36,Philipa,Bigglestone,pbigglestonez@networkadvertising.org,Female,235.113.203.193,1/11/2019,49,2571.05 +37,Konstantine,Reavell,kreavell10@pcworld.com,Male,212.115.157.70,1/15/2019,32,1521.5 +38,Neddie,Peckham,npeckham11@shareasale.com,Male,165.199.0.54,11/10/2019,4,4159.67 +39,Veronique,Crocetti,vcrocetti12@bravesites.com,Female,155.94.241.75,11/27/2019,70,1682.83 +40,Stanford,Folk,sfolk13@walmart.com,Male,115.78.90.21,8/20/2019,21,1049.63 +41,Tamera,Bacchus,tbacchus14@techcrunch.com,Female,125.75.125.6,2/3/2019,44,3804.48 +42,Andromache,Hakonsson,ahakonsson15@ft.com,Female,216.82.36.186,8/3/2019,38,3643.39 +43,Elnora,Amos,eamos16@domainmarket.com,Female,233.33.105.19,11/12/2019,97,1234.57 +44,Andrus,Hegge,ahegge17@arstechnica.com,Male,48.49.214.246,9/21/2019,79,4728.49 +45,Grady,Rodell,grodell18@ox.ac.uk,Male,69.64.12.243,4/22/2019,64,3514.69 +46,Maryann,Shaddick,mshaddick19@boston.com,Female,145.192.46.176,8/7/2019,43,1944.22 +47,Gaelan,Kirtley,gkirtley1a@topsy.com,Male,145.162.10.133,9/14/2019,39,2598.76 +48,Denver,Kennicott,dkennicott1b@amazon.com,Male,179.116.133.53,12/18/2018,10,2243.1 +49,Bordy,Saw,bsaw1c@cmu.edu,Male,6.22.237.36,1/27/2019,80,2196.95 +50,Gwenette,Iston,giston1d@multiply.com,Female,211.116.16.113,3/29/2019,34,2230.26 +51,Hedvig,Simmers,hsimmers1e@uol.com.br,Female,155.181.252.255,8/23/2019,7,3711.71 +52,Jannel,Sarre,jsarre1f@tuttocitta.it,Female,127.187.194.109,6/4/2019,82,2641.84 +53,Rusty,Saffill,rsaffill1g@mozilla.com,Male,152.175.79.114,3/24/2019,63,4482.27 +54,Shelden,Brandin,sbrandin1h@jugem.jp,Male,218.156.254.18,9/29/2019,12,1487.3 +55,Rusty,Dumbare,rdumbare1i@purevolume.com,Male,49.252.90.82,3/2/2019,26,4880.92 +56,Agace,Davidovitz,adavidovitz1j@mtv.com,Female,187.52.194.143,4/21/2019,59,4803.16 +57,Ross,McGarva,rmcgarva1k@upenn.edu,Male,41.191.56.78,8/23/2019,97,4860.07 +58,Kayne,Maruszewski,kmaruszewski1l@stanford.edu,Male,41.228.104.199,7/18/2019,23,1358.8 +59,Stavros,Comar,scomar1m@google.ru,Male,5.91.47.215,6/20/2019,66,1423.4 +60,Ruperto,Proudlock,rproudlock1n@hostgator.com,Male,105.156.116.198,1/20/2019,28,4631.21 +61,Milka,Marvel,mmarvel1o@devhub.com,Female,9.251.162.16,5/26/2019,80,3446.13 +62,Zared,Pallesen,zpallesen1p@ted.com,Male,246.159.163.241,6/13/2019,25,2949.72 +63,Sharona,Muscat,smuscat1q@youtube.com,Female,192.207.68.239,1/17/2019,53,4522.67 +64,Annabella,Persitt,apersitt1r@china.com.cn,Female,5.217.19.64,7/26/2019,52,2113.55 +65,Tawsha,Constantine,tconstantine1s@4shared.com,Female,6.89.103.116,6/15/2019,38,2727.92 +66,Leonard,Pavlasek,lpavlasek1t@theglobeandmail.com,Male,42.64.175.217,2/16/2019,85,2694.45 +67,Kalvin,Caudle,kcaudle1u@baidu.com,Male,193.11.181.80,4/23/2019,18,2549.05 +68,Jessica,Cumbridge,jcumbridge1v@hugedomains.com,Female,238.81.101.205,12/18/2018,80,2877.37 +69,Iorgo,Hampshaw,ihampshaw1w@youtu.be,Male,35.99.25.88,4/15/2019,100,4485.79 +70,Sherlocke,Kerswell,skerswell1x@zdnet.com,Male,201.53.40.240,9/5/2019,6,4147.46 +71,Rikki,Blodg,rblodg1y@admin.ch,Male,233.254.145.162,9/20/2019,41,4950.16 +72,Leoine,MacInnes,lmacinnes1z@joomla.org,Female,76.138.109.238,7/23/2019,45,3870.58 +73,Leicester,O'Haire,lohaire20@nba.com,Male,51.179.242.230,8/7/2019,23,2243.91 +74,Bennett,Jankowski,bjankowski21@jugem.jp,Male,248.133.185.229,6/4/2019,67,2448.41 +75,Josias,Wardingley,jwardingley22@bigcartel.com,Male,128.111.46.189,8/22/2019,2,4954.97 +76,Farrand,Edon,fedon23@networkadvertising.org,Female,181.161.32.177,3/30/2019,95,3728.89 +77,Tirrell,Daugherty,tdaugherty24@miitbeian.gov.cn,Male,202.140.213.72,11/9/2019,36,3436.25 +78,Celeste,Odby,codby25@answers.com,Female,152.36.106.124,6/16/2019,12,1327.35 +79,Jory,Roomes,jroomes26@usa.gov,Male,124.197.56.246,7/2/2019,62,3910.3 +80,Saudra,Woodham,swoodham27@smh.com.au,Female,109.122.138.13,4/17/2019,22,3553.65 +81,Renaldo,Calow,rcalow28@cloudflare.com,Male,108.38.150.172,12/5/2018,98,3790.92 +82,Chrissie,Wynch,cwynch29@de.vu,Female,113.58.215.184,5/25/2019,54,3925.41 +83,Boris,Ilyas,bilyas2a@webeden.co.uk,Male,98.65.148.122,1/26/2019,4,2722.03 +84,Zach,McReynolds,zmcreynolds2b@about.com,Male,169.251.18.46,3/25/2019,33,2238.47 +85,Pip,Puttan,pputtan2c@multiply.com,Male,6.160.216.170,10/23/2019,20,1502.59 +86,Lenore,Shafto,lshafto2d@globo.com,Female,144.169.11.70,1/17/2019,5,2162.94 +87,Maggie,Dryden,mdryden2e@cpanel.net,Female,203.155.129.86,3/12/2019,76,3017.41 +88,Madeleine,Alflatt,malflatt2f@spotify.com,Female,38.43.105.230,6/3/2019,70,4950.07 +89,Jojo,Niblock,jniblock2g@usgs.gov,Female,241.182.83.206,6/20/2019,98,3224.06 +90,Chan,Lebbern,clebbern2h@about.me,Male,129.233.179.181,5/31/2019,14,3407.91 +91,Juanita,O'Neil,joneil2i@sina.com.cn,Female,196.212.243.128,4/21/2019,4,1238.45 +92,Albina,Nestoruk,anestoruk2j@rakuten.co.jp,Female,173.60.28.232,11/25/2019,2,3850.73 +93,Gerrard,Lowrance,glowrance2k@huffingtonpost.com,Male,65.158.65.49,5/30/2019,56,2495.36 +94,Enrique,Borrel,eborrel2l@slashdot.org,Male,234.74.144.119,11/11/2019,89,1230.11 +95,Sheppard,Millward,smillward2m@plala.or.jp,Male,30.207.143.30,9/13/2019,14,4656.55 +96,Karna,Zisneros,kzisneros2n@comcast.net,Female,207.85.89.67,4/30/2019,40,1087.58 +97,Mohandas,Abbitt,mabbitt2o@cocolog-nifty.com,Male,157.202.50.94,2/2/2019,18,4141.99 +98,Alena,McVee,amcvee2p@so-net.ne.jp,Female,35.120.251.203,9/28/2019,15,4863.32 +99,Lanita,Sommerlin,lsommerlin2q@mozilla.com,Female,63.103.18.73,2/17/2019,69,4424.01 +100,Celine,Huddlestone,chuddlestone2r@ask.com,Female,207.219.182.50,6/24/2019,92,4185.16 +101,Jan,Vorley,jvorley2s@bbc.co.uk,Male,24.122.66.16,10/7/2019,88,4856.43 +102,Gordon,Burness,gburness2t@wired.com,Male,251.54.167.76,7/28/2019,77,1249.9 +103,Doris,Dey,ddey2u@youtube.com,Female,105.167.122.156,5/18/2019,95,2541.59 +104,Colby,Ashurst,cashurst2v@wix.com,Male,93.195.66.138,9/14/2019,49,3987.84 +105,Phyllida,Brookson,pbrookson2w@apple.com,Female,15.169.21.114,4/8/2019,10,4565.43 +106,Jeramie,Crasswell,jcrasswell2x@posterous.com,Male,205.238.4.171,7/19/2019,10,1042.23 +107,Lynsey,Plum,lplum2y@blogtalkradio.com,Female,184.41.245.159,11/15/2019,27,1913.04 +108,Dorella,Dulanty,ddulanty2z@discuz.net,Female,29.143.190.208,3/15/2019,71,1939.76 +109,Ruthi,Rishworth,rrishworth30@liveinternet.ru,Female,107.240.252.87,11/14/2019,25,4378.32 +110,Petrina,Featherstonehaugh,pfeatherstonehaugh31@umich.edu,Female,139.60.87.163,5/3/2019,86,2273.95 +111,Karla,Dechelle,kdechelle32@google.cn,Female,147.220.216.41,11/22/2019,79,2940.0 +112,Joshia,Fishlock,jfishlock33@booking.com,Male,158.103.241.179,7/8/2019,68,3644.03 +113,Junia,Maryman,jmaryman34@jigsy.com,Female,216.105.242.205,5/15/2019,97,2466.85 +114,Mabelle,Warmisham,mwarmisham35@mysql.com,Female,246.108.73.60,2/5/2019,43,1904.03 +115,Phaidra,Fleet,pfleet36@1und1.de,Female,83.157.253.208,2/13/2019,21,1765.81 +116,Flo,Mardlin,fmardlin37@unicef.org,Female,31.252.115.185,12/11/2018,14,3875.57 +117,Crin,Aspinall,caspinall38@pen.io,Female,152.151.189.190,9/21/2019,76,3615.12 +118,Lorrie,Carnaman,lcarnaman39@sina.com.cn,Male,182.12.111.81,2/1/2019,66,1537.87 +119,Barnabas,Denslow,bdenslow3a@dell.com,Male,109.193.202.177,10/17/2019,71,1352.18 +120,Bennett,Saffen,bsaffen3b@cloudflare.com,Male,180.151.92.220,3/8/2019,19,3352.34 +121,Jonell,Menauteau,jmenauteau3c@yellowbook.com,Female,49.115.246.26,9/25/2019,26,4823.26 +122,Alicia,Jakubovicz,ajakubovicz3d@nps.gov,Female,239.158.188.213,3/27/2019,32,1051.47 +123,Nikolai,Raselles,nraselles3e@histats.com,Male,94.104.99.187,5/13/2019,43,1043.08 +124,Nikolaos,Loder,nloder3f@google.it,Male,19.118.58.253,3/17/2019,73,1254.57 +125,Sheffield,Muncey,smuncey3g@elpais.com,Male,77.244.5.146,7/28/2019,67,1704.55 +126,Marni,Cowin,mcowin3h@google.com.br,Female,61.232.91.222,7/8/2019,50,1367.66 +127,Storm,Kennedy,skennedy3i@wikispaces.com,Female,191.12.223.90,7/31/2019,77,3871.16 +128,Trent,Gutierrez,tgutierrez3j@sourceforge.net,Male,113.242.15.190,8/10/2019,81,4352.61 +129,Dodi,Tiller,dtiller3k@dailymail.co.uk,Female,0.240.169.55,11/21/2019,35,4607.1 +130,Vivie,Sture,vsture3l@yelp.com,Female,46.11.195.152,10/27/2019,82,2166.72 +131,Nerissa,Giddins,ngiddins3m@whitehouse.gov,Female,25.100.68.103,3/11/2019,81,4326.19 +132,Emalee,Huckerby,ehuckerby3n@europa.eu,Female,249.239.20.180,2/14/2019,15,1607.1 +133,Cesare,Deave,cdeave3o@google.es,Male,215.226.177.3,12/16/2018,64,3602.38 +134,Britni,Neagle,bneagle3p@is.gd,Female,238.87.102.252,5/1/2019,95,3254.36 +135,Andrej,Gandrich,agandrich3q@addtoany.com,Male,122.104.65.90,8/14/2019,41,3220.23 +136,Cody,Worssam,cworssam3r@chronoengine.com,Male,221.63.128.0,11/11/2019,7,4570.98 +137,Mord,Bradford,mbradford3s@utexas.edu,Male,168.172.15.29,2/8/2019,52,2842.69 +138,Madeline,Golledge,mgolledge3t@japanpost.jp,Female,180.54.218.245,8/1/2019,31,2426.19 +139,Clarie,Tunn,ctunn3u@sun.com,Female,170.49.242.95,3/30/2019,6,2375.77 +140,Seana,Gatherell,sgatherell3v@myspace.com,Female,229.46.37.246,7/1/2019,83,3626.95 +141,Veronica,Fielder,vfielder3w@hugedomains.com,Female,211.136.81.248,10/5/2019,76,4578.69 +142,Kris,Searby,ksearby3x@constantcontact.com,Male,75.40.234.246,5/14/2019,79,3491.43 +143,Dorita,Henze,dhenze3y@mozilla.com,Female,19.91.34.111,3/5/2019,23,3869.59 +144,Ada,Sydall,asydall3z@netlog.com,Female,63.122.73.224,9/28/2019,5,3118.74 +145,Josias,Vanichkov,jvanichkov40@amazon.co.jp,Male,111.18.27.20,3/11/2019,82,1807.86 +146,Payton,Chesney,pchesney41@forbes.com,Male,253.128.22.165,6/1/2019,93,1101.65 +147,Arabele,Marcome,amarcome42@bbb.org,Female,25.78.95.237,8/25/2019,20,3268.49 +148,Dick,Egre,degre43@discovery.com,Male,136.113.116.45,3/3/2019,35,3221.24 +149,Charleen,Eckh,ceckh44@shareasale.com,Female,251.215.112.50,6/30/2019,47,3524.18 +150,Minne,Lawfull,mlawfull45@shinystat.com,Female,15.159.68.230,7/31/2019,56,3915.18 +151,Timi,Pelchat,tpelchat46@issuu.com,Female,218.157.149.25,11/17/2019,53,1224.92 +152,Gabrila,Goosnell,ggoosnell47@hugedomains.com,Female,79.133.249.98,12/28/2018,30,4687.86 +153,Casie,Brimm,cbrimm48@4shared.com,Female,252.229.161.4,2/15/2019,98,1455.37 +154,Leeland,Dewi,ldewi49@multiply.com,Male,81.68.121.138,3/25/2019,63,4518.04 +155,Pascal,Garred,pgarred4a@facebook.com,Male,223.70.91.166,5/3/2019,71,2996.67 +156,Lazaro,Manktelow,lmanktelow4b@wikia.com,Male,185.80.62.190,7/21/2019,82,1094.16 +157,Sandi,Montgomery,smontgomery4c@java.com,Female,190.222.21.13,11/17/2019,21,2832.31 +158,Valentine,Jimes,vjimes4d@about.com,Female,74.198.243.183,5/1/2019,53,1644.56 +159,Erika,Ferraresi,eferraresi4e@google.fr,Female,54.193.54.25,5/19/2019,21,4436.52 +160,Nerta,Zaczek,nzaczek4f@spotify.com,Female,108.17.93.214,2/22/2019,81,2156.82 +161,Lucita,Harte,lharte4g@nasa.gov,Female,193.242.177.185,12/21/2018,64,3544.36 +162,Jedidiah,Danielsohn,jdanielsohn4h@accuweather.com,Male,245.98.253.52,9/16/2019,1,2115.11 +163,Lorettalorna,Quarrie,lquarrie4i@fc2.com,Female,76.173.212.93,6/13/2019,4,1466.75 +164,Rich,Tryhorn,rtryhorn4j@moonfruit.com,Male,143.167.201.182,10/7/2019,1,1661.04 +165,Gardie,Karlqvist,gkarlqvist4k@so-net.ne.jp,Male,249.11.192.35,8/12/2019,6,3746.95 +166,Xylia,Penna,xpenna4l@dailymotion.com,Female,180.58.51.110,11/28/2019,61,3441.57 +167,Axel,Renackowna,arenackowna4m@tripod.com,Male,146.67.140.217,3/7/2019,78,3550.93 +168,Chen,Fulton,cfulton4n@columbia.edu,Male,146.169.34.152,4/2/2019,74,2383.26 +169,Alon,Cufley,acufley4o@photobucket.com,Male,125.231.215.140,4/16/2019,65,1732.78 +170,Koo,Gumm,kgumm4p@php.net,Female,243.153.77.38,3/21/2019,48,3721.4 +171,Korey,Weatherdon,kweatherdon4q@blogger.com,Male,240.168.248.218,3/12/2019,77,3795.59 +172,Lena,Stannus,lstannus4r@lulu.com,Female,109.85.91.216,12/5/2018,46,2634.33 +173,Elijah,Westney,ewestney4s@noaa.gov,Male,158.146.220.98,8/7/2019,27,4530.75 +174,Eachelle,Schiefersten,eschiefersten4t@symantec.com,Female,54.128.102.166,9/15/2019,87,2940.88 +175,Georgeanne,Gotthard.sf,ggotthardsf4u@geocities.com,Female,86.43.67.105,1/9/2019,37,2319.01 +176,Frazier,Feldbrin,ffeldbrin4v@joomla.org,Male,184.234.191.22,10/14/2019,23,4596.74 +177,Bancroft,Alvarez,balvarez4w@cisco.com,Male,226.3.76.213,7/28/2019,21,3413.13 +178,Ricky,Lyles,rlyles4x@abc.net.au,Male,156.11.73.17,11/28/2019,6,1870.07 +179,Lorettalorna,Bomfield,lbomfield4y@virginia.edu,Female,37.210.36.178,6/20/2019,66,1127.34 +180,Catrina,Ruse,cruse4z@exblog.jp,Female,81.216.141.90,12/5/2018,34,2485.16 +181,Loleta,Pawels,lpawels50@merriam-webster.com,Female,176.42.193.141,6/10/2019,84,4221.89 +182,Hedvige,Commings,hcommings51@domainmarket.com,Female,138.3.249.198,1/29/2019,8,3910.06 +183,Dmitri,McCrory,dmccrory52@mit.edu,Male,135.37.103.219,7/28/2019,64,2804.83 +184,Hendrika,Shawyer,hshawyer53@xinhuanet.com,Female,16.30.34.147,2/20/2019,65,1706.29 +185,Lorilee,Dunlop,ldunlop54@ed.gov,Female,111.241.90.104,5/10/2019,75,4965.63 +186,Jerad,Faunch,jfaunch55@blogtalkradio.com,Male,139.35.31.167,3/18/2019,93,4404.83 +187,Gualterio,Eary,geary56@illinois.edu,Male,59.170.22.192,10/2/2019,49,3569.07 +188,Barby,Jikylls,bjikylls57@deviantart.com,Female,22.44.213.16,4/7/2019,75,4908.44 +189,Jabez,Mathiot,jmathiot58@w3.org,Male,93.194.63.80,5/5/2019,64,2744.04 +190,Worthy,Edland,wedland59@barnesandnoble.com,Male,4.66.208.56,11/12/2019,51,4272.28 +191,Doralyn,Braunstein,dbraunstein5a@youtube.com,Female,68.179.11.250,3/1/2019,37,3713.51 +192,Mallory,Eyres,meyres5b@google.com.hk,Female,222.214.3.63,7/22/2019,57,3522.06 +193,Louie,Dunkley,ldunkley5c@cdc.gov,Male,154.18.175.128,7/10/2019,51,2901.79 +194,Elbert,Kenvin,ekenvin5d@ftc.gov,Male,206.116.235.21,2/23/2019,75,4198.55 +195,Sean,Hankin,shankin5e@virginia.edu,Female,32.170.127.155,7/7/2019,76,4284.24 +196,Tamiko,O'Fogarty,tofogarty5f@comsenz.com,Female,249.124.65.230,2/27/2019,97,1816.59 +197,Dana,Caress,dcaress5g@bandcamp.com,Female,63.163.104.0,6/11/2019,70,4546.28 +198,Starla,Bicksteth,sbicksteth5h@deviantart.com,Female,93.41.109.63,3/6/2019,75,1536.56 +199,Olly,Chalmers,ochalmers5i@nature.com,Male,206.17.239.226,6/1/2019,99,2617.06 +200,Ermengarde,Laible,elaible5j@alibaba.com,Female,232.255.191.98,4/14/2019,7,2122.32 +201,Melloney,Stalf,mstalf5k@constantcontact.com,Female,254.159.238.133,3/11/2019,17,1829.95 +202,Aggy,Sandry,asandry5l@chicagotribune.com,Female,88.162.78.17,4/23/2019,82,1228.42 +203,Tuesday,Brunning,tbrunning5m@microsoft.com,Female,24.185.56.166,12/2/2018,25,2420.45 +204,Graehme,Marconi,gmarconi5n@forbes.com,Male,134.166.130.121,1/15/2019,29,3650.99 +205,Susi,Casillas,scasillas5o@jimdo.com,Female,130.75.119.191,4/6/2019,26,3164.59 +206,Bunny,Bollands,bbollands5p@privacy.gov.au,Female,73.155.139.92,7/20/2019,94,1459.89 +207,Corrine,Bythway,cbythway5q@ucsd.edu,Female,152.20.150.152,12/30/2018,74,1997.35 +208,Dannye,Adshede,dadshede5r@netlog.com,Female,210.46.12.79,8/9/2019,28,2915.74 +209,Gerald,Waiton,gwaiton5s@1und1.de,Male,47.243.251.9,5/18/2019,66,3698.92 +210,Belia,Hatherley,bhatherley5t@dot.gov,Female,3.253.140.62,10/2/2019,54,1089.69 +211,Terrell,Witherup,twitherup5u@ibm.com,Male,125.43.97.27,5/20/2019,97,3331.73 +212,Vic,Kliner,vkliner5v@cargocollective.com,Male,91.117.26.173,1/22/2019,12,1020.32 +213,Mayor,Drover,mdrover5w@comsenz.com,Male,165.45.244.175,9/18/2019,83,1282.01 +214,Didi,Kanwell,dkanwell5x@mysql.com,Female,249.71.28.189,1/25/2019,39,3401.56 +215,Lothario,Heyworth,lheyworth5y@patch.com,Male,204.254.193.144,6/27/2019,14,2392.22 +216,Adi,Bertome,abertome5z@washingtonpost.com,Female,247.98.53.39,3/19/2019,67,1188.17 +217,Zebadiah,Kryzhov,zkryzhov60@columbia.edu,Male,126.42.169.163,11/28/2019,85,2177.47 +218,Putnam,Wallworke,pwallworke61@sourceforge.net,Male,54.55.143.193,4/5/2019,72,4454.14 +219,Amery,Hitchens,ahitchens62@harvard.edu,Male,48.224.217.2,6/13/2019,64,3615.62 +220,Joana,Davitti,jdavitti63@ebay.co.uk,Female,62.165.254.131,3/4/2019,80,3629.81 +221,Kathleen,Tuer,ktuer64@biblegateway.com,Female,5.70.130.77,3/11/2019,13,1608.46 +222,Renaldo,Campbell-Dunlop,rcampbelldunlop65@skyrock.com,Male,26.131.233.63,12/29/2018,50,3202.62 +223,Titus,Ault,tault66@elpais.com,Male,165.158.147.201,7/2/2019,84,4835.57 +224,Gamaliel,Kilfedder,gkilfedder67@hostgator.com,Male,84.168.17.247,12/23/2018,9,4909.15 +225,Stewart,Boylund,sboylund68@liveinternet.ru,Male,225.118.153.204,6/28/2019,11,3319.59 +226,Jo,Kitchiner,jkitchiner69@skype.com,Female,59.124.146.200,2/6/2019,67,1600.09 +227,Elvis,Fosken,efosken6a@pcworld.com,Male,205.87.85.15,9/9/2019,6,3922.34 +228,Cammie,Danson,cdanson6b@narod.ru,Female,56.105.230.103,2/13/2019,65,1885.94 +229,Fabiano,Garaghan,fgaraghan6c@ezinearticles.com,Male,78.123.49.176,7/20/2019,51,3114.09 +230,Ailina,Givens,agivens6d@cbsnews.com,Female,60.180.138.180,7/5/2019,89,4535.53 +231,Armstrong,Dunkerly,adunkerly6e@independent.co.uk,Male,90.216.21.184,2/26/2019,14,1990.77 +232,Catharine,Matityahu,cmatityahu6f@alibaba.com,Female,57.63.241.97,3/10/2019,95,3363.25 +233,Sile,Glassman,sglassman6g@google.com.au,Female,69.8.60.158,9/2/2019,51,1557.41 +234,Benyamin,Scantleberry,bscantleberry6h@constantcontact.com,Male,130.141.87.136,2/28/2019,73,2950.29 +235,Mendel,Whether,mwhether6i@google.com,Male,241.33.68.87,8/7/2019,82,1090.67 +236,Marcos,Everitt,meveritt6j@yelp.com,Male,233.19.226.38,3/31/2019,37,1052.69 +237,Missie,Eastment,meastment6k@statcounter.com,Female,70.194.212.197,12/20/2018,78,4585.45 +238,Tim,Godfray,tgodfray6l@ucla.edu,Male,200.47.142.40,2/15/2019,5,1682.26 +239,Aguste,Pinney,apinney6m@posterous.com,Male,230.75.22.90,5/30/2019,41,2301.61 +240,Matthias,Francesconi,mfrancesconi6n@biglobe.ne.jp,Male,105.93.88.19,12/8/2018,67,4462.69 +241,Donna,Luckes,dluckes6o@over-blog.com,Female,213.3.126.62,7/2/2019,16,2107.3 +242,Nathanial,Spurden,nspurden6p@microsoft.com,Male,230.177.142.225,3/28/2019,78,1795.33 +243,Stanford,Keets,skeets6q@sbwire.com,Male,192.100.251.103,5/30/2019,60,1912.38 +244,Joly,Mont,jmont6r@technorati.com,Female,14.164.142.106,4/29/2019,23,4036.1 +245,Tyrus,Reasce,treasce6s@ibm.com,Male,12.231.0.1,12/15/2018,60,2707.42 +246,Lee,MacKeogh,lmackeogh6t@woothemes.com,Male,182.53.212.225,12/26/2018,49,1052.96 +247,Valeria,Le Hucquet,vlehucquet6u@cisco.com,Female,155.224.213.71,1/8/2019,67,1292.01 +248,Jillana,Breddy,jbreddy6v@fc2.com,Female,97.42.41.207,1/27/2019,79,2603.53 +249,Alic,Bergeau,abergeau6w@fema.gov,Male,247.140.30.46,10/2/2019,61,1209.85 +250,Cairistiona,Meredith,cmeredith6x@hhs.gov,Female,70.70.142.81,4/12/2019,17,3084.34 +251,Baird,Hollerin,bhollerin6y@issuu.com,Male,22.99.57.132,9/29/2019,50,2427.97 +252,Leonard,Caldecot,lcaldecot6z@vistaprint.com,Male,181.234.61.189,1/17/2019,4,4714.6 +253,Frants,Cochrane,fcochrane70@usgs.gov,Male,243.153.97.44,10/25/2019,7,2131.81 +254,Gertrud,Enticknap,genticknap71@csmonitor.com,Female,252.82.226.210,5/21/2019,11,2407.13 +255,Sullivan,Chattington,schattington72@pinterest.com,Male,155.193.236.102,1/10/2019,82,4204.53 +256,Taite,Sighard,tsighard73@dell.com,Male,201.139.42.108,7/13/2019,40,3983.56 +257,Rozina,Stannas,rstannas74@eventbrite.com,Female,175.179.96.178,1/6/2019,67,4645.75 +258,Sanson,Trevon,strevon75@patch.com,Male,40.224.2.112,5/22/2019,69,4383.12 +259,Torrey,Gilhoolie,tgilhoolie76@cdc.gov,Male,210.149.121.27,6/3/2019,44,2232.38 +260,Lauri,Lackeye,llackeye77@ted.com,Female,104.17.18.94,6/14/2019,21,3534.19 +261,Rica,Vineall,rvineall78@craigslist.org,Female,164.92.184.86,7/29/2019,67,2725.57 +262,Dane,Youell,dyouell79@flavors.me,Male,33.252.240.196,12/2/2018,78,2150.98 +263,Tricia,Singyard,tsingyard7a@facebook.com,Female,117.214.88.252,3/29/2019,46,1692.77 +264,Adrea,Rubinsohn,arubinsohn7b@sakura.ne.jp,Female,27.195.5.14,9/8/2019,72,3230.72 +265,Dotti,Brader,dbrader7c@addthis.com,Female,13.85.47.30,12/26/2018,100,2732.26 +266,Gabi,Fackrell,gfackrell7d@scientificamerican.com,Female,58.145.63.14,8/11/2019,95,1238.44 +267,Price,Moger,pmoger7e@deviantart.com,Male,19.116.110.91,8/15/2019,23,1473.89 +268,Jayme,Wakelin,jwakelin7f@cisco.com,Male,26.252.180.229,10/5/2019,56,4366.22 +269,Maurizio,Dunsmuir,mdunsmuir7g@clickbank.net,Male,120.22.85.145,11/3/2019,31,1877.99 +270,Carlos,Edmands,cedmands7h@redcross.org,Male,20.67.51.110,6/14/2019,79,1238.13 +271,Johan,McGinly,jmcginly7i@amazonaws.com,Male,12.205.191.101,3/20/2019,49,4095.82 +272,Albrecht,Rotchell,arotchell7j@google.es,Male,60.170.217.205,9/28/2019,92,2894.61 +273,Eli,De Lacey,edelacey7k@goo.ne.jp,Male,55.7.194.20,11/10/2019,78,4537.32 +274,Sutherlan,Mill,smill7l@i2i.jp,Male,130.65.164.97,1/16/2019,31,1681.32 +275,Nathalie,Willder,nwillder7m@usnews.com,Female,69.170.87.110,5/5/2019,1,1024.53 +276,Rem,Iczokvitz,riczokvitz7n@harvard.edu,Male,7.203.57.167,4/4/2019,39,3672.82 +277,Lorens,Denyukin,ldenyukin7o@uol.com.br,Male,203.70.155.205,2/14/2019,41,3600.8 +278,Mag,Pigden,mpigden7p@psu.edu,Female,239.194.157.251,6/14/2019,47,3599.97 +279,Petronia,Carvill,pcarvill7q@apple.com,Female,151.29.121.135,8/16/2019,68,4879.68 +280,Felicity,Capewell,fcapewell7r@patch.com,Female,176.136.185.249,9/14/2019,75,2448.16 +281,Hartwell,Zellner,hzellner7s@wordpress.org,Male,210.182.89.221,5/26/2019,68,4758.87 +282,Marcela,Geggie,mgeggie7t@samsung.com,Female,118.65.180.139,2/10/2019,15,4222.62 +283,Keith,Loxston,kloxston7u@etsy.com,Male,30.75.222.61,3/31/2019,90,1964.35 +284,Mattheus,Guinn,mguinn7v@virginia.edu,Male,157.141.233.64,2/5/2019,20,1509.77 +285,Cristy,Van den Bosch,cvandenbosch7w@yandex.ru,Female,106.186.220.48,2/10/2019,57,2650.92 +286,Pansie,Pull,ppull7x@tripod.com,Female,133.223.218.112,3/12/2019,16,1844.52 +287,Hyacinthie,Bools,hbools7y@phpbb.com,Female,6.136.111.144,6/24/2019,88,3753.3 +288,Cosimo,Humphris,chumphris7z@ftc.gov,Male,42.252.197.80,1/8/2019,5,1335.74 +289,Raquela,Ledbetter,rledbetter80@imdb.com,Female,25.84.71.62,12/13/2018,39,4474.51 +290,Domingo,McKelvey,dmckelvey81@globo.com,Male,139.34.201.250,9/6/2019,40,4039.82 +291,Britta,Grzesiak,bgrzesiak82@google.fr,Female,254.24.80.245,7/7/2019,73,1052.79 +292,Palmer,Gliddon,pgliddon83@example.com,Male,60.248.224.227,12/27/2018,33,4273.36 +293,Millard,Feore,mfeore84@mlb.com,Male,129.50.148.247,4/3/2019,60,2015.88 +294,Lanie,Blasgen,lblasgen85@ocn.ne.jp,Female,124.254.122.231,10/6/2019,35,1212.04 +295,Sherry,Jamrowicz,sjamrowicz86@newyorker.com,Female,8.187.192.111,6/12/2019,57,2819.04 +296,Payton,Loxton,ploxton87@ted.com,Male,20.185.112.233,5/16/2019,9,4976.7 +297,Anderea,Blandford,ablandford88@tinypic.com,Female,30.186.15.181,2/3/2019,54,3962.4 +298,Adele,Goldstein,agoldstein89@csmonitor.com,Female,101.24.151.157,8/29/2019,47,1300.26 +299,Christiana,Kybbye,ckybbye8a@soup.io,Female,164.124.255.193,8/24/2019,35,4524.75 +300,Bettine,Bryden,bbryden8b@tinyurl.com,Female,71.23.174.26,4/21/2019,27,3413.85 +301,Halsey,Deeble,hdeeble8c@gizmodo.com,Male,17.234.31.127,8/30/2019,74,2872.84 +302,Peggi,Gallier,pgallier8d@aol.com,Female,34.161.21.167,3/28/2019,26,2530.19 +303,Oby,Lemanu,olemanu8e@skyrock.com,Male,123.215.166.71,10/24/2019,90,2590.72 +304,Kelly,Limbert,klimbert8f@123-reg.co.uk,Male,225.87.194.99,7/15/2019,71,3252.4 +305,Edmon,Pittham,epittham8g@wufoo.com,Male,206.168.11.133,11/1/2019,84,4290.32 +306,Nicola,Hazelby,nhazelby8h@nih.gov,Male,248.203.87.61,8/14/2019,33,4439.66 +307,Norry,Cheesworth,ncheesworth8i@spotify.com,Male,188.191.145.160,9/14/2019,19,3777.37 +308,Madeleine,Colchett,mcolchett8j@goo.ne.jp,Female,49.89.233.117,10/26/2019,97,3215.79 +309,Alyse,Rilston,arilston8k@friendfeed.com,Female,178.80.192.158,4/26/2019,10,3704.99 +310,Aubrey,Rodrigues,arodrigues8l@clickbank.net,Female,110.27.123.138,2/26/2019,82,3312.78 +311,Wade,Fitzgerald,wfitzgerald8m@blogspot.com,Male,83.93.6.27,4/14/2019,18,4200.81 +312,Bar,Aspall,baspall8n@jimdo.com,Male,220.44.202.201,6/14/2019,31,3252.11 +313,Martynne,Jurczik,mjurczik8o@homestead.com,Female,45.95.32.123,4/16/2019,64,3091.17 +314,Rem,Binion,rbinion8p@spiegel.de,Male,194.45.225.156,10/13/2019,32,1460.2 +315,Brocky,Picker,bpicker8q@usda.gov,Male,43.227.235.110,6/26/2019,13,2705.18 +316,Caspar,Frankowski,cfrankowski8r@baidu.com,Male,77.43.200.240,4/9/2019,65,3908.27 +317,Fernanda,Jerman,fjerman8s@qq.com,Female,251.97.23.5,12/2/2018,98,2644.07 +318,Kirbie,Hickford,khickford8t@phoca.cz,Female,222.19.145.98,2/18/2019,75,2101.99 +319,Justen,Simonsson,jsimonsson8u@goodreads.com,Male,50.143.144.122,5/18/2019,23,3668.84 +320,Base,Quainton,bquainton8v@quantcast.com,Male,210.105.216.149,9/25/2019,17,3690.64 +321,Evonne,Biss,ebiss8w@blogspot.com,Female,151.218.87.78,6/20/2019,54,2157.7 +322,Desmund,Naris,dnaris8x@cafepress.com,Male,158.117.9.15,4/8/2019,55,3607.48 +323,Briant,Pulley,bpulley8y@rediff.com,Male,226.108.222.137,7/8/2019,4,2048.56 +324,Neddy,Wannop,nwannop8z@cisco.com,Male,183.31.92.122,8/27/2019,59,3925.77 +325,Trip,Eberst,teberst90@so-net.ne.jp,Male,147.174.43.177,3/9/2019,54,3125.57 +326,Feodor,Ccomini,fccomini91@patch.com,Male,101.243.251.93,9/13/2019,9,1769.13 +327,Lazar,Krinks,lkrinks92@infoseek.co.jp,Male,21.83.214.146,10/20/2019,24,4619.45 +328,Tate,Kedslie,tkedslie93@businesswire.com,Female,141.169.231.230,5/30/2019,49,1552.68 +329,Jessee,Boggon,jboggon94@kickstarter.com,Male,203.194.131.251,11/9/2019,24,1485.03 +330,Doralyn,Durrad,ddurrad95@google.co.jp,Female,240.121.195.82,7/8/2019,86,2176.49 +331,Jesse,Thynn,jthynn96@usnews.com,Male,199.184.188.96,12/29/2018,33,2828.35 +332,Emlyn,Redparth,eredparth97@naver.com,Female,23.58.23.190,9/1/2019,55,1076.4 +333,Gusella,Dimsdale,gdimsdale98@fema.gov,Female,126.167.16.255,5/27/2019,98,3454.61 +334,Dunn,Rentalll,drentalll99@japanpost.jp,Male,222.206.129.103,7/25/2019,85,1144.19 +335,Hyacintha,Coltan,hcoltan9a@creativecommons.org,Female,109.55.166.241,4/4/2019,87,1786.85 +336,Hyacinthe,Matyatin,hmatyatin9b@1und1.de,Female,110.109.78.10,7/3/2019,93,1671.35 +337,Adrian,Sollowaye,asollowaye9c@sitemeter.com,Male,33.129.1.150,11/4/2019,88,3482.58 +338,Arlina,Merriment,amerriment9d@census.gov,Female,236.177.140.9,11/17/2019,95,1747.4 +339,Anne-marie,Fakes,afakes9e@wix.com,Female,61.10.72.218,12/17/2018,67,1347.14 +340,Chico,Curgenuer,ccurgenuer9f@jugem.jp,Male,70.238.241.201,5/12/2019,90,4320.01 +341,Lonee,Roggerone,lroggerone9g@bizjournals.com,Female,176.243.54.186,4/28/2019,89,3039.36 +342,Kendell,Howett,khowett9h@fema.gov,Male,199.214.110.115,3/29/2019,12,2789.57 +343,Agatha,Dolligon,adolligon9i@canalblog.com,Female,34.170.13.241,12/20/2018,92,4743.08 +344,Ky,Fedder,kfedder9j@blogtalkradio.com,Male,163.0.64.234,6/29/2019,25,3252.69 +345,Wat,Kelsell,wkelsell9k@utexas.edu,Male,214.250.242.115,8/21/2019,70,2043.76 +346,Emyle,MacKean,emackean9l@networksolutions.com,Female,92.255.128.207,6/30/2019,1,3104.96 +347,Jeanette,Uridge,juridge9m@ucoz.com,Female,19.150.66.177,1/5/2019,64,4984.27 +348,Lilia,Vann,lvann9n@google.it,Female,89.252.120.154,10/16/2019,75,2663.58 +349,Cecile,Bromley,cbromley9o@unesco.org,Female,123.37.220.84,7/20/2019,54,2929.23 +350,Laureen,Twiddle,ltwiddle9p@narod.ru,Female,216.255.144.65,10/16/2019,19,1270.83 +351,Judas,de Clerc,jdeclerc9q@123-reg.co.uk,Male,70.252.28.9,7/19/2019,52,2346.55 +352,Ardeen,Loveman,aloveman9r@ow.ly,Female,156.219.46.63,2/10/2019,22,2964.62 +353,Raychel,Bilbie,rbilbie9s@cbslocal.com,Female,17.168.95.135,7/30/2019,77,2114.06 +354,Aylmer,Ortsmann,aortsmann9t@wufoo.com,Male,38.11.85.41,7/7/2019,93,3751.57 +355,Cassey,Ivanilov,civanilov9u@infoseek.co.jp,Female,55.185.103.167,8/19/2019,31,2292.8 +356,Hedwiga,Mabbitt,hmabbitt9v@hostgator.com,Female,138.225.43.83,5/18/2019,34,3855.85 +357,Andy,Selwin,aselwin9w@php.net,Female,125.221.82.185,11/12/2019,33,3992.33 +358,Alfonso,Waiton,awaiton9x@cam.ac.uk,Male,229.52.201.138,12/12/2018,79,4822.9 +359,Falito,Waugh,fwaugh9y@behance.net,Male,139.179.83.249,2/9/2019,58,4262.13 +360,Goldia,Devennie,gdevennie9z@globo.com,Female,201.225.234.254,6/29/2019,57,4846.5 +361,Charmaine,Craney,ccraneya0@tinypic.com,Female,225.240.75.169,7/12/2019,84,1316.62 +362,Zeke,Laidlow,zlaidlowa1@ehow.com,Male,166.40.176.121,7/4/2019,35,3356.21 +363,Brok,Drayton,bdraytona2@livejournal.com,Male,144.40.40.68,8/13/2019,11,4276.45 +364,Yorke,Stickins,ystickinsa3@joomla.org,Male,43.66.244.157,9/2/2019,69,4537.3 +365,Niven,Carlow,ncarlowa4@berkeley.edu,Male,172.206.45.58,7/5/2019,65,3926.86 +366,Dexter,Roycraft,droycrafta5@bbb.org,Male,77.45.212.134,7/21/2019,55,3035.99 +367,Nicoline,Maryin,nmaryina6@google.com.au,Female,47.168.8.172,8/1/2019,41,4917.76 +368,Ryon,Manuaud,rmanuauda7@domainmarket.com,Male,47.123.90.232,2/9/2019,74,2439.17 +369,Yehudi,Paylie,ypayliea8@domainmarket.com,Male,191.251.55.194,1/27/2019,6,1923.42 +370,Griffith,Tincey,gtinceya9@oaic.gov.au,Male,25.66.148.134,9/12/2019,39,2655.81 +371,Rafa,McLeman,rmclemanaa@mac.com,Female,230.203.148.84,5/6/2019,15,1870.44 +372,Ethel,Deuss,edeussab@hp.com,Female,28.53.103.241,5/16/2019,32,1469.62 +373,Vasily,Sockell,vsockellac@istockphoto.com,Male,56.222.178.227,3/11/2019,69,1735.2 +374,Lorenza,Adelsberg,ladelsbergad@fda.gov,Female,11.94.242.174,1/22/2019,86,3213.96 +375,Colas,Wakerley,cwakerleyae@hostgator.com,Male,145.79.64.143,10/18/2019,32,3929.61 +376,Corbie,Suthworth,csuthworthaf@so-net.ne.jp,Male,185.110.156.111,11/20/2019,59,1791.8 +377,Raviv,Burdon,rburdonag@google.cn,Male,199.130.230.228,8/31/2019,56,2672.48 +378,Willabella,Braybrook,wbraybrookah@wired.com,Female,21.168.228.152,8/23/2019,81,3055.15 +379,Stavro,Culley,sculleyai@rambler.ru,Male,200.89.13.168,7/13/2019,53,4163.02 +380,Even,Scargill,escargillaj@boston.com,Male,239.83.129.85,4/1/2019,3,3610.96 +381,Estell,Feltham,efelthamak@amazon.com,Female,15.107.128.8,12/17/2018,47,4775.21 +382,Babette,Vel,bvelal@spotify.com,Female,175.148.241.38,1/10/2019,41,3884.25 +383,Artair,Sonschein,asonscheinam@paginegialle.it,Male,127.94.90.52,9/23/2019,34,3579.98 +384,Pegeen,Taynton,ptayntonan@mozilla.org,Female,237.12.237.200,8/17/2019,83,4949.73 +385,Rubina,Yarnley,ryarnleyao@bravesites.com,Female,163.161.0.128,2/1/2019,48,2608.0 +386,Imojean,Swadlen,iswadlenap@behance.net,Female,187.101.162.242,11/26/2019,25,3891.41 +387,Remington,Hunnam,rhunnamaq@xrea.com,Male,155.26.3.155,3/2/2019,98,4085.69 +388,Cart,Symson,csymsonar@arstechnica.com,Male,65.122.8.87,12/12/2018,10,1780.3 +389,Kate,Fitzsimons,kfitzsimonsas@i2i.jp,Female,43.231.183.143,9/5/2019,8,4589.81 +390,Derril,Rimmington,drimmingtonat@homestead.com,Male,6.22.197.94,5/8/2019,63,3112.81 +391,Alyson,McCue,amccueau@wikia.com,Female,23.46.105.252,8/28/2019,70,3955.82 +392,Magdalen,Huncoot,mhuncootav@spiegel.de,Female,148.37.230.51,10/31/2019,2,4091.18 +393,Quincey,Tumilson,qtumilsonaw@webeden.co.uk,Male,56.32.172.37,4/8/2019,42,1930.92 +394,Patrick,Causer,pcauserax@ucsd.edu,Male,246.121.43.120,5/6/2019,93,4121.69 +395,Nadia,Vannuccini,nvannucciniay@ifeng.com,Female,136.227.239.1,6/28/2019,9,2309.55 +396,Grethel,Briggs,gbriggsaz@opensource.org,Female,74.158.54.139,12/18/2018,93,1324.43 +397,Carmelina,Witson,cwitsonb0@slate.com,Female,0.189.23.96,9/17/2019,95,2043.81 +398,Stanford,Gariff,sgariffb1@latimes.com,Male,30.67.52.138,11/28/2019,23,3754.58 +399,Broddie,Dunster,bdunsterb2@businesswire.com,Male,195.171.91.125,5/13/2019,35,1781.96 +400,Brigit,Brownsworth,bbrownsworthb3@yale.edu,Female,235.56.89.121,5/7/2019,11,2976.14 +401,Hillary,Daughtrey,hdaughtreyb4@zimbio.com,Male,171.99.161.95,3/31/2019,14,4683.28 +402,Rubetta,Ryding,rrydingb5@facebook.com,Female,121.209.254.88,2/16/2019,48,3181.31 +403,Darill,Giffin,dgiffinb6@so-net.ne.jp,Male,76.229.144.119,12/1/2019,20,1267.15 +404,Meredith,Leghorn,mleghornb7@google.co.jp,Female,88.130.30.36,3/6/2019,73,1165.58 +405,Godfrey,Kleinhandler,gkleinhandlerb8@auda.org.au,Male,202.128.125.132,2/14/2019,50,4151.4 +406,Andie,Tootell,atootellb9@netscape.com,Male,145.145.81.122,6/12/2019,41,1126.15 +407,Roselia,Craise,rcraiseba@java.com,Female,200.79.82.15,6/21/2019,56,4562.67 +408,Conny,Saice,csaicebb@baidu.com,Male,242.82.15.36,11/6/2019,20,4226.99 +409,Keary,Hartrick,khartrickbc@independent.co.uk,Male,189.126.222.123,12/13/2018,86,3150.61 +410,Salli,Scotchmer,sscotchmerbd@cloudflare.com,Female,229.204.119.25,1/15/2019,85,4684.69 +411,Verena,Everington,veveringtonbe@delicious.com,Female,49.206.228.25,4/25/2019,67,2869.88 +412,Bambi,Berzon,bberzonbf@dailymotion.com,Female,47.88.180.96,10/26/2019,67,4843.29 +413,Barbara,Kovacs,bkovacsbg@deliciousdays.com,Female,116.1.242.72,4/20/2019,43,2218.64 +414,Laurice,Adrianello,ladrianellobh@nbcnews.com,Female,69.69.82.208,6/21/2019,91,3331.25 +415,Nadine,Stenning,nstenningbi@tripadvisor.com,Female,105.204.235.18,9/2/2019,13,2037.16 +416,Cristina,Milsap,cmilsapbj@t-online.de,Female,36.13.98.63,12/4/2018,51,2933.37 +417,Kaleb,Easby,keasbybk@howstuffworks.com,Male,59.120.45.235,12/11/2018,4,1277.52 +418,Alister,Kyberd,akyberdbl@wsj.com,Male,184.221.78.151,5/1/2019,85,3931.28 +419,Roma,Uvedale,ruvedalebm@jigsy.com,Male,127.113.15.154,7/21/2019,71,4158.48 +420,Chrisse,Briggs,cbriggsbn@godaddy.com,Male,36.183.171.148,7/26/2019,63,1042.39 +421,Armin,Fidelus,afidelusbo@sogou.com,Male,207.188.30.35,1/13/2019,52,2565.26 +422,Helena,Harlow,hharlowbp@archive.org,Female,125.154.161.88,7/31/2019,11,3388.81 +423,Judy,Stone Fewings,jstonefewingsbq@youtube.com,Female,220.36.160.104,10/2/2019,54,2051.64 +424,Eddi,Gritsaev,egritsaevbr@sphinn.com,Female,36.194.183.230,6/1/2019,60,3020.44 +425,Royal,Juares,rjuaresbs@craigslist.org,Male,84.222.181.156,5/30/2019,30,2382.04 +426,Violette,Kopje,vkopjebt@blogs.com,Female,12.135.203.81,5/12/2019,61,3565.51 +427,Lesli,Franses,lfransesbu@histats.com,Female,124.138.107.148,11/22/2019,71,2644.08 +428,Alric,Barehead,abareheadbv@stumbleupon.com,Male,220.251.223.254,12/17/2018,6,2989.17 +429,Karin,Rosingdall,krosingdallbw@ucoz.ru,Female,83.135.106.197,8/9/2019,89,1199.79 +430,Margaretta,Hartles,mhartlesbx@google.com.br,Female,146.47.193.138,10/15/2019,82,1786.77 +431,Broderic,Adenot,badenotby@upenn.edu,Male,131.77.120.209,9/22/2019,15,4020.02 +432,Konstanze,Scintsbury,kscintsburybz@eepurl.com,Female,187.225.93.97,9/12/2019,91,3882.0 +433,Heriberto,Branchett,hbranchettc0@google.ca,Male,47.131.19.61,9/10/2019,30,3830.84 +434,Dulcy,Moxham,dmoxhamc1@pinterest.com,Female,139.65.244.96,3/31/2019,48,1930.97 +435,Kakalina,Pellamont,kpellamontc2@51.la,Female,46.138.21.69,3/29/2019,53,2265.45 +436,Durward,McAlester,dmcalesterc3@wisc.edu,Male,43.93.21.201,4/1/2019,19,4312.73 +437,Alfy,Dawby,adawbyc4@alibaba.com,Female,60.254.119.60,7/12/2019,53,1447.77 +438,Rafferty,Cullabine,rcullabinec5@acquirethisname.com,Male,107.140.224.21,8/31/2019,10,4627.05 +439,Catlaina,Laurenty,claurentyc6@tripod.com,Female,72.146.104.69,5/8/2019,77,1050.26 +440,Yves,Kinnock,ykinnockc7@narod.ru,Male,212.80.251.121,9/24/2019,26,4289.62 +441,Rustie,Runham,rrunhamc8@google.cn,Male,14.208.111.115,3/30/2019,17,3840.32 +442,Shannon,Teece,steecec9@issuu.com,Female,224.215.224.129,11/26/2019,87,3028.32 +443,Tawsha,Huggons,thuggonsca@oakley.com,Female,28.182.47.108,12/9/2018,80,3985.84 +444,Jozef,Ropcke,jropckecb@washington.edu,Male,71.34.133.206,10/5/2019,51,2177.5 +445,Brittany,Treadgold,btreadgoldcc@dell.com,Female,70.179.135.39,10/6/2019,35,1239.98 +446,Reynolds,Dungay,rdungaycd@taobao.com,Male,198.198.184.105,3/17/2019,84,1401.56 +447,Deeyn,MacNeely,dmacneelyce@google.nl,Female,129.131.12.166,9/24/2019,67,2584.15 +448,Opalina,McAndrew,omcandrewcf@imgur.com,Female,170.144.235.40,9/27/2019,32,1990.03 +449,Annabell,Bowne,abownecg@tamu.edu,Female,15.103.10.164,11/4/2019,82,4979.86 +450,Shepherd,Toye,stoyech@oakley.com,Male,28.94.51.150,5/4/2019,79,3581.94 +451,Dolorita,Rowatt,drowattci@yale.edu,Female,199.209.35.59,1/7/2019,46,2901.35 +452,Gale,Fenich,gfenichcj@seattletimes.com,Female,117.140.18.113,2/2/2019,95,1402.56 +453,Salvidor,Ruperti,srupertick@mashable.com,Male,253.18.192.61,6/10/2019,83,4161.11 +454,Griffie,Colthard,gcolthardcl@google.com.br,Male,125.41.227.143,5/28/2019,72,2219.96 +455,York,Rittmeyer,yrittmeyercm@redcross.org,Male,117.143.157.105,12/25/2018,69,2618.72 +456,Sarene,Brantzen,sbrantzencn@dion.ne.jp,Female,243.21.1.226,1/14/2019,99,1604.26 +457,Maximilien,Jouhan,mjouhanco@dailymotion.com,Male,135.19.146.201,8/12/2019,22,2904.57 +458,Valma,Chipping,vchippingcp@last.fm,Female,106.227.96.134,12/11/2018,21,2367.02 +459,Delmar,Kaas,dkaascq@histats.com,Male,149.43.164.167,8/29/2019,33,1178.21 +460,Dalli,MacBain,dmacbaincr@tripod.com,Male,179.253.105.225,6/28/2019,57,4678.73 +461,Griz,Macquire,gmacquirecs@google.cn,Male,131.224.85.128,8/28/2019,22,1605.86 +462,Far,Ogden,fogdenct@reverbnation.com,Male,164.236.27.67,12/10/2018,46,3121.44 +463,Eleen,Norree,enorreecu@telegraph.co.uk,Female,172.69.9.125,4/6/2019,18,4440.78 +464,Franzen,Izkoveski,fizkoveskicv@issuu.com,Male,92.192.132.174,9/19/2019,12,2651.29 +465,Rhiamon,Saladino,rsaladinocw@wix.com,Female,123.91.96.42,4/10/2019,88,4982.0 +466,Franny,Grinin,fgrinincx@booking.com,Male,43.0.247.215,3/26/2019,89,3774.54 +467,Colin,O'Donohue,codonohuecy@go.com,Male,88.162.185.175,10/22/2019,3,3491.68 +468,Wendye,Compson,wcompsoncz@hud.gov,Female,136.150.155.64,11/13/2019,74,4538.45 +469,Dyane,Raithmill,draithmilld0@ted.com,Female,235.21.43.42,5/16/2019,17,3995.57 +470,Lacie,Dumper,ldumperd1@ycombinator.com,Female,211.130.88.136,5/5/2019,21,4467.62 +471,Talbert,Jurca,tjurcad2@soup.io,Male,110.180.63.75,4/11/2019,72,1047.55 +472,Blondelle,Ingerfield,bingerfieldd3@bbc.co.uk,Female,21.57.56.111,10/18/2019,36,4305.36 +473,Huntington,Keele,hkeeled4@wired.com,Male,29.115.183.130,1/18/2019,90,3988.22 +474,Merle,Lissenden,mlissendend5@google.ru,Male,181.207.215.130,9/9/2019,14,3780.87 +475,Ahmed,Lowthorpe,alowthorped6@fotki.com,Male,170.252.164.227,7/24/2019,56,1887.16 +476,Melli,Monsey,mmonseyd7@house.gov,Female,226.80.98.178,5/13/2019,14,2671.62 +477,Shelly,Flay,sflayd8@epa.gov,Female,77.216.133.212,7/25/2019,13,4660.94 +478,Ryun,Maffey,rmaffeyd9@discovery.com,Male,130.172.183.105,12/18/2018,45,3261.01 +479,Archer,Monksfield,amonksfieldda@google.com.br,Male,182.48.50.111,8/2/2019,52,3036.93 +480,Rosemonde,Wragg,rwraggdb@icq.com,Female,195.223.97.213,8/25/2019,56,1193.62 +481,Halsey,Robbeke,hrobbekedc@cnet.com,Male,232.48.110.118,2/3/2019,42,1298.35 +482,Paten,Paslow,ppaslowdd@instagram.com,Male,29.24.97.210,5/13/2019,98,2545.85 +483,Dora,Ghidoli,dghidolide@digg.com,Female,58.13.173.228,8/13/2019,89,2796.74 +484,Arlene,Dronsfield,adronsfielddf@t.co,Female,79.160.187.181,3/18/2019,55,2539.18 +485,Blakelee,Lipp,blippdg@sakura.ne.jp,Female,19.124.37.230,8/29/2019,1,4628.15 +486,Cecelia,Grinham,cgrinhamdh@twitter.com,Female,234.55.104.182,2/3/2019,48,1693.35 +487,Onofredo,Andreazzi,oandreazzidi@google.ca,Male,117.52.172.57,7/29/2019,53,2615.64 +488,Kiley,Burdekin,kburdekindj@shop-pro.jp,Female,201.52.16.189,8/24/2019,95,3929.48 +489,Bink,Kestin,bkestindk@chron.com,Male,100.111.135.87,7/13/2019,21,1958.77 +490,Mitch,Cagan,mcagandl@pagesperso-orange.fr,Male,25.244.113.46,10/16/2019,82,2492.12 +491,Charlton,Hughes,chughesdm@dmoz.org,Male,29.138.111.115,11/12/2019,10,3339.82 +492,Doria,Ivatts,divattsdn@nih.gov,Female,242.17.53.201,5/29/2019,72,2228.99 +493,Coriss,Lathan,clathando@domainmarket.com,Female,25.75.179.134,10/4/2019,23,4848.67 +494,Elmore,Reside,eresidedp@diigo.com,Male,79.112.126.164,9/21/2019,59,1610.62 +495,Ezekiel,Scherer,eschererdq@telegraph.co.uk,Male,79.39.63.134,8/28/2019,69,1597.98 +496,Werner,Cobson,wcobsondr@artisteer.com,Male,227.194.178.190,3/13/2019,53,4233.49 +497,Randee,Ornillos,rornillosds@youtube.com,Female,67.192.57.128,12/22/2018,59,2404.97 +498,Gottfried,Carloni,gcarlonidt@google.ca,Male,176.184.59.246,7/25/2019,33,4007.86 +499,Findlay,Ferrieroi,fferrieroidu@edublogs.org,Male,164.15.3.146,6/15/2019,29,1439.89 +500,Anestassia,Caldron,acaldrondv@imdb.com,Female,73.5.249.139,12/5/2018,77,4450.98 +501,Ignazio,Prinnett,iprinnettdw@merriam-webster.com,Male,254.189.253.253,5/26/2019,53,3955.94 +502,Debi,Sedgebeer,dsedgebeerdx@msn.com,Female,90.91.234.210,11/26/2019,96,1951.45 +503,Beverlee,Colliard,bcolliarddy@stanford.edu,Female,112.73.182.216,8/1/2019,60,4097.93 +504,Cinnamon,McFadin,cmcfadindz@blogs.com,Female,149.198.138.102,4/3/2019,80,3719.88 +505,Walden,Bruinemann,wbruinemanne0@360.cn,Male,21.212.132.5,11/7/2019,92,2275.38 +506,Quinton,Glanfield,qglanfielde1@amazon.de,Male,213.175.246.203,12/13/2018,8,4630.05 +507,Cello,Potkins,cpotkinse2@github.com,Male,135.169.51.63,3/16/2019,63,2813.83 +508,Percival,Coley,pcoleye3@photobucket.com,Male,205.135.254.197,1/14/2019,93,3766.81 +509,Brockie,Siddens,bsiddense4@usda.gov,Male,166.107.18.144,7/26/2019,11,4226.07 +510,Emmerich,Eglise,eeglisee5@istockphoto.com,Male,39.239.19.196,11/3/2019,23,1444.76 +511,Theo,Olivetta,tolivettae6@yellowpages.com,Male,135.95.4.136,8/1/2019,59,3670.72 +512,Gabie,Blasius,gblasiuse7@vistaprint.com,Male,176.138.63.24,3/12/2019,100,3276.6 +513,Tiebold,Wharmby,twharmbye8@chicagotribune.com,Male,204.219.78.122,6/13/2019,73,3542.76 +514,Tann,Duke,tdukee9@irs.gov,Male,153.153.136.24,3/14/2019,70,2338.35 +515,Westley,Ottery,wotteryea@soundcloud.com,Male,35.239.11.15,9/18/2019,61,2876.26 +516,Noll,Birkmyre,nbirkmyreeb@histats.com,Male,45.218.226.8,5/4/2019,3,3180.04 +517,Angelle,Canizares,acanizaresec@usgs.gov,Female,79.98.22.161,11/16/2019,57,1414.53 +518,Maddy,Rawlins,mrawlinsed@ocn.ne.jp,Female,194.212.205.87,8/24/2019,9,2037.3 +519,Gonzales,Digle,gdigleee@tinyurl.com,Male,188.81.253.229,2/11/2019,31,1096.61 +520,Matias,Arrighetti,marrighettief@jimdo.com,Male,119.210.95.197,10/13/2019,59,1525.12 +521,Ag,Almon,aalmoneg@discuz.net,Female,211.209.145.71,5/9/2019,5,1832.58 +522,Romona,Keppel,rkeppeleh@auda.org.au,Female,180.44.222.236,12/5/2018,69,1470.18 +523,Aeriel,Seear,aseearei@over-blog.com,Female,132.233.16.148,6/8/2019,20,4592.62 +524,Terri,Trulocke,ttrulockeej@clickbank.net,Female,138.176.80.221,10/1/2019,5,1787.96 +525,Linn,Stonestreet,lstonestreetek@un.org,Male,74.243.5.94,11/27/2019,31,1779.4 +526,Dmitri,Coode,dcoodeel@ameblo.jp,Male,201.81.71.70,1/25/2019,94,1400.26 +527,Alane,Sabattier,asabattierem@scribd.com,Female,32.109.38.132,10/10/2019,10,1416.04 +528,Sadye,Esplin,sesplinen@tiny.cc,Female,76.85.72.29,3/14/2019,45,3626.01 +529,Alexia,Iorizzo,aiorizzoeo@themeforest.net,Female,172.234.209.31,7/10/2019,46,4064.06 +530,Gayelord,Kalewe,gkaleweep@over-blog.com,Male,83.169.129.240,9/10/2019,53,1508.96 +531,Clive,Stuchbery,cstuchberyeq@dell.com,Male,9.182.133.41,12/29/2018,21,4980.91 +532,Derron,Lober,dloberer@epa.gov,Male,184.138.78.88,2/14/2019,24,2245.42 +533,Aleda,Addison,aaddisones@wsj.com,Female,181.181.179.67,6/17/2019,81,4493.79 +534,Marshall,Ugolotti,mugolottiet@aboutads.info,Male,159.50.251.20,7/3/2019,35,1104.16 +535,Garold,Moxon,gmoxoneu@slashdot.org,Male,117.142.41.149,10/7/2019,34,2523.56 +536,Fee,Colleer,fcolleerev@state.gov,Male,207.42.100.89,4/12/2019,87,4816.8 +537,Smitty,Smallridge,ssmallridgeew@spotify.com,Male,132.67.213.163,2/26/2019,84,3814.0 +538,Ber,Pettegre,bpettegreex@google.ru,Male,8.176.93.49,9/6/2019,67,3272.53 +539,Tybi,Brown,tbrowney@ibm.com,Female,100.73.19.52,3/7/2019,76,1088.01 +540,Roxanne,Rigler,rriglerez@weebly.com,Female,29.96.199.117,4/1/2019,65,2694.03 +541,Alphonse,Astlett,aastlettf0@hatena.ne.jp,Male,244.194.52.149,7/29/2019,47,1467.11 +542,Calvin,Finn,cfinnf1@ucoz.com,Male,199.41.9.21,12/30/2018,7,1828.33 +543,Broddie,Brandts,bbrandtsf2@answers.com,Male,100.8.254.225,10/29/2019,64,1792.68 +544,Herrick,Chadderton,hchaddertonf3@wired.com,Male,187.66.85.223,3/1/2019,38,3230.59 +545,Teodoor,Benny,tbennyf4@home.pl,Male,6.177.43.100,4/29/2019,13,2503.4 +546,Karl,Wrintmore,kwrintmoref5@apple.com,Male,73.104.69.176,8/7/2019,97,2688.4 +547,Alexandra,Testo,atestof6@loc.gov,Female,15.230.156.211,6/9/2019,84,4522.93 +548,Colin,Giorgietto,cgiorgiettof7@nymag.com,Male,13.75.177.91,2/21/2019,3,3730.12 +549,Talbot,McNickle,tmcnicklef8@wp.com,Male,44.250.27.152,3/18/2019,30,2209.95 +550,Cassandre,Hayle,chaylef9@newyorker.com,Female,116.81.18.95,11/21/2019,10,3204.22 +551,Tommi,Bilney,tbilneyfa@prweb.com,Female,61.67.100.120,10/16/2019,79,3613.66 +552,Larisa,Pollok,lpollokfb@loc.gov,Female,79.115.80.86,9/30/2019,29,1901.41 +553,Deb,Dorkins,ddorkinsfc@xrea.com,Female,26.52.68.180,10/15/2019,99,4906.29 +554,Johanna,Kainz,jkainzfd@chronoengine.com,Female,142.73.143.215,8/18/2019,4,1226.42 +555,Gasparo,Handrek,ghandrekfe@vinaora.com,Male,21.21.61.211,10/16/2019,91,1731.15 +556,Elwyn,Zahor,ezahorff@washingtonpost.com,Male,184.132.148.138,1/5/2019,55,1626.51 +557,Devina,De Vaar,ddevaarfg@miibeian.gov.cn,Female,195.180.225.61,7/12/2019,2,4095.24 +558,Ikey,Verner,ivernerfh@msu.edu,Male,175.129.187.1,8/8/2019,10,1643.3 +559,Shae,Potteril,spotterilfi@cyberchimps.com,Male,135.218.100.211,9/30/2019,43,2747.3 +560,Kim,Kittel,kkittelfj@buzzfeed.com,Male,224.125.75.142,12/12/2018,17,4109.17 +561,Alexei,Morecomb,amorecombfk@independent.co.uk,Male,172.224.245.105,12/9/2018,33,2899.08 +562,Cathryn,Finnan,cfinnanfl@ask.com,Female,27.110.235.165,5/28/2019,94,4841.66 +563,Maryjane,Duffus,mduffusfm@eventbrite.com,Female,3.255.15.114,10/22/2019,54,1514.19 +564,Violetta,Reisk,vreiskfn@typepad.com,Female,39.227.35.28,4/18/2019,92,4609.62 +565,Vicky,Lots,vlotsfo@cisco.com,Female,231.114.228.254,7/16/2019,5,2747.65 +566,Odilia,Shemmans,oshemmansfp@phpbb.com,Female,173.16.238.214,7/15/2019,64,2509.13 +567,Doralynn,Borne,dbornefq@vistaprint.com,Female,182.193.106.25,9/27/2019,58,2388.86 +568,Gallagher,Tinsey,gtinseyfr@wsj.com,Male,222.169.135.174,8/26/2019,9,2587.26 +569,Ulberto,Hellyar,uhellyarfs@yellowbook.com,Male,248.76.37.74,7/15/2019,30,1922.6 +570,Carilyn,Skones,cskonesft@liveinternet.ru,Female,156.207.111.147,5/19/2019,37,4692.05 +571,Sarine,Rubinovitch,srubinovitchfu@networksolutions.com,Female,80.120.49.55,8/19/2019,20,1594.95 +572,Jemmy,Marlowe,jmarlowefv@engadget.com,Female,75.14.237.58,4/14/2019,51,1904.61 +573,Gaby,Demelt,gdemeltfw@infoseek.co.jp,Male,229.88.216.80,2/3/2019,51,1648.97 +574,Jacob,Lamberton,jlambertonfx@hugedomains.com,Male,47.215.55.112,11/23/2019,98,2245.77 +575,Emile,Bullivent,ebulliventfy@is.gd,Male,222.149.227.61,1/14/2019,28,2610.31 +576,Reidar,Gierardi,rgierardifz@flickr.com,Male,137.20.90.27,7/14/2019,44,1963.44 +577,Dwain,De Mars,ddemarsg0@theglobeandmail.com,Male,29.126.92.147,5/8/2019,83,2977.28 +578,Seth,Hebron,shebrong1@github.io,Male,97.93.183.184,2/17/2019,17,2725.06 +579,Shep,Rabjohn,srabjohng2@sfgate.com,Male,118.230.96.220,4/5/2019,75,4150.25 +580,Georgine,Martill,gmartillg3@who.int,Female,89.160.34.190,1/8/2019,37,4712.71 +581,Theodora,Mitchenson,tmitchensong4@delicious.com,Female,140.245.239.155,4/11/2019,58,1505.59 +582,Geri,Reedman,greedmang5@mac.com,Male,149.218.213.221,6/22/2019,29,3919.37 +583,Hamel,Ruddick,hruddickg6@uiuc.edu,Male,74.103.5.12,3/19/2019,32,2242.44 +584,Marylou,Baggott,mbaggottg7@goo.gl,Female,67.211.254.135,11/7/2019,35,4631.99 +585,Ignacius,Croisdall,icroisdallg8@imdb.com,Male,194.136.32.103,4/9/2019,22,4505.82 +586,Agnes,Pentercost,apentercostg9@yolasite.com,Female,201.109.22.156,4/7/2019,6,2659.75 +587,Phillipe,O'Henery,poheneryga@baidu.com,Male,169.210.213.194,4/28/2019,100,3089.16 +588,Mersey,Bilston,mbilstongb@mozilla.org,Female,212.118.21.202,6/6/2019,47,1546.62 +589,Carie,Pawelski,cpawelskigc@examiner.com,Female,185.32.131.13,12/23/2018,13,1607.17 +590,Cassandra,Zywicki,czywickigd@ask.com,Female,58.164.239.126,10/6/2019,86,3316.82 +591,Myrtia,Avrasin,mavrasinge@tripod.com,Female,23.46.205.131,6/2/2019,28,1376.97 +592,Stanford,Greatrakes,sgreatrakesgf@europa.eu,Male,110.99.123.217,12/31/2018,89,4653.75 +593,Giulietta,Hinkens,ghinkensgg@list-manage.com,Female,146.42.27.152,3/17/2019,90,4663.89 +594,Dame,Eam,deamgh@jalbum.net,Male,93.210.79.222,12/3/2018,99,4955.03 +595,Claresta,Spradbery,cspradberygi@wunderground.com,Female,177.74.189.41,5/7/2019,69,2660.67 +596,Charisse,Janos,cjanosgj@yellowbook.com,Female,107.1.160.123,11/30/2019,27,3260.09 +597,Mufi,Letterick,mletterickgk@apache.org,Female,230.153.229.231,6/16/2019,59,2986.56 +598,Fabe,Sabberton,fsabbertongl@mapquest.com,Male,219.168.121.194,7/18/2019,70,3658.28 +599,Nikolas,Gildersleaves,ngildersleavesgm@ox.ac.uk,Male,162.123.231.93,7/20/2019,78,1233.59 +600,Justin,Vigours,jvigoursgn@sourceforge.net,Male,154.142.42.26,6/28/2019,31,4990.95 +601,Kile,Le Clercq,kleclercqgo@indiatimes.com,Male,239.28.13.21,12/13/2018,84,1001.19 +602,Isidoro,Tregonna,itregonnagp@webeden.co.uk,Male,171.67.239.44,1/16/2019,41,4417.17 +603,Mab,Ironside,mironsidegq@google.cn,Female,42.162.241.202,7/23/2019,91,2259.53 +604,Dimitry,Manass,dmanassgr@51.la,Male,45.173.17.98,1/25/2019,46,1586.27 +605,Rossy,Arden,rardengs@bigcartel.com,Male,214.115.174.58,4/28/2019,51,1823.4 +606,Daniele,Barnard,dbarnardgt@so-net.ne.jp,Female,135.128.233.112,2/1/2019,71,3995.81 +607,Helene,Westphalen,hwestphalengu@addthis.com,Female,106.111.55.197,11/15/2019,95,2675.0 +608,Zeke,Mixer,zmixergv@europa.eu,Male,70.187.67.163,2/1/2019,26,1019.63 +609,Modesta,Cock,mcockgw@berkeley.edu,Female,16.132.149.179,1/19/2019,79,2922.43 +610,Bard,Vieyra,bvieyragx@shinystat.com,Male,192.107.97.186,10/5/2019,17,4998.16 +611,Boote,Geall,bgeallgy@networksolutions.com,Male,54.164.158.9,1/1/2019,95,3385.89 +612,Ninnetta,Loveman,nlovemangz@histats.com,Female,25.150.239.54,9/19/2019,24,3487.97 +613,Sigismund,Fitzer,sfitzerh0@163.com,Male,93.203.46.222,9/7/2019,26,3405.11 +614,Perren,Haquin,phaquinh1@networkadvertising.org,Male,27.195.139.40,7/13/2019,95,4472.37 +615,Ramsay,Galland,rgallandh2@sohu.com,Male,64.157.166.62,2/15/2019,30,3256.71 +616,Silva,Strete,sstreteh3@yellowpages.com,Female,28.120.167.41,10/30/2019,67,4109.49 +617,Dee dee,Poate,dpoateh4@github.io,Female,169.234.44.240,1/26/2019,87,2487.52 +618,Bianca,Martell,bmartellh5@bloomberg.com,Female,17.155.34.89,12/5/2018,88,2523.49 +619,Alan,Wallwork,awallworkh6@bloglines.com,Male,136.41.225.203,11/17/2019,32,2593.63 +620,Alysa,Lembrick,alembrickh7@github.io,Female,4.186.245.140,3/12/2019,42,4087.94 +621,Yoshiko,Alans,yalansh8@list-manage.com,Female,113.124.38.19,1/8/2019,5,3091.72 +622,Chelsy,Watford,cwatfordh9@yellowpages.com,Female,10.18.35.232,5/4/2019,86,4661.23 +623,Bill,Gotthard,bgotthardha@moonfruit.com,Male,169.67.131.116,5/21/2019,11,1287.77 +624,Cad,Kirtlan,ckirtlanhb@xrea.com,Male,40.152.181.2,1/24/2019,24,3155.78 +625,Ahmed,McClenan,amcclenanhc@webmd.com,Male,20.99.191.248,8/13/2019,36,3301.08 +626,Tobit,Barthelemy,tbarthelemyhd@bizjournals.com,Male,35.143.211.133,9/10/2019,98,1382.31 +627,Kacie,Lurner,klurnerhe@illinois.edu,Female,4.70.92.52,3/14/2019,58,3754.13 +628,Keith,Skeech,kskeechhf@pbs.org,Male,14.243.98.120,8/22/2019,99,2840.36 +629,Loy,Brettoner,lbrettonerhg@marriott.com,Male,244.228.186.208,5/28/2019,83,1322.53 +630,Ring,Keppy,rkeppyhh@mediafire.com,Male,63.223.185.137,10/29/2019,49,3414.88 +631,Jennee,Saltsberg,jsaltsberghi@angelfire.com,Female,168.154.55.70,2/20/2019,89,1792.13 +632,Leslie,Sunley,lsunleyhj@furl.net,Female,142.154.216.195,1/14/2019,85,1049.36 +633,Serge,Brightman,sbrightmanhk@nsw.gov.au,Male,218.24.194.199,8/25/2019,17,3821.08 +634,Thadeus,Janosevic,tjanosevichl@auda.org.au,Male,117.42.23.253,6/4/2019,12,3771.8 +635,Spense,Ribchester,sribchesterhm@google.cn,Male,60.125.96.255,3/20/2019,10,4152.59 +636,Cordelia,Petrashov,cpetrashovhn@jalbum.net,Female,4.255.192.99,5/3/2019,42,4778.71 +637,Rhea,Jest,rjestho@hao123.com,Female,60.250.169.224,11/1/2019,88,3984.23 +638,Patricia,Feehery,pfeeheryhp@dot.gov,Female,238.226.108.19,1/3/2019,72,2436.71 +639,Griffie,Haswell,ghaswellhq@linkedin.com,Male,141.208.249.19,3/30/2019,54,4591.33 +640,Isahella,Brockett,ibrocketthr@webnode.com,Female,187.222.253.93,8/18/2019,40,2025.08 +641,Rhea,Castiglioni,rcastiglionihs@cpanel.net,Female,59.223.205.19,3/28/2019,8,4878.09 +642,Stu,Gladman,sgladmanht@yandex.ru,Male,148.174.89.129,2/7/2019,6,4658.63 +643,Meade,Penn,mpennhu@tinypic.com,Female,159.237.205.132,7/14/2019,67,1741.76 +644,Analise,Teesdale,ateesdalehv@istockphoto.com,Female,112.255.159.227,4/27/2019,43,4943.97 +645,Gabbie,Gawith,ggawithhw@bing.com,Male,156.88.177.49,9/1/2019,30,2127.26 +646,Fancie,Matura,fmaturahx@prweb.com,Female,245.199.208.176,10/14/2019,48,3611.12 +647,Oneida,Klee,okleehy@merriam-webster.com,Female,76.241.235.4,4/24/2019,75,3574.83 +648,Patty,Deadman,pdeadmanhz@deviantart.com,Female,119.238.140.122,12/3/2018,78,4990.77 +649,Rica,Habbershon,rhabbershoni0@imdb.com,Female,235.54.40.9,8/21/2019,72,4008.1 +650,Dominick,Morphey,dmorpheyi1@state.gov,Male,26.182.126.198,9/27/2019,32,2803.47 +651,Lin,Elvey,lelveyi2@qq.com,Female,217.142.5.50,5/2/2019,75,1382.58 +652,Candra,Ellershaw,cellershawi3@liveinternet.ru,Female,37.103.239.8,11/5/2019,64,1785.17 +653,Petr,Blamey,pblameyi4@cornell.edu,Male,102.165.209.59,11/16/2019,23,4146.8 +654,Starlene,Shoebrook,sshoebrooki5@un.org,Female,168.143.167.147,3/14/2019,4,4991.14 +655,Rochelle,Inggall,ringgalli6@biglobe.ne.jp,Female,102.127.212.247,9/12/2019,81,1583.69 +656,Ezmeralda,Jubert,ejuberti7@icio.us,Female,81.4.17.157,7/22/2019,52,4205.34 +657,Berny,Crufts,bcruftsi8@jigsy.com,Female,244.211.38.231,1/6/2019,46,4968.82 +658,Philis,Hitzke,phitzkei9@google.es,Female,206.218.221.24,10/5/2019,21,2082.32 +659,Dacey,Beck,dbeckia@netscape.com,Female,52.22.157.97,4/17/2019,22,3785.01 +660,Lammond,Esmead,lesmeadib@slate.com,Male,216.172.89.83,4/11/2019,87,4186.81 +661,Bevin,Pattullo,bpattulloic@yelp.com,Male,96.237.177.242,9/30/2019,9,3862.46 +662,Abbie,Melsom,amelsomid@businesswire.com,Female,226.28.218.124,8/28/2019,98,4520.86 +663,Hilarius,Weagener,hweagenerie@google.nl,Male,6.108.117.111,9/10/2019,80,4920.12 +664,Onida,Dewberry,odewberryif@chron.com,Female,95.189.17.251,7/12/2019,27,1206.75 +665,Sawyer,Behne,sbehneig@who.int,Male,232.40.190.187,6/26/2019,92,2730.93 +666,Ingaborg,Benoit,ibenoitih@diigo.com,Female,45.171.74.30,2/26/2019,79,3169.39 +667,Christyna,Beardow,cbeardowii@hibu.com,Female,212.112.66.197,8/15/2019,22,1664.25 +668,Chrysa,Bouda,cboudaij@posterous.com,Female,182.254.214.92,6/20/2019,58,4842.58 +669,Skell,Janny,sjannyik@statcounter.com,Male,117.115.79.57,8/25/2019,64,3147.82 +670,Willie,Gisbye,wgisbyeil@smh.com.au,Male,163.74.14.6,12/24/2018,60,2181.71 +671,Loydie,MacGiolla Pheadair,lmacgiollapheadairim@ftc.gov,Male,66.165.25.118,12/24/2018,17,4234.43 +672,Millisent,Warwick,mwarwickin@google.co.uk,Female,11.125.80.152,5/27/2019,57,2770.04 +673,Lutero,Campelli,lcampelliio@alibaba.com,Male,218.66.248.154,10/4/2019,29,4169.81 +674,Waverly,Kroch,wkrochip@google.co.uk,Male,117.138.8.158,10/6/2019,55,2248.55 +675,Jorge,Tipple,jtippleiq@google.cn,Male,75.32.226.30,1/5/2019,20,2316.81 +676,Rycca,Markham,rmarkhamir@posterous.com,Female,108.165.80.206,4/1/2019,37,3733.9 +677,Kendell,Tabourel,ktabourelis@ucsd.edu,Male,31.106.135.186,1/27/2019,41,2767.65 +678,Xymenes,Christofol,xchristofolit@slashdot.org,Male,205.98.142.54,4/17/2019,75,3761.36 +679,Willamina,Gluyas,wgluyasiu@patch.com,Female,208.141.12.123,9/10/2019,62,4055.56 +680,Missy,Chaudron,mchaudroniv@ox.ac.uk,Female,253.225.93.169,5/17/2019,54,3188.83 +681,Harrie,Levee,hleveeiw@dropbox.com,Female,104.60.96.6,9/4/2019,73,3779.89 +682,Nickie,Awdry,nawdryix@deviantart.com,Female,186.254.251.36,1/3/2019,76,2909.63 +683,Wash,Mapletoft,wmapletoftiy@baidu.com,Male,176.231.204.160,2/12/2019,3,1072.43 +684,Thea,Crankshaw,tcrankshawiz@bluehost.com,Female,240.218.215.50,12/5/2018,41,2503.95 +685,Bryna,Clemmen,bclemmenj0@slate.com,Female,117.149.65.242,6/24/2019,33,2635.47 +686,Fiann,Dipple,fdipplej1@usda.gov,Female,13.222.48.15,5/1/2019,97,4530.95 +687,Hilliary,Nowell,hnowellj2@jigsy.com,Female,237.64.236.63,9/8/2019,4,3931.64 +688,Francene,Perfitt,fperfittj3@upenn.edu,Female,35.17.66.62,3/5/2019,24,4353.24 +689,Adair,Foucher,afoucherj4@google.com,Male,184.228.99.56,5/7/2019,75,3261.23 +690,Evyn,Cristou,ecristouj5@xrea.com,Male,114.91.151.161,7/17/2019,95,3655.93 +691,Carleton,Mooreed,cmooreedj6@walmart.com,Male,17.30.55.141,8/31/2019,66,1486.95 +692,Ashley,Wallage,awallagej7@dyndns.org,Male,214.116.89.237,5/6/2019,17,3179.86 +693,Corney,Healeas,chealeasj8@phoca.cz,Male,36.170.221.28,12/24/2018,29,3068.73 +694,Marabel,Abbado,mabbadoj9@google.nl,Female,56.208.153.166,4/15/2019,4,4988.67 +695,Barr,Gregr,bgregrja@mozilla.com,Male,118.210.102.100,5/28/2019,31,2310.92 +696,Ulrika,Verni,uvernijb@hhs.gov,Female,252.208.223.205,3/13/2019,34,4254.15 +697,Carri,McWilliam,cmcwilliamjc@unblog.fr,Female,244.144.133.38,2/26/2019,57,4082.44 +698,Ciro,Burnet,cburnetjd@simplemachines.org,Male,56.117.3.236,11/7/2019,71,2943.82 +699,Eryn,Lindblom,elindblomje@paginegialle.it,Female,218.110.190.80,10/26/2019,98,3327.13 +700,Tandi,Jenney,tjenneyjf@sciencedirect.com,Female,61.111.94.217,8/9/2019,63,3161.01 +701,Karissa,McGeachy,kmcgeachyjg@themeforest.net,Female,97.151.85.120,3/15/2019,75,2793.19 +702,Daisie,Gosling,dgoslingjh@yale.edu,Female,80.132.185.177,12/24/2018,99,2564.95 +703,Web,Waters,wwatersji@icio.us,Male,138.42.236.158,11/26/2019,12,3133.25 +704,Beulah,Saltrese,bsaltresejj@rakuten.co.jp,Female,111.246.77.69,5/10/2019,85,1562.53 +705,Shea,Bansal,sbansaljk@timesonline.co.uk,Male,45.157.189.79,6/13/2019,64,4095.48 +706,Granger,Maddyson,gmaddysonjl@cdbaby.com,Male,4.174.208.225,10/22/2019,90,2312.31 +707,Frederic,Ferras,fferrasjm@europa.eu,Male,93.89.74.109,4/21/2019,1,2688.0 +708,Terri-jo,Blockwell,tblockwelljn@diigo.com,Female,139.206.39.244,10/28/2019,77,2032.65 +709,Portia,Messum,pmessumjo@cpanel.net,Female,205.8.231.154,7/5/2019,7,3703.36 +710,Fay,Bleakley,fbleakleyjp@fema.gov,Female,51.78.72.116,11/14/2019,97,4827.37 +711,Blayne,Marnane,bmarnanejq@nasa.gov,Male,254.10.160.105,11/17/2019,59,4393.22 +712,Brooke,Dreinan,bdreinanjr@yandex.ru,Male,101.190.49.170,7/13/2019,91,3896.42 +713,Dannie,Butten,dbuttenjs@w3.org,Male,254.183.249.58,7/3/2019,49,4087.49 +714,Niki,Gooch,ngoochjt@huffingtonpost.com,Male,14.126.59.16,2/13/2019,81,3541.85 +715,Penny,Bovis,pbovisju@macromedia.com,Female,194.73.1.154,9/15/2019,22,3343.77 +716,Agna,Wellings,awellingsjv@economist.com,Female,18.191.109.188,6/20/2019,59,3995.96 +717,Kelsi,Binestead,kbinesteadjw@weibo.com,Female,209.183.105.9,6/22/2019,10,2251.08 +718,Lucio,MacLennan,lmaclennanjx@oracle.com,Male,138.238.128.41,6/18/2019,76,4327.17 +719,Leonora,Shailer,lshailerjy@illinois.edu,Female,119.146.115.106,12/20/2018,29,4657.75 +720,Fonsie,O'Doogan,fodooganjz@cbsnews.com,Male,130.108.253.158,8/21/2019,94,1870.33 +721,Stearne,Claire,sclairek0@booking.com,Male,131.59.84.18,4/11/2019,98,3369.19 +722,Maye,Howis,mhowisk1@buzzfeed.com,Female,22.69.128.140,9/8/2019,85,1974.16 +723,Orton,Kiffe,okiffek2@github.com,Male,81.226.255.158,10/22/2019,52,3864.03 +724,Barty,Leadbeater,bleadbeaterk3@amazon.de,Male,208.66.100.248,4/24/2019,28,4214.56 +725,Sidnee,Coxhead,scoxheadk4@cam.ac.uk,Male,62.75.3.110,2/16/2019,8,4882.21 +726,Worden,Quan,wquank5@telegraph.co.uk,Male,86.238.192.197,3/13/2019,3,4136.64 +727,Brad,Marlor,bmarlork6@chron.com,Male,205.102.239.46,1/10/2019,27,3958.67 +728,Jefferson,Fanning,jfanningk7@google.de,Male,139.239.121.50,10/19/2019,26,3356.51 +729,North,Leidecker,nleideckerk8@nyu.edu,Male,240.19.0.156,4/1/2019,27,4866.45 +730,Chrissy,Rounsefull,crounsefullk9@topsy.com,Female,181.133.238.56,12/31/2018,19,1456.66 +731,Jennine,D'eathe,jdeatheka@ow.ly,Female,82.172.76.47,10/8/2019,87,1326.34 +732,Nedda,Hyland,nhylandkb@unesco.org,Female,85.174.186.120,10/9/2019,67,4967.34 +733,Ripley,Bavester,rbavesterkc@facebook.com,Male,200.70.120.11,7/30/2019,67,3364.31 +734,Amandi,Angrove,aangrovekd@hud.gov,Female,51.90.237.193,10/18/2019,98,3962.5 +735,Jandy,Fritchley,jfritchleyke@youtu.be,Female,236.202.35.177,11/17/2019,79,4641.47 +736,Kevin,Tozer,ktozerkf@godaddy.com,Male,92.185.81.191,9/20/2019,75,2652.18 +737,Erinna,Bucke,ebuckekg@hugedomains.com,Female,134.19.86.195,1/16/2019,19,4117.83 +738,Melania,Margach,mmargachkh@pagesperso-orange.fr,Female,57.86.172.205,1/22/2019,34,4369.1 +739,Darryl,Besset,dbessetki@canalblog.com,Female,150.168.219.97,10/15/2019,85,2449.44 +740,Urbano,Loy,uloykj@vistaprint.com,Male,192.95.90.230,1/29/2019,66,1697.74 +741,Shanan,Titcombe,stitcombekk@addtoany.com,Male,78.104.122.110,1/2/2019,31,2712.55 +742,North,Kropp,nkroppkl@huffingtonpost.com,Male,123.193.124.129,7/19/2019,32,2129.1 +743,Dario,Mennithorp,dmennithorpkm@nifty.com,Male,10.142.173.99,11/4/2019,64,2962.06 +744,Sally,Clerk,sclerkkn@youtu.be,Female,67.123.50.70,11/27/2019,32,4948.27 +745,Phillida,Grishkov,pgrishkovko@hatena.ne.jp,Female,105.59.57.150,5/19/2019,78,2513.36 +746,Warren,Gauthorpp,wgauthorppkp@dailymotion.com,Male,109.33.209.101,3/24/2019,74,3859.6 +747,Yurik,McArthur,ymcarthurkq@time.com,Male,177.53.197.246,6/4/2019,25,1927.47 +748,Lucine,Pritchett,lpritchettkr@adobe.com,Female,214.120.212.72,5/5/2019,44,3376.03 +749,Reeba,Facchini,rfacchiniks@fotki.com,Female,62.203.183.86,3/16/2019,29,2413.06 +750,Marys,MacGaughey,mmacgaugheykt@blogger.com,Female,241.223.207.143,7/28/2019,84,2694.2 +751,Abdul,Rollett,arollettku@intel.com,Male,224.183.67.157,5/16/2019,100,3327.64 +752,Lorry,Wolstenholme,lwolstenholmekv@facebook.com,Female,54.19.245.157,4/24/2019,43,4692.53 +753,Kore,Illingworth,killingworthkw@1und1.de,Female,4.3.169.154,11/2/2019,94,2378.36 +754,Mikel,Welbrock,mwelbrockkx@so-net.ne.jp,Male,94.86.96.2,5/16/2019,74,3938.38 +755,Debby,Largan,dlarganky@mozilla.org,Female,99.67.157.53,10/14/2019,62,2417.72 +756,Brana,Wabe,bwabekz@eepurl.com,Female,243.219.60.35,9/27/2019,36,3520.16 +757,Dyana,Dagworthy,ddagworthyl0@statcounter.com,Female,248.115.199.134,1/29/2019,10,1238.39 +758,Jobi,McAndie,jmcandiel1@alibaba.com,Female,76.175.25.123,9/8/2019,27,2305.18 +759,Karlene,Jery,kjeryl2@va.gov,Female,135.147.68.149,10/20/2019,58,1166.14 +760,Reinhold,Lepoidevin,rlepoidevinl3@baidu.com,Male,31.102.77.143,11/13/2019,22,2344.24 +761,Quent,Screen,qscreenl4@opera.com,Male,12.112.10.35,2/10/2019,53,4842.57 +762,Samuel,Lindberg,slindbergl5@github.io,Male,168.90.162.31,12/12/2018,89,1308.19 +763,Haleigh,Raubenheimer,hraubenheimerl6@quantcast.com,Female,105.212.55.253,1/14/2019,37,3535.98 +764,Shela,Croutear,scroutearl7@istockphoto.com,Female,91.117.195.180,2/8/2019,38,3265.27 +765,Kellyann,Capron,kcapronl8@example.com,Female,124.152.40.23,5/29/2019,50,4056.87 +766,Garey,enzley,genzleyl9@latimes.com,Male,90.152.83.190,9/28/2019,97,1906.66 +767,Mick,Schroter,mschroterla@google.fr,Male,7.60.95.15,5/31/2019,3,1395.4 +768,Alfy,Amdohr,aamdohrlb@google.com,Male,224.77.126.110,3/1/2019,50,4548.48 +769,Mirabelle,Staresmeare,mstaresmearelc@netvibes.com,Female,11.204.171.148,1/11/2019,55,4544.46 +770,Opal,Fincken,ofinckenld@paypal.com,Female,163.158.79.29,9/30/2019,16,4021.93 +771,Donielle,Philliphs,dphilliphsle@g.co,Female,141.55.105.178,7/20/2019,49,1131.35 +772,Stephie,Whitaker,swhitakerlf@skyrock.com,Female,225.117.77.187,3/27/2019,10,4871.35 +773,Elisa,Reddell,ereddelllg@cargocollective.com,Female,74.40.71.217,9/11/2019,9,4241.01 +774,Lars,Bunner,lbunnerlh@si.edu,Male,169.187.187.173,3/18/2019,30,4554.14 +775,Travers,Prinnett,tprinnettli@artisteer.com,Male,105.11.246.207,5/19/2019,60,1589.02 +776,Laurens,Held,lheldlj@delicious.com,Male,124.146.44.210,8/19/2019,96,2202.45 +777,Francesco,Florence,fflorencelk@army.mil,Male,220.136.205.22,7/26/2019,20,3108.6 +778,Lorenzo,Sandhill,lsandhillll@cbc.ca,Male,59.175.249.79,9/30/2019,75,1913.25 +779,Eddy,Duchart,educhartlm@blinklist.com,Male,45.9.255.250,9/3/2019,23,2272.21 +780,Melisse,Corpe,mcorpeln@biblegateway.com,Female,177.26.210.63,10/20/2019,52,4203.4 +781,Clementia,Raggett,craggettlo@wikispaces.com,Female,66.66.204.21,10/17/2019,35,3945.21 +782,Constantine,Spaducci,cspaduccilp@upenn.edu,Male,63.181.82.150,8/21/2019,46,2543.36 +783,Durant,Andreix,dandreixlq@desdev.cn,Male,196.76.252.7,9/20/2019,14,4613.73 +784,Dilan,Jesty,djestylr@nature.com,Male,121.131.244.90,3/19/2019,89,4665.71 +785,Geralda,Zotto,gzottols@samsung.com,Female,203.26.209.205,4/15/2019,76,2964.31 +786,Greg,Goodings,ggoodingslt@instagram.com,Male,64.38.244.127,9/12/2019,92,4711.1 +787,Bailey,Stuchberry,bstuchberrylu@indiatimes.com,Male,26.71.81.206,12/16/2018,30,1848.55 +788,Mata,Wilkowski,mwilkowskilv@google.co.uk,Male,155.242.58.56,11/26/2019,85,4335.11 +789,Hamnet,Phillpotts,hphillpottslw@paypal.com,Male,7.182.159.232,6/16/2019,71,1440.95 +790,Dimitry,Capeloff,dcapelofflx@pinterest.com,Male,109.227.224.121,7/10/2019,80,3282.33 +791,Rafaello,Coggles,rcogglesly@prweb.com,Male,111.224.235.85,12/10/2018,16,4340.53 +792,Judith,Witul,jwitullz@issuu.com,Female,175.239.78.176,3/2/2019,1,4375.79 +793,Addy,Symson,asymsonm0@xing.com,Female,21.208.246.221,2/11/2019,82,1009.31 +794,Joey,Troak,jtroakm1@hhs.gov,Male,134.87.130.194,1/28/2019,60,1454.05 +795,Goldi,Currell,gcurrellm2@xinhuanet.com,Female,93.106.48.19,10/16/2019,65,1228.04 +796,Joaquin,Teodori,jteodorim3@github.com,Male,240.116.96.102,7/31/2019,71,1091.62 +797,Rollo,Embling,remblingm4@un.org,Male,56.201.58.245,3/29/2019,20,2170.46 +798,Mina,Blondel,mblondelm5@weibo.com,Female,98.87.116.35,7/18/2019,58,1320.41 +799,Meridel,Aries,mariesm6@technorati.com,Female,142.95.106.58,11/15/2019,87,2705.6 +800,Bret,Perrelle,bperrellem7@360.cn,Male,118.67.219.42,6/16/2019,87,3500.22 +801,Augustine,Hamments,ahammentsm8@oracle.com,Male,55.61.38.103,3/26/2019,8,1526.07 +802,Billie,Roo,broom9@tuttocitta.it,Female,219.152.107.102,3/14/2019,97,3539.6 +803,Susann,Pargiter,spargiterma@umich.edu,Female,147.205.25.119,6/27/2019,22,1160.81 +804,Glennis,Penella,gpenellamb@posterous.com,Female,192.52.234.179,11/2/2019,36,2548.63 +805,Mozelle,Densumbe,mdensumbemc@phpbb.com,Female,72.69.188.204,7/10/2019,51,4208.3 +806,Bernarr,Congrave,bcongravemd@gizmodo.com,Male,54.147.238.56,6/24/2019,10,3573.77 +807,Humfrid,Glauber,hglauberme@adobe.com,Male,88.115.210.97,2/26/2019,18,1504.77 +808,Suzie,Awmack,sawmackmf@com.com,Female,25.246.10.228,9/22/2019,58,1734.63 +809,Tanitansy,McDill,tmcdillmg@apache.org,Female,176.212.121.232,9/10/2019,91,3442.09 +810,Astrid,O'Henery,aohenerymh@cnbc.com,Female,114.120.10.56,5/9/2019,8,3084.41 +811,Pepita,Estrella,pestrellami@1688.com,Female,32.233.56.52,11/12/2019,14,4239.8 +812,Cornie,Jennaway,cjennawaymj@amazon.de,Male,193.210.211.129,6/10/2019,19,3412.2 +813,Barbette,Rudgard,brudgardmk@myspace.com,Female,176.253.137.53,2/4/2019,1,1136.15 +814,Timofei,Donner,tdonnerml@ed.gov,Male,123.83.191.246,3/26/2019,1,1133.51 +815,Vasily,Jeary,vjearymm@nationalgeographic.com,Male,98.99.97.55,5/7/2019,92,1187.51 +816,Jamey,Windsor,jwindsormn@nih.gov,Male,196.125.95.56,6/29/2019,71,3115.9 +817,Evangelina,Gorrie,egorriemo@theglobeandmail.com,Female,35.130.99.82,1/14/2019,79,2252.03 +818,Odie,Titchmarsh,otitchmarshmp@sina.com.cn,Male,172.30.187.143,6/12/2019,63,3327.2 +819,Hestia,Fresson,hfressonmq@hp.com,Female,195.31.239.116,7/16/2019,39,3541.73 +820,Mortimer,Bestwerthick,mbestwerthickmr@microsoft.com,Male,217.124.4.132,10/24/2019,19,4855.38 +821,Chaunce,Hechlin,chechlinms@goo.ne.jp,Male,197.140.52.246,7/29/2019,1,2219.75 +822,Odella,Casson,ocassonmt@sciencedaily.com,Female,40.211.128.59,3/16/2019,93,3085.53 +823,Shellysheldon,Pallent,spallentmu@youtu.be,Male,153.196.220.186,2/19/2019,19,2695.0 +824,Emelyne,Childes,echildesmv@livejournal.com,Female,126.181.2.21,11/6/2019,13,1095.75 +825,Fred,Calf,fcalfmw@chicagotribune.com,Female,240.193.197.180,11/17/2019,79,3914.36 +826,Dag,Mulliss,dmullissmx@4shared.com,Male,238.137.20.149,8/6/2019,4,3539.27 +827,Georgeanna,Pitcock,gpitcockmy@comsenz.com,Female,102.167.151.225,10/12/2019,84,4585.02 +828,Sunny,Panther,spanthermz@unicef.org,Male,151.172.118.190,1/12/2019,91,4343.08 +829,Belita,Alderson,baldersonn0@blogtalkradio.com,Female,137.76.226.221,1/10/2019,42,3569.01 +830,Ame,Forte,aforten1@sourceforge.net,Female,147.157.177.133,1/8/2019,21,1365.56 +831,Timmie,Rodden,troddenn2@businessweek.com,Male,130.254.151.248,3/26/2019,96,1881.36 +832,Ole,Schafer,oschafern3@about.com,Male,127.222.178.16,3/17/2019,17,2401.6 +833,Patty,Cooling,pcoolingn4@seesaa.net,Female,61.215.62.193,2/11/2019,48,2474.66 +834,Collin,Stute,cstuten5@goo.ne.jp,Male,130.45.80.94,9/10/2019,4,3847.7 +835,Yorgo,Swancott,yswancottn6@intel.com,Male,219.62.66.145,2/25/2019,65,2423.66 +836,Ron,Routley,rroutleyn7@spotify.com,Male,56.197.234.81,8/23/2019,33,2148.92 +837,Stefania,McSkin,smcskinn8@dot.gov,Female,98.31.14.146,3/16/2019,62,1990.6 +838,Salem,Lergan,slergann9@usnews.com,Male,15.104.246.221,6/13/2019,38,2449.21 +839,Dunstan,Kenzie,dkenziena@networksolutions.com,Male,87.134.108.52,11/9/2019,44,4224.03 +840,Hunt,Ledamun,hledamunnb@yahoo.com,Male,176.159.246.215,3/10/2019,86,3822.13 +841,Farrand,Callam,fcallamnc@paypal.com,Female,226.107.7.0,8/27/2019,74,2378.51 +842,Nada,Catlin,ncatlinnd@furl.net,Female,47.100.217.78,9/6/2019,80,4344.19 +843,Carlita,Glavis,cglavisne@thetimes.co.uk,Female,51.186.12.78,12/12/2018,10,1226.08 +844,Lianna,McColm,lmccolmnf@smh.com.au,Female,11.59.43.151,12/24/2018,75,2920.03 +845,Darill,Klempke,dklempkeng@bloomberg.com,Male,130.161.53.81,10/30/2019,26,1470.72 +846,Laughton,Whithalgh,lwhithalghnh@booking.com,Male,245.52.162.163,5/13/2019,95,3958.01 +847,Cammie,Izhakov,cizhakovni@admin.ch,Female,124.164.33.27,4/7/2019,43,2040.2 +848,Marline,Duddell,mduddellnj@opensource.org,Female,170.97.255.200,6/14/2019,35,2449.64 +849,Hillier,Caulder,hcauldernk@npr.org,Male,83.220.85.148,8/30/2019,1,3069.76 +850,Coral,Raffles,crafflesnl@friendfeed.com,Female,149.92.2.58,1/20/2019,13,1301.57 +851,Barb,Dudny,bdudnynm@fc2.com,Female,243.249.246.96,2/19/2019,2,4053.62 +852,Arch,Bente,abentenn@mapy.cz,Male,229.210.219.135,9/9/2019,41,4556.35 +853,Alix,Sheriff,asheriffno@jigsy.com,Female,203.28.108.229,1/30/2019,70,2074.89 +854,Vaughn,Schwaiger,vschwaigernp@webmd.com,Male,112.58.20.107,5/25/2019,5,2348.46 +855,Stearn,Linggood,slinggoodnq@multiply.com,Male,247.71.219.146,11/23/2019,5,3348.25 +856,Doralin,Kleinschmidt,dkleinschmidtnr@ca.gov,Female,30.114.11.63,9/21/2019,29,3475.53 +857,Ali,Treweke,atrewekens@xrea.com,Female,181.217.116.253,1/19/2019,50,4184.66 +858,Brandon,Ogger,boggernt@example.com,Male,19.9.219.173,12/21/2018,53,3270.85 +859,Garth,Sterre,gsterrenu@sina.com.cn,Male,7.170.103.142,12/30/2018,60,4285.48 +860,Elberta,Stooke,estookenv@goo.gl,Female,104.12.213.185,4/7/2019,60,1570.75 +861,Winfield,Peacock,wpeacocknw@liveinternet.ru,Male,214.134.25.83,2/21/2019,76,4428.25 +862,Ernest,Allabarton,eallabartonnx@home.pl,Male,148.170.100.93,4/25/2019,54,2410.98 +863,Florette,Pendle,fpendleny@google.co.uk,Female,163.75.98.87,3/3/2019,25,1877.39 +864,Enrica,Smogur,esmogurnz@jiathis.com,Female,212.86.14.17,10/30/2019,90,1736.18 +865,Selle,Meece,smeeceo0@va.gov,Female,216.204.181.172,12/31/2018,9,4254.26 +866,Leighton,Behninck,lbehnincko1@ted.com,Male,128.137.145.34,7/28/2019,8,4817.49 +867,Dallis,Kildahl,dkildahlo2@ucsd.edu,Male,57.50.158.153,11/29/2019,80,3940.06 +868,Carr,McKeachie,cmckeachieo3@cbsnews.com,Male,155.169.255.5,10/25/2019,92,1248.52 +869,Gwendolin,Twinborough,gtwinborougho4@engadget.com,Female,126.69.215.135,10/31/2019,60,1790.54 +870,Katha,Mains,kmainso5@wired.com,Female,108.80.188.101,9/5/2019,90,1953.27 +871,Anabella,Hawkridge,ahawkridgeo6@elegantthemes.com,Female,194.91.70.106,11/7/2019,33,1067.92 +872,Carney,Moxon,cmoxono7@about.me,Male,243.35.248.83,5/25/2019,46,3541.93 +873,Cynthy,Minette,cminetteo8@unesco.org,Female,198.115.128.127,11/13/2019,17,1202.6 +874,Humfrey,Doogue,hdoogueo9@businesswire.com,Male,118.100.123.208,9/24/2019,21,1883.88 +875,Rosabella,Frowen,rfrowenoa@who.int,Female,168.21.241.150,3/26/2019,12,3747.05 +876,Inger,Benoiton,ibenoitonob@bing.com,Female,62.18.91.144,2/5/2019,55,3668.36 +877,Aldus,McHardy,amchardyoc@google.com,Male,217.43.238.237,2/7/2019,25,3733.76 +878,Thea,Klemke,tklemkeod@aboutads.info,Female,13.193.63.194,9/1/2019,15,2199.75 +879,Nathaniel,Alesio,nalesiooe@prweb.com,Male,45.77.38.94,8/21/2019,88,1398.05 +880,Jo-ann,Thring,jthringof@plala.or.jp,Female,67.45.206.82,3/28/2019,23,1119.69 +881,Betteann,Andreone,bandreoneog@google.it,Female,28.46.236.211,9/21/2019,68,2637.19 +882,Leland,Boulding,lbouldingoh@booking.com,Male,223.0.133.33,6/26/2019,95,1645.04 +883,Rosalia,Sieve,rsieveoi@opera.com,Female,146.244.116.76,11/14/2019,20,3684.84 +884,Pietra,Lillyman,plillymanoj@sphinn.com,Female,241.84.132.180,1/28/2019,100,4262.03 +885,Cosme,Guest,cguestok@chronoengine.com,Male,200.190.189.24,4/16/2019,70,2178.29 +886,Wallie,Telega,wtelegaol@ebay.com,Male,121.243.189.159,4/30/2019,52,1182.3 +887,Lishe,Skillett,lskillettom@umn.edu,Female,195.58.225.2,3/5/2019,71,2012.1 +888,Arleta,Manley,amanleyon@linkedin.com,Female,51.84.250.183,10/15/2019,15,4912.75 +889,Ravi,Willder,rwillderoo@clickbank.net,Male,172.59.196.252,11/3/2019,61,1209.86 +890,Averell,Towner,atownerop@twitpic.com,Male,39.252.161.23,5/12/2019,64,4531.62 +891,Patrice,Dedman,pdedmanoq@marriott.com,Male,210.154.94.25,6/13/2019,74,4735.98 +892,Shem,Girtin,sgirtinor@is.gd,Male,104.118.74.161,11/10/2019,100,4267.43 +893,Francyne,Bransby,fbransbyos@g.co,Female,44.30.38.123,2/4/2019,46,4181.62 +894,Christye,Farbrace,cfarbraceot@hibu.com,Female,112.150.190.191,2/16/2019,23,2095.36 +895,Nadean,Given,ngivenou@spiegel.de,Female,151.241.243.171,4/25/2019,81,2443.82 +896,Cesya,Clutheram,cclutheramov@smh.com.au,Female,165.200.216.167,7/4/2019,31,3937.84 +897,Bax,Goodwins,bgoodwinsow@nhs.uk,Male,11.52.15.206,4/9/2019,91,2252.61 +898,Lewiss,Lamblot,llamblotox@hubpages.com,Male,47.131.77.115,8/30/2019,24,2400.36 +899,Red,Wick,rwickoy@photobucket.com,Male,83.184.219.168,10/21/2019,15,4178.01 +900,Salvatore,Pimblett,spimblettoz@cmu.edu,Male,167.151.230.214,5/15/2019,42,1341.9 +901,Hughie,Bryceson,hbrycesonp0@princeton.edu,Male,196.234.12.37,6/21/2019,62,1336.58 +902,Clayson,Hankinson,chankinsonp1@over-blog.com,Male,23.197.178.40,8/12/2019,99,1615.05 +903,Lilas,Liccardo,lliccardop2@wisc.edu,Female,122.30.29.218,11/8/2019,18,2646.47 +904,Orville,Durrant,odurrantp3@clickbank.net,Male,72.40.168.148,8/12/2019,37,1473.73 +905,Orrin,Skelly,oskellyp4@a8.net,Male,105.220.135.4,5/6/2019,50,1525.97 +906,Tallou,Sandyford,tsandyfordp5@homestead.com,Female,227.225.220.181,2/6/2019,58,4786.43 +907,Quincy,Roseman,qrosemanp6@biglobe.ne.jp,Male,54.163.190.213,7/1/2019,24,4037.23 +908,Tabbie,Kiraly,tkiralyp7@newsvine.com,Male,224.190.131.109,3/13/2019,100,1323.77 +909,Sandy,Matskevich,smatskevichp8@simplemachines.org,Female,2.231.87.52,12/29/2018,82,3517.0 +910,Duane,Dye,ddyep9@nasa.gov,Male,104.68.110.228,10/11/2019,72,3764.03 +911,Vassily,McNeill,vmcneillpa@eepurl.com,Male,224.20.3.98,5/2/2019,93,2130.67 +912,Donalt,Astlet,dastletpb@chron.com,Male,114.210.201.171,5/7/2019,75,2025.04 +913,Nickey,Stobie,nstobiepc@icio.us,Male,185.166.110.244,4/16/2019,71,1045.07 +914,Alejandra,Evenett,aevenettpd@spotify.com,Female,53.71.229.172,3/31/2019,68,3272.6 +915,Malia,Turpey,mturpeype@slashdot.org,Female,100.204.158.195,7/24/2019,23,1887.0 +916,Sancho,Coy,scoypf@unicef.org,Male,172.2.26.180,7/3/2019,57,3139.02 +917,Gabey,Skoyles,gskoylespg@epa.gov,Female,194.148.9.101,3/13/2019,84,2292.4 +918,Bertrando,Ivankin,bivankinph@fda.gov,Male,118.157.82.229,9/22/2019,3,1287.51 +919,Tannie,MacCosty,tmaccostypi@digg.com,Male,72.202.202.95,12/24/2018,82,2588.07 +920,Ranee,Bessent,rbessentpj@imgur.com,Female,127.24.169.67,11/10/2019,54,3444.15 +921,Tiffanie,Trawin,ttrawinpk@marketwatch.com,Female,17.85.226.126,5/24/2019,65,2725.46 +922,Almeria,Gillan,agillanpl@geocities.com,Female,122.181.145.74,11/21/2019,9,4518.15 +923,Myron,Cornuau,mcornuaupm@fema.gov,Male,119.235.159.166,8/23/2019,71,2151.88 +924,Julie,Garmston,jgarmstonpn@istockphoto.com,Female,239.238.200.150,1/14/2019,64,2838.43 +925,Piggy,Gobel,pgobelpo@fastcompany.com,Male,118.158.61.149,2/6/2019,34,3108.47 +926,Gib,Featherstone,gfeatherstonepp@infoseek.co.jp,Male,90.82.112.24,7/12/2019,72,1446.28 +927,Ezri,Roome,eroomepq@bandcamp.com,Male,162.179.9.53,11/8/2019,89,4420.45 +928,Mattias,Bilbie,mbilbiepr@jugem.jp,Male,26.98.219.102,6/29/2019,53,3055.7 +929,Tremain,Puleston,tpulestonps@newsvine.com,Male,57.241.217.97,2/19/2019,74,4113.34 +930,Penrod,Human,phumanpt@amazon.co.jp,Male,191.23.222.227,8/12/2019,14,3914.95 +931,Helyn,Ladell,hladellpu@a8.net,Female,20.100.134.221,4/17/2019,94,2293.8 +932,Enid,Rough,eroughpv@imageshack.us,Female,107.222.42.7,6/17/2019,21,1914.06 +933,Eloise,Rumbold,erumboldpw@meetup.com,Female,43.79.13.253,12/16/2018,59,4639.52 +934,Sol,Merricks,smerrickspx@ow.ly,Male,123.39.195.179,11/1/2019,57,2899.49 +935,Mahmud,Keeney,mkeeneypy@wikispaces.com,Male,72.102.171.49,3/11/2019,6,4225.54 +936,Asia,Bartlosz,abartloszpz@mtv.com,Female,243.106.58.70,12/21/2018,69,1884.34 +937,Christian,Stirman,cstirmanq0@discuz.net,Female,107.80.178.46,8/29/2019,55,2956.9 +938,Alfredo,Adnams,aadnamsq1@washington.edu,Male,37.204.15.227,12/6/2018,15,2349.12 +939,Rudy,Diggins,rdigginsq2@nsw.gov.au,Male,136.105.142.55,10/22/2019,56,4720.66 +940,Valaria,Paulus,vpaulusq3@etsy.com,Female,109.100.3.110,1/2/2019,26,1610.79 +941,Conny,Roels,croelsq4@mozilla.com,Female,208.213.210.29,1/31/2019,54,4096.32 +942,Bucky,Kennan,bkennanq5@pinterest.com,Male,172.225.189.229,8/19/2019,87,4628.59 +943,Iago,Samwyse,isamwyseq6@github.io,Male,89.18.109.205,11/10/2019,60,4746.45 +944,Pietrek,Gori,pgoriq7@reverbnation.com,Male,92.121.178.154,11/5/2019,33,1692.9 +945,Tabina,Kears,tkearsq8@theglobeandmail.com,Female,144.45.170.150,10/3/2019,52,3611.17 +946,Wendye,Sollis,wsollisq9@walmart.com,Female,238.248.64.91,5/1/2019,5,3395.62 +947,Rafferty,Waycot,rwaycotqa@yellowbook.com,Male,56.12.230.243,10/22/2019,65,3819.8 +948,Bendix,Heamus,bheamusqb@adobe.com,Male,249.250.105.13,1/13/2019,1,3871.34 +949,Elfrieda,Gierardi,egierardiqc@uiuc.edu,Female,70.40.147.33,5/15/2019,33,3013.33 +950,Malachi,Sweet,msweetqd@soup.io,Male,45.89.78.169,12/12/2018,80,3668.82 +951,Lanae,Pollendine,lpollendineqe@nasa.gov,Female,95.61.177.183,2/13/2019,1,4889.44 +952,Ryley,Lawry,rlawryqf@scientificamerican.com,Male,125.229.131.211,1/14/2019,2,3286.34 +953,Terri-jo,Jamblin,tjamblinqg@epa.gov,Female,188.157.97.186,6/5/2019,47,2943.87 +954,Leland,Hildred,lhildredqh@scribd.com,Male,225.216.250.143,6/17/2019,56,4864.96 +955,Gabe,Olyff,golyffqi@nba.com,Male,132.213.9.245,4/23/2019,98,1702.76 +956,Madelena,Astling,mastlingqj@samsung.com,Female,30.58.29.118,12/18/2018,84,4673.11 +957,Reinaldo,Kitchingman,rkitchingmanqk@csmonitor.com,Male,188.111.118.234,5/23/2019,75,4450.61 +958,Padgett,Spacey,pspaceyql@google.de,Male,36.237.235.122,11/27/2019,56,1279.87 +959,Rachel,Chezelle,rchezelleqm@domainmarket.com,Female,96.79.189.100,11/24/2019,91,3136.13 +960,Pollyanna,Eggerton,peggertonqn@nsw.gov.au,Female,18.201.58.237,12/19/2018,20,3493.5 +961,Marris,Wincott,mwincottqo@bandcamp.com,Female,184.31.11.215,6/12/2019,8,1515.01 +962,Shae,Mair,smairqp@friendfeed.com,Male,62.3.75.126,5/26/2019,17,1886.62 +963,Rik,Citrine,rcitrineqq@ameblo.jp,Male,185.79.147.211,7/2/2019,34,4809.78 +964,Clare,Bohey,cboheyqr@wunderground.com,Female,107.176.103.42,5/11/2019,88,4309.81 +965,Hayes,Brushfield,hbrushfieldqs@i2i.jp,Male,2.5.51.42,11/26/2019,76,1551.99 +966,Misty,Domico,mdomicoqt@google.pl,Female,39.47.212.202,12/6/2018,70,4670.57 +967,Arthur,Elstub,aelstubqu@independent.co.uk,Male,176.248.255.191,12/30/2018,46,2705.52 +968,Berkeley,Hapgood,bhapgoodqv@technorati.com,Male,178.208.39.27,10/14/2019,22,3380.97 +969,Brose,Kynton,bkyntonqw@arstechnica.com,Male,46.20.210.218,3/5/2019,56,4943.64 +970,Tarah,Deguara,tdeguaraqx@netvibes.com,Female,218.157.37.87,10/15/2019,52,4735.44 +971,Lorie,Tooting,ltootingqy@e-recht24.de,Female,180.29.70.96,5/13/2019,2,3053.29 +972,Consuela,Lyndon,clyndonqz@nature.com,Female,33.99.22.111,10/26/2019,16,1782.96 +973,Heloise,Loges,hlogesr0@ebay.co.uk,Female,65.91.147.32,8/6/2019,91,3905.33 +974,Lamond,Hamnet,lhamnetr1@tripod.com,Male,59.5.218.194,3/21/2019,78,3783.64 +975,Matilda,Clemencet,mclemencetr2@livejournal.com,Female,50.223.87.130,10/4/2019,23,2543.68 +976,Bayard,Roskruge,broskruger3@sitemeter.com,Male,69.240.99.87,7/3/2019,80,1587.29 +977,Benn,Jirak,bjirakr4@delicious.com,Male,128.35.209.194,12/2/2018,44,3277.87 +978,Nahum,Attle,nattler5@tiny.cc,Male,112.43.114.140,6/8/2019,7,2273.81 +979,Evangeline,Ribey,eribeyr6@google.fr,Female,81.105.199.64,3/29/2019,67,4510.15 +980,Ryann,Ellul,rellulr7@ning.com,Female,240.217.190.216,12/13/2018,84,1668.81 +981,Ermina,Venn,evennr8@de.vu,Female,133.154.240.217,2/13/2019,97,1524.47 +982,Toby,Durward,tdurwardr9@state.tx.us,Male,121.122.162.100,6/18/2019,93,2462.12 +983,Frederic,Scraney,fscraneyra@gnu.org,Male,169.185.152.85,9/1/2019,5,4899.03 +984,Marty,Phebey,mphebeyrb@tripadvisor.com,Male,168.107.107.230,12/6/2018,84,4793.66 +985,Harris,Lockney,hlockneyrc@nifty.com,Male,93.129.49.110,8/4/2019,49,1798.63 +986,Eugen,Leverton,elevertonrd@instagram.com,Male,159.232.54.24,9/21/2019,60,3305.1 +987,Gabie,Beardwood,gbeardwoodre@theatlantic.com,Male,20.18.125.82,1/24/2019,5,1946.11 +988,Myrwyn,Pesterfield,mpesterfieldrf@scientificamerican.com,Male,145.133.177.91,8/13/2019,25,3808.27 +989,Mercy,Chadd,mchaddrg@51.la,Female,185.164.11.233,6/3/2019,40,4001.54 +990,Cornelle,Conford,cconfordrh@behance.net,Female,21.225.190.101,1/23/2019,37,3044.81 +991,Maynord,Till,mtillri@youtube.com,Male,152.132.239.240,7/13/2019,100,1128.62 +992,Evelin,Dmitrichenko,edmitrichenkorj@weibo.com,Male,209.57.214.249,7/17/2019,97,1964.24 +993,Quincy,Rupel,qrupelrk@github.io,Male,64.185.162.129,7/17/2019,98,3247.38 +994,Althea,Ternault,aternaultrl@hao123.com,Female,67.166.119.252,9/5/2019,71,1679.32 +995,Tracy,Usmar,tusmarrm@archive.org,Female,218.147.181.108,4/29/2019,13,4937.95 +996,Frank,Thebeaud,fthebeaudrn@phpbb.com,Male,80.246.35.156,3/21/2019,91,3229.53 +997,Kerk,Feathersby,kfeathersbyro@i2i.jp,Male,216.252.23.125,4/2/2019,38,2610.64 +998,Brigid,Worvell,bworvellrp@cnn.com,Female,48.50.178.158,5/19/2019,35,1974.9 +999,Ike,Van der Merwe,ivandermerwerq@craigslist.org,Male,103.61.116.181,8/14/2019,56,2115.14 +1000,Mark,Dallison,mdallisonrr@cdc.gov,Male,187.245.203.40,8/8/2019,73,1286.22 diff --git a/scripts/accum_pattern_multiple-scrabble.py b/scripts/accum_pattern_multiple-scrabble.py new file mode 100644 index 0000000..8fd9a4e --- /dev/null +++ b/scripts/accum_pattern_multiple-scrabble.py @@ -0,0 +1,30 @@ + # -*- coding: utf-8 -*- +""" +Created on Thu Jun 6 16:11:59 2019 + +@author: http://ice-web.cc.gatech.edu/ce21/1/static/audio/static/pip/Dictionaries/dictionary_accum.html#scarlet.txt +""" + +f = open('study_in_scarlet.txt', 'r', encoding='utf8') +txt = f.read() +f.close() +# now txt is one long string containing all the characters +x = {} # start with an empty dictionary +for c in txt: + if c not in x: + # we have not seen this character before, so initialize a counter for it + x[c] = 0 + + #whether we've seen it before or not, increment its counter + x[c] = x[c] + 1 + +# build a second dictionary, containing the scrabble scores for individual characters +# calculate the scrabble score of your text +letter_values = {'a': 1, 'b': 3, 'c': 3, 'd': 2, 'e': 1, 'f':4, 'g': 2, 'h':4, 'i':1, 'j':8, 'k':5, 'l':1, 'm':3, 'n':1, 'o':1, 'p':3, 'q':10, 'r':1, 's':1, 't':1, '':1, 'v':8, 'w':4, 'x':8, 'y':4, 'z':10} + +tot = 0 +for y in x: + if y in letter_values: + tot = tot + letter_values[y] * x[y] + +print('total scrabble score = ', tot) diff --git a/scripts/accum_pattern_multiple.py b/scripts/accum_pattern_multiple.py new file mode 100644 index 0000000..2cbaedd --- /dev/null +++ b/scripts/accum_pattern_multiple.py @@ -0,0 +1,22 @@ +h# -*- coding: utf-8 -*- +""" +Created on Thu Jun 6 15:31:20 2019 + +@author: http://ice-web.cc.gatech.edu/ce21/1/static/audio/static/pip/Dictionaries/dictionary_accum.html#scarlet.txt +""" + +f = open('study_in_scarlet.txt', 'r', encoding="utf8") +txt = f.read() +f.close() +# now txt is one long string containing all the characters +x = {} # start with an empty dictionary +for c in txt: + if c not in x: + # we have not seen this character before, so initialize a counter for it + x[c] = 0 + + #whether we've seen it before or not, increment its counter + x[c] = x[c] + 1 + +for c in x.keys(): + print(c + ": " + str(x[c]) + " occurrences") \ No newline at end of file diff --git a/scripts/accum_pattern_single.py b/scripts/accum_pattern_single.py new file mode 100644 index 0000000..ec0983f --- /dev/null +++ b/scripts/accum_pattern_single.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 6 14:47:11 2019 + +@author: http://ice-web.cc.gatech.edu/ce21/1/static/audio/static/pip/Iteration/iteration.html +""" + +nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +accum = 0 +for w in nums: + accum = accum + w + print(accum) + diff --git a/scripts/accum_pattern_single_text.py b/scripts/accum_pattern_single_text.py new file mode 100644 index 0000000..7e7c546 --- /dev/null +++ b/scripts/accum_pattern_single_text.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 6 15:02:14 2019 + +@author: http://ice-web.cc.gatech.edu/ce21/1/static/audio/static/pip/Dictionaries/dictionary_accum.html#scarlet.txt +""" + +#f = open('study_in_scarlet.txt', 'r', encoding="utf8") +f = open('Data\patients.txt', 'r') +txt = f.read() +# now txt is one long string containing all the characters +t_count = 0 #initialize the accumulator variable + +# check the number of occurences of t +for ch in txt: + if ch == 't': + t_count = t_count + 1 #increment the counter +print("t: " + str(t_count) + " occurrences") +f.close() + + +# a more elaborted loop for 2 characters +# a lot of elif's required to test for all 26 characters +t_count = 0 #initialize the accumulator variable +s_count = 0 # initialize the s counter accumulator as well +for ch in txt: + if ch == 't': + t_count = t_count + 1 #increment the t counter + elif ch == 's': + s_count = s_count + 1 +print("t: " + str(t_count) + " occurrences") +print("s: " + str(s_count) + " occurrences") +f.close() diff --git a/scripts/actors.csv b/scripts/actors.csv new file mode 100644 index 0000000..b82ba4c --- /dev/null +++ b/scripts/actors.csv @@ -0,0 +1,5 @@ +First Name,Last Name,Date of Birth +Tom,Cruise,"July 3, 1962" +Bruce,Willis,"March 19, 1955" +Morgan,Freeman,"June 1, 1937" +John,Wayne,"May 26, 1907" \ No newline at end of file diff --git a/scripts/basic_datatypes.ipynb b/scripts/basic_datatypes.ipynb new file mode 100644 index 0000000..ac297f9 --- /dev/null +++ b/scripts/basic_datatypes.ipynb @@ -0,0 +1,400 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "markdown", + "source": "# Built-in data types", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\nfrom traceback import print_exc", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Key concepts in programming\n\n- Variables (integers, strings, dates, etc.)\n- Flow control (if then, loop, etc.)\n- Functions (list of steps the code will follow)", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "## built-in data types\n\n| Type | Meaning | Example |\n|------|---------|---------|\n| int | integers (whole numbers) | a = 2 |\n| float | floating point numbers (real numbers) | a = 2.0 |\n| complex | complex numbers with a real and imaginary part | a = 1.2 + 3j |\n| bool | boolean: True/False values | a = True |\n| str | string: characters or text | a = 'abc' |", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "## integer\n- Most basic numerical type. \n- Any number without a decimal point is an integer.\n- Note: Python integers are variable-precision, not limited as in C, Matlab to 4 or 8 bytes.\n - see https://rushter.com/blog/python-integer-implementation/", + "metadata": {} + }, + { + "cell_type": "code", + "source": "a = 2\nb = 2**200\nprint('type of a', type(a))\nprint('type of b', type(b))\nprint('a: ', a)\nprint('b: ', b)\nprint('size of a:', a.__sizeof__(), ' bits')\nprint('size of b:', b.__sizeof__(), ' bits')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## floating point \n\n- The floating-point type can store fractional numbers. \n- standard decimal notation, or in exponential notation\n * ´a = 0.000005´\n * ´b = 5e-6´\n - Note: limited precision, never rely on exact equality tests with floating-point values.\n0.1 + 0.2 == 0.3\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "a = 0.000005\nb = 5.08e-6\nprint(a, b)\nprint('type', type(a))\nprint('type', type(b))", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "comparisons with float numbers can be tricky\n\ndue to the limited precision of representing floats, never rely on exact equality tests with floating-point values. 0.1 + 0.2 == 0.3", + "metadata": {} + }, + { + "cell_type": "code", + "source": "a = 0.1\nb = 0.2\nprint('a + b =', a + b)\nc = 0.3\nprint('test a + b == c: ', (a + b) == c)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "A better way to cmpare floats: check the absolute difference\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "epsilon = 0.00001\nx = 0.1 + 0.2\ny = 0.3\nprint(abs(x - y) < epsilon) ", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "**Optional:** Get an idea of the binary representation of a float: you can convert the float to an integer using the int.from_bytes() function, and then convert that integer to binary with the bin() function.\n ", + "metadata": {} + }, + { + "cell_type": "code", + "source": "import struct\n\nx = 0.1\nprint(x.hex())\npacked = struct.pack('f', x)\ninteger = int.from_bytes(packed, byteorder='big')\nbinary = bin(integer)\nprint(binary)\ny = x\n\n# precision needed beyond 16th digit!\nx = 0.10000000000000001\nprint(x.hex())\npacked = struct.pack('f', x)\ninteger = int.from_bytes(packed, byteorder='big')\nbinary = bin(integer)\nprint(binary)\n\nprint(x==y)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "In the context of programming and numerical computation, “machine epsilon” refers to the smallest representable number such that 1.0 + epsilon is not equal to 1.0. It represents the upper bound on the relative error due to rounding in floating point arithmetic.\n\nMachine epsilon is a measure of precision in the representation of real numbers in a computer. It varies between systems and is specific to the floating-point format used by the system.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "import sys\nepsilon = sys.float_info.epsilon\nprint(epsilon)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## complex \n- A complex number consists of 2 doubles\n- It accepts either `J` or `j` but the numerical value of the imaginary part must immediately precede it. If the imaginary part is a variable the 1 must be present.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "a = 7.86\nc1 = complex(1, 2)\nc2 = 3 + 5.3j\nprint('type: ', type(c1))\nprint('dir: ', dir(c1))\nc1.imag\nc1.real\nc3 = 2.3 + a*1j\n#c3 = 2.3 + a*j\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## boolean\n- Simple type with two possible values: True and False\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "result = (4 > 5)\nprint('result: ', result)\nprint('type: ', type(result))", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "a = 2.3\nb = 3.4\nc = bool(a*b)\nprint(c)\nd = bool(0*a)\nprint(d)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## type conversion\nIf a variable is of one type but it needs to be of a different type, it is necessary to do a type conversion aka a cast.\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "i = 6\nr = float(i)\nprint('r: ', r)\nii = int(3.14)\nprint('ii: ', ii)\ns = str(r)\nprint('type s: ', type(s))\nprint('s: ', s)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## string\n\n(some inspiration from http://www.cs.cornell.edu/courses/cs1110/2019fa/lectures/lecture5/presentation-05.pdf)\n\n- A string is a (ordered) sequence of characters\n- Created with single ‘ or double quotes “\n - 'ab cd' (' preferred)\n - \"ab cd\"\n - slicing\n- immutable: cannot be changed", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# '012345678901'\ns = 'Hello World!'\nprint(s)\nprint(id(s))\nprint('s[0] ', s[0])\nprint('s[2:] ', s[2:])\nprint('s[2:4] ', s[2:4])\nprint('s[2:8:1] ', s[2:8:1])\nprint('s[2:8:2] ', s[2:8:2])\n\n# assign a new value\ns = 'Where are you?'\nprint(s)\nprint(id(s))\ns[7] = 'x'\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### string concatenation and replication\n\nconcatenation of string variables or constants using the + operator\n\nreplication: multiply a string by a number\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "a = 'John'\nb = 'Mary'\nc = a + b\nprint(c)\nc_bis = a + ' ' + b\nprint(c_bis)\n\n# add a number\nd = a + str(4.5)\nprint(d)\ne = a*4+b*2\nprint(e)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### strings and Methods \n\n`rstrip`\n\n- Getting rid of line endings: `rstrip('\\r\\n')`\n- Method will strip all combinations of \\r and \\n from right end of string\n- Similar methods:\n - `lstrip`: strips from left end of string\n - `strip`: strips from both ends of string\n- No arguments, strips: space, \\t, \\r, \\n, …\n- These methods do not modify the original string, instead they return a new string that has been altered\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "str1 = 'this is a string'\nprint(dir(str1))", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "str1.capitalize()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "my_str_1 = 'this is my string,\\t with some text in it \\n More text on a next line \\n'\ndir(my_str_1)\nprint(my_str_1)\nprint(my_str_1.rstrip())", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "`split`\n\nSplitting string: `split()` returns list of strings\n- no argument: split on (multiple) whitespace\n- otherwise, split on provided string\n- limit number of splits by providing extra argument\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "my_str_1 = 'this is my string,\\t with some text in it \\n More text on a next line \\n'\nprint(my_str_1)\nmy_str_split_1 = my_str_1.split()\nprint(my_str_split_1)\nmy_str_split_2 = my_str_1.split(',')\nprint(my_str_split_2)\n\nmy_str_3 = 'end 1: 2013-03-28 03:05:57'\n# split on :, but keep the time format!\nmy_str_split_3 = my_str_3.split(':', 1)\nprint(my_str_split_3)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "my_long_string = ' this is a nice piece of text for you '\nmy_words = my_long_string.split()\nprint(my_words)\n\n# split on a specified character\nmy_words_bis = my_long_string.split('i')\nprint(my_words_bis)\n\n#%% putting things together\nnew_word = ' '.join(my_words_bis).strip()\nprint(new_word)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "More methods: is\n isupper\n islower\n isspace\n isdigit\n isalpha", + "metadata": {} + }, + { + "cell_type": "code", + "source": "print('ABC'.isupper())\nprint('A19'.isupper())\nprint('Abc'.isupper())\nprint('19'.isupper())\nmy_str_1 = 'this is my string,\\t with some text in it \\n More text on a next line \\n'\nprint(my_str_1.isalpha())\nprint(my_str_1.isalnum())", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### searching and replacing\n\n- does a string contain a substring: `in`\n\n- search: `index` or `find`\n - find returns -1 when the substring is not found\n - only for strings\n - index will return an error\n - also for lists and tuples\n- Function `len()` computes str length \n- replace with `replace`\n \nMake combinations\n- cut to pull out parts\n- glue to create new strings", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# substring in string\nprint('ab' in 'ABCD')\nprint('ab' in 'ABCDab')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# extract information between braces\nstr1 = ' this is a string containing (some) text'\n# find the first occurence of '('\nstart_brc = str1.index('(')\n# cut from the first brace\ntail = str1[start_brc+1:]\n# find the first occurence of ')'\nend_brc = tail.index(')')\ntext = tail[:end_brc]\nprint('extracted text: ', text)\nprint('len(str1) :', len(str1))\nprint(str1.replace('is', 'as'))\nstr1 = str1.replace('is', 'was')\nprint(str1)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# '012345678901'\ns = 'Hello World!'\nprint('s[0] ', s[0])\nprint('s[2:] ', s[2:])\nprint('s[2:4] ', s[2:4])\nprint('s[2:8:1] ', s[2:8:1])\nprint('s[2:8:2] ', s[2:8:2])\nprint('s[:4] ', s[:4])\n\nprint('s[:] ', s[:])\nprint('s[-1] ', s[-1])\nprint('s[8:4:-1] ', s[8:4:-1])\nprint('s[:4:-1] ', s[:4:-1])\nprint('s[8::-1] ', s[8::-1])\nprint('s[::-1] ', s[::-1])", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "small_str_1 = ' small'\nsmall_str_2 = ' part'\nconcat_1 = small_str_1 + small_str_2\nprint('concat_1: ', concat_1)\nconcat_2 = 3*small_str_1\nprint('concat_2: ', concat_2)", + "metadata": { + "scrolled": true, + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "str1 = 'help'\nstr2 = 'me'\na1 = str1 + str2\nprint(a1)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "print(str1*3)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## format output\n\n### printf-style formatting: \nThis is similar to the formatting used in C’s printf function. It’s less commonly used in modern Python code.\n\n### str.format(): \nThis method is more versatile and can be used in Python 2.7 and above.\n\n### string Interpolation (f-strings): \nAvailable since Python 3.6\nF-string is a string literal that is prefixed with `f` or `F`. These strings may contain replacement fields (delimited by curly braces {} – fill out the braces). F-string is evaluated at run time.\n\nFile: fstring_01.py\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "name = 'Peter'\nage = 23\n\nprint('%s is %d years old' % (name, age)) # printf style\nprint('{} is {} years old'.format(name, age)) # .format\nprint(f'{name} is {age} years old') # f-string", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "fnum = 2007.12345\nprint(f\"Simple = {fnum}\")\nprint(f\"Decimal Places specified = {fnum:.2f}\")\nprint(f\"Significant Figures={fnum:.3g}\")", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## character\n\n`ord()` takes a string argument of a single Unicode character and returns its integer Unicode code point value.\n\n`chr()` function takes integer argument and returns the string representing a character.\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "print(ord('a'))\n\nprint(chr(98))", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## docstring\n\nDocumentation strings or “docstrings” use a special form of comment.\nThe lines are enclosed in triple double quotes \n\"\"\" \"\"\"\n- Everything within triple double quotes is treated as a literal string and a comment, including line breaks.\n- Docstrings are placed at the top of program units, just under the declaration of the unit name (if present). \n- If they are correctly placed, certain automated tools are available to display the documentation.", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "### None\n\n`None` is the equivalent of null in C.\n\nWhen to use? Often you want to perform an action that may or may not work. Using `None` is one way you can check the state of the action later.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "a=None\nprint(id(a))\nprint(type(a))\n\nr_v = print('abc')\nprint(r_v)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/basic_syntax.ipynb b/scripts/basic_syntax.ipynb new file mode 100644 index 0000000..f2b35bc --- /dev/null +++ b/scripts/basic_syntax.ipynb @@ -0,0 +1,292 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Some basic Python syntax\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\n", + "from traceback import print_exc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check:\n", + "\n", + "https://jakevdp.github.io/WhirlwindTourOfPython/02-basic-python-syntax.html\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Comment\n", + "Comments are marked by `#`\n", + "Anything on the line following the hash sign is ignored by the interpreter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#\n", + "# some comments\n", + "#\n", + "x = 2 # assign x a value of 2\n", + "\n", + "# print the value of x\n", + "\n", + "print(x) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Statement\n", + "\n", + "A statement is one complete “sentence” in the language. It contains one complete instruction. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 2 + 1\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Continuation\n", + "\n", + "`\\` marker is a continuation line" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "a = 8\n", + "x = 1 + 2 + 3 + 4 +\\\n", + " 5 + 6 + 7 + 8\n", + "print('x = ', x)\n", + "%who" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `;`\n", + "Semicolon `;` can optionally terminate a statement (discouraged)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "lower = []; upper = []\n", + "%whos" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%who" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Blocks\n", + "\n", + "Statements can be grouped into **blocks**. \n", + "\n", + "a **block of code** is a set of statements that should be treated as a unit (meant to be executed together).\n", + "\n", + "* Structures that introduce a block end with a colon `:`\n", + "* Blocks are indicated by **indentation level**.\n", + "\n", + "Indentation is used to define the level of a block of code. This is different from many other programming languages, which often use braces {} or keywords.\n", + "\n", + "Indent each block by however many spaces you wish, but each block level must be indented by exactly the same number. \n", + "* Do not use tabs.\n", + "* Some editors (e.g. Spyder) will automatically indent the next statement to the same level as the one before it.\n", + "* The Python standard is to use four white spaces to indent code.\n", + "\n", + "\n", + "Some key points:\n", + "\n", + "* **Indentation matters**: In Python, indentation is not just for readability. It determines how statements are grouped together.\n", + "* **Consistent indentation**: You must use the same amount of indentation for every line in the same block. This can be any number of spaces or tabs, but spaces are preferred.\n", + "* **Blocks can contain other blocks**: If a statement like `if`, `for`, or `while` has its own block, it can contain other blocks. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "if 5 > 2:\n", + " print(\"Five is greater than two!\")\n", + "else:\n", + " print(\"Five is not greater than two!\")\n", + " \n", + "if False:\n", + " print(\"I'm a code block\")\n", + " print(\"Look at the indent\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from math import sqrt\n", + "\n", + "# calculate the sum of square root of even numbers\n", + "my_numbers = [1, 4, 3, 4, 16, 9]\n", + "sum = 0\n", + "for i in my_numbers:\n", + " if i%2 == 0:\n", + " sum = sum + sqrt(i)\n", + " print(sum)\n", + " print('final sum = ',sum)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!notepad check_whitespace.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "!python check_whitespace.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%run check_whitespace.py" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Whitespace within lines does not matter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a=1+2\n", + "b = 1 + 2\n", + "c = 1 + 2\n", + "print(a, b, c)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "tip: check the way python is implemented (what is under the hood)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import platform \n", + "platform.python_implementation()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "tip: check in what environment the code is running" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "print(sys.prefix)\n", + "print(sys.base_prefix)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/scripts/bitwise.py b/scripts/bitwise.py new file mode 100644 index 0000000..b8a165d --- /dev/null +++ b/scripts/bitwise.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 14 11:19:09 2018 +bitwise + +@author: u0015831 +""" +x = 10 +print(bin(x)) + +y = 13 +print(bin(y)) + +print('x&y',x&y) +print('x&y',bin(x&y)) + +print('x|y',x|y) +print('x|y',bin(x|y)) + +print('x', x) +print('x<<2',x<<2) +print('x<<2',bin(x<<2)) + +print('x', x) +print('x>>1',x>>1) +print('x>>1',bin(x>>1)) + +print('x', x) +print('~x',~x) +print('~x',bin(~x)) \ No newline at end of file diff --git a/scripts/block_code.py b/scripts/block_code.py new file mode 100644 index 0000000..0fae151 --- /dev/null +++ b/scripts/block_code.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Feb 21 10:06:18 2022 + +@author: u0015831 +""" + +from math import sqrt + +my_list = [1, 2, 3, 4] +result = 0 +for i in my_list: + if i%2 == 0: + result = result + sqrt(i) + print(result) \ No newline at end of file diff --git a/scripts/check_variable_object.py b/scripts/check_variable_object.py new file mode 100644 index 0000000..e4a0f4d --- /dev/null +++ b/scripts/check_variable_object.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" +check variable as an object + +@author: u0015831 +""" + +a = 4.5 +b = 56 +c = 'Hello' +d = a + b + +print(a, b, c, d) + +print (type(a), type(b), type(c), type(d)) + +print(dir(a)) +print('is a integer?', a.is_integer()) diff --git a/scripts/check_whitespace.py b/scripts/check_whitespace.py new file mode 100644 index 0000000..a5d1c2b --- /dev/null +++ b/scripts/check_whitespace.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 14 10:34:11 2018 +check the White Space! +@author: u0015831 +""" +#%% +for i in range(3): + print("Hello") + print("Bye!") + +#%% +# for i in range(10): +# if i%2 == 1: +# print (0.1*i) +# print ('bla') +# print('end block') + +#%% +# for i in range(10): +# if i%2 == 1: +# print (0.1*i) +# print ('bla') +# print('end block') + +#%% +# for i in range(10): +# if i%2 == 1: +# print (0.1*i) +# print('bla') +# print('end block') \ No newline at end of file diff --git a/scripts/command_line_io.py b/scripts/command_line_io.py new file mode 100644 index 0000000..b67ad56 --- /dev/null +++ b/scripts/command_line_io.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Nov 7 13:22:42 2019 + +command line IO + +example command line: python command_line_io.py o m g +example in Spyder: run command_line_io.py o m g + +@author: u0015831 +""" + +import sys +print('This is the name of the script: ', sys.argv[0]) +print('Number of arguments: ', len(sys.argv)) +print('The arguments are: ', sys.argv) + + +for arg in sys.argv: + print(type(arg), arg) \ No newline at end of file diff --git a/scripts/control_flow_conditionals.ipynb b/scripts/control_flow_conditionals.ipynb new file mode 100644 index 0000000..0813dac --- /dev/null +++ b/scripts/control_flow_conditionals.ipynb @@ -0,0 +1,172 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "code", + "source": "from IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\nfrom traceback import print_exc", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Computer programs can’t do that many things, they can:\n\n- Assign values to variables (memory locations).\n- Make decisions based on comparisons.\n- Repeat a sequence of instructions over and over.\n- Call subprograms.\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "# Control flow: conditionals\n\nbased on:\n- https://jakevdp.github.io/WhirlwindTourOfPython/07-control-flow-statements.html\n- https://realpython.com/python-for-loop/", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "With control flow, you can execute certain code blocks conditionally and/or repeatedly: these basic building blocks can be combined to create programs.", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "## Conditionals\n\n- Boolean values: `True`, `False`\n- Boolean operators: `not`, `and`, `or`\n- Comparison operators: `==`, `!=`, `<`, `<=`, `>`, `>=`\n- membership: `in`\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "9 > 8", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### if statement\n\nIf expression is True, execute all statements **indented** underneath\n*note the indents and the colon :*\n```python\nif expression:\n statement(s)\n```", + "metadata": {} + }, + { + "cell_type": "code", + "source": "if 0==0:\n print('Hello World')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "if 0==1:\n print('Is this happening?')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# change the value of x\nx = 0\n\nif (x > 2):\n print('Hello')\nprint('World')\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### if else statement\n\nIf expression is True, execute all statements indented under if.\nIf expression is False, execute all statements indented under else.\n\n```python\nif expression:\n statement(s)\nelse:\n statement(s)\n```", + "metadata": {} + }, + { + "cell_type": "code", + "source": "x = 0\n\nif (x > 2):\n print('Hello')\nelse:\n print('No')\n print('World')\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## if elif else statement\nExecute a code block only if some condition holds\n\n\n**syntax**\n \n*note the indents and the colon :*\n```python\nif expression:\n statement(s)\nelif expression:\n statement(s)\nelif expression:\n statement(s)\nelse:\n statement(s)\n```\n\n`elif` and `else` blocks are optional\n\n- no limit on number of `elif`\n- Booleans are checked in order. Once it finds first True, skips over all others\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "x = -100\n\nif x == 0:\n print(x, 'is zero')\nelif x > 0:\n print(x, 'is positive')\nelif x < 0:\n print(x, 'is negative')\nelse:\n print(x, 'what happend here?')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## nesting\n\ncombine the expressions", + "metadata": {} + }, + { + "cell_type": "code", + "source": "temp = 60\npressure = 100\n\nif 20 <= temp < 40:\n if pressure <= 60:\n print('Case A')\n else:\n print('Case B')\nelif temp >80:\n print('Case C')\n\nelse:\n print('don\\'t know')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Exceptions\n\nAN exception is an event that arises when an error occurs during the execution of a program. Python uses exception objects to signal that something has gone wrong. \n\nSome built-in exceptions:\n\n- `Exception`: This is the base class for most error types.\n- `ArithmeticError`: This is the base class for exceptions that occur for numeric calculations.\n- `ZeroDivisionError`: This is a subclass of ArithmeticError and is raised when you’re trying to divide by zero.\n- `FileNotFoundError`: This exception is raised when a file or directory is requested but doesn’t exist.\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "try:\n x = 1 / 0\nexcept ZeroDivisionError as e:\n print(f'Caught an exception: {e}')\nfinally:\n print(f'The try-except clause is exhausted now')\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# x = 5 # put in comment to test\n\ntry:\n print(x/0)\nexcept NameError as e:\n print(f\"problem: {e}\")\nexcept:\n print(\"Something else went wrong\")", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "del x", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/control_flow_loops.ipynb b/scripts/control_flow_loops.ipynb new file mode 100644 index 0000000..03d7dc2 --- /dev/null +++ b/scripts/control_flow_loops.ipynb @@ -0,0 +1,502 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "code", + "source": "from IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\nfrom traceback import print_exc", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "# Control flow: loops\n\nbased on:\n- https://jakevdp.github.io/WhirlwindTourOfPython/07-control-flow-statements.html\n- https://realpython.com/python-for-loop/\n- https://www.w3schools.com/python/default.asp\n- https://docs.python.org/3/tutorial/index.html\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "Loops\n\n**for** loops are executed a fixed number of iterations. It is possible to exit early but this must be added to the code.\n\n**while** loops do not have a predetermined number of iterations. They terminate when some condition becomes False.\n\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "Computer programs can’t do that many things, they can:\n\n- Assign values to variables (memory locations).\n- Make decisions based on comparisons.\n- Repeat a sequence of instructions over and over.\n- Call subprograms.\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "## Motivation for loops\n\nexample of calculating sum of the numbers 1 ... 100\n\ncalculate the sum of 1 + 2 + 3 + ...+ 100\n\n- brute force\n- for loop", + "metadata": {} + }, + { + "cell_type": "code", + "source": "!type sum_brute_force.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run sum_brute_force.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type sum_for_loop.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run sum_for_loop.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "# for loops\nrepeat a code block\n\ndefinite iteration: the number of repetitions is specified explicitly in advance\n\n**(basic) syntax**\n\n```python\nfor in :\n statement(s)\nelse:\n statement(s)\n```\nThe indentation is very important!\nThe `else` clause gets entered only if the for-loop is fully exhausted.\n\n\n**concept**\n\nTo carry out the iteration this for loop describes, Python does the following:\n- Calls iter() to obtain an iterator\n- Calls next() repeatedly to obtain each item from the iterator in turn\n- Terminates the loop when next() raises the StopIteration exception\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "sum=0\nnumbers =[1,22,31,45]\nfor num in numbers:\n print(num)\n sum=sum+num # check the indentation\navg=sum/len(numbers)\nprint ('Average:', avg)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "\"\"\"\nexample for loop from Python tutorial R 3.7.0\n\"\"\"\nwords = ['cat', 'window', 'defenestrate']\n\nfor w in words[:]: # Loop over a slice copy of the entire list.\n#for w in words: # Loop over the sequence, beware for an infinite list!.\n if len(w) > 6:\n words.insert(0, w)\n\nprint(words)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Loop over collections\n\nstrings, list and tuple preserve order", + "metadata": {} + }, + { + "cell_type": "code", + "source": "my_string = 'mississippi'\n\nfor x in (my_string):\n print(x)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "l_my_string = list(my_string)\nprint(l_my_string)\n\nfor x in (l_my_string):\n print(x)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "t_my_string = tuple(my_string)\nprint(t_my_string)\n\nfor x in (l_my_string):\n print(x)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "s_my_string = set(my_string)\nprint(s_my_string)\n\nfor x in (s_my_string):\n print(x)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "d = {'6': 's', '7': 's', '8':'i', '9': 'p', '10': 'p', '11': 'i',\n '1': 'm', '2': 'i', '3': 's', '4': 's', '5':'i',}\n# Dictionaries preserve order of entry (newer version of python)\nfor x in d:\n print(x)\nprint('****')\n \nfor x in d.values():\n print(x)\nprint('****')\n \nfor x, y in d.items():\n print(x,y)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Loops can be nested", + "metadata": {} + }, + { + "cell_type": "code", + "source": "count = 0\n# sequential loops\nfor i in range(0, 10):\n count += 1\nfor j in range(0, 20):\n count += 1\nprint(count)\nprint(\"-----------------\")\n# -------------------------\n# nested loop\ncount = 0\nfor i in range(0, 10):\n for j in range(0, 20):\n count += 1\nprint(count)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "# while loops\n\nRepeat a code block until some condition is met.\n\nThe argument of the while loop is evaluated as a boolean statement, and the loop is executed until the statement evaluates to False.\nIt is not always known beforehand how many times the loop will have to repeated.\n\n**(basic) syntax**\n\n```python\nwhile condition:\n statement(s)\nelse:\n statement(s)\n```\nThe indentation is very important! The `else` clause is executed as soon as the condition in the `while` loop evaluates to `False`. Beware of infinite loops!\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "i = 0\nwhile i < 10:\n print(i, end=' ')\n i += 1\nelse:\n print('\\n the end \\n')\nprint('this is the next statement') ", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run while_loop_1.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "watch out for infinite loops!\n\ntrigger a KeyboardInterrupt in a Notebook via the menu \"Kernel --> Interrupt\".", + "metadata": {} + }, + { + "cell_type": "code", + "source": "i = 0\nwhile i < 10:\n print(i, end=' ')\n i -= 1", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## fine-tuning loops\n### Skipping loop iterations\n\n`continue` : skips the remainder of the current loop and goes to the next iteration.\n\n`break`: breaks-out of the loop entirely and go to the next statement following the loop", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "#### continue\n\nthe loop iterates over a list of numbers. If the current number (num) is even (i.e., num % 2 == 0), the continue statement is executed. This causes the loop to skip the print(num) statement for even numbers and immediately move on to the next iteration. As a result, only the odd numbers are printed. ", + "metadata": {} + }, + { + "cell_type": "code", + "source": "num_list = [1, 2, 3, 44, 56, 77, 8, 18, 19, 77.7, 100, 101, 23]\nfor num in num_list:\n if num%2 == 0:\n continue\n print(num)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "#### break\n\nthe loop iterates over a list of numbers. If the current number (num) is even (i.e., num % 2 == 0), the break statement is executed. This causes the loop to break out of the loop when an even number is encountered.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "num_list = [1, 2, 3, 44, 56, 77, 8, 18, 19, 77.7, 100, 101, 23]\nfor num in num_list:\n if num%2 == 0:\n break \n print(num)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "n = 101\nwhile n < 1000:\n if not(n%20):\n break \n print(n, 'in while loop') \n n += 1\nelse:\n print('else part of the while statement')\nprint('out of while loop')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run while_loop_break_continue.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "#### `pass`\n\nThe `pass` statement in Python is a placeholder statement that is used when the syntax requires a statement, but you don’t want to execute any code. It’s often used as a placeholder for future code.\n\nThe example below uses `pass`as an alternative for the `continue` statement.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "num_list = [1, 2, 3, 44, 56, 77, 8, 18, 19, 77.7, 100, 101, 23]\nfor num in num_list:\n if num%2 == 0:\n pass\n else:\n print(num)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### `else` part\n\n**(full) syntax `for` loop**\n\n```python\nfor in :\n statement(s) \nelse: # optional \n statement(s)\n```\n\n**(full) syntax `while` loop**\n\n```python\nwhile condition :\n statement(s) \nelse: # optional \n statement(s)\n```\nThe indentation is very important!\n\n**else** part\n\nuse case: implement search loops, searching for an item meeting a particular condition, and need to perform additional processing or raise warning if no acceptable value is found\n\n- Loop should not contain `break` statement.\n- The statements in the else block will be executed after all iterations are completed (normal termination).\n\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "numbers =[1, 2, 32, 45]\nfor i in numbers: \n print(i) \n if i > 5.5:\n break\nelse: # Not executed as there is a break \n print('No break encountered') \nprint('finished')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "count = 0\n\nwhile count < 5:\n print(count)\n count += 1\nelse:\n print(\"Loop ended, count is no longer less than 5.\")\nprint(\"last line\")", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# another demo of the else clause\nfor n in range(2, 10):\n for x in range(2, n):\n if n % x == 0:\n print( n, 'equals', x, '*', n/x)\n break\n else:\n # loop fell through without finding a factor\n print(n, 'is a prime number')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "# iterators\n\n\nAn iterator is a special object that gives values in succession, it implements the `next` protocol and raises `StopIteration` when exhausted.\nIterators:\n\n- range()\n- enumerate()\n- zip()\n\n## range\n\nIf you need to iterate over a sequence of numbers, the built-in function `range()` can be used, it\ngenerates arithmetic progressions\n\nfor loop is often used with the `range` function (a commonly-used iterator in Python)\n* `range(n)` - sequence 0,1,…,n−1\n* `range(m, n)` - sequence m,m+1,…,n−1\n* `range(m, n, s)` - sequence m,m+s, m+2s,… <= n-1\n\nNote: limitation of `range()`: it works only with integers. (consider NumPy `arange`). See also : https://pynative.com/python-range-for-float-numbers/\n\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "for i in range(10):\n print(i, end=' ')\nprint()\n \nfor i in range(5):\n print('Hello World')\nprint('')\n\nfor _ in range(5): # throwaway variable, the loop variable isn't used.\n print('Hello World')\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "In many ways the object returned by `range()` behaves as if it is a list, but it is an object\nwhich returns the successive items of the desired sequence when you iterate over it, but it doesn’t really\nmake the list, thus saving memory.\n\nSuch an object is an *iterable*, that is, suitable as a target for functions and constructs that expect\nsomething from which they can obtain successive items until the supply is exhausted. ", + "metadata": {} + }, + { + "cell_type": "code", + "source": "print(range(10))", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "list(range(10))", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Note: The benefit of the iterator indirection is that the full list is never explicitly created!\n```python\nN = 10 ** 12\n\nfor i in range(N):\n if i >= 10: break\n print(i, end=', ')\n```\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "N = 10 ** 12\n\nrange_N = range(N)\nprint(range_N)\nprint(type(range_N))\n\nfor i in range_N:\n if i >= 10: break\n print(i, end=', ')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "al = [2, 3, 5, 7]\nfor i in al:\n i += 1 \n print('i = ', i)\nprint('al: ', al)\n\n# simulate a counter \nal_len = len(al)\npos = range(al_len)\nfor i in pos:\n al[i] += 1\nprint('al: ', al)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# python way\nfruitslist = ['banana', 'apple', 'mango']\nfor i in fruitslist:\n print(i)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# Traditional indexing\nfruitslist = ['banana', 'apple', 'mango']\nfor i in range(len(fruitslist)):\n print(fruitslist[i])\n ", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "* regular for loop uses the items\n* use `enumerate` when index is needed. The function gives you back two loop variables:\n - The count of the current iteration\n - The value of the item at the current iteration\n* use `zip` when skimming multiple lists", + "metadata": {} + }, + { + "cell_type": "code", + "source": "fruitslist = ['banana', 'apple', 'mango', 'grape', 'orange']\n# use of enumerate - tuple: (index, value)\nfor line in enumerate(fruitslist, start=0):\n print(line) \nprint(' ')\n\n# use of enumerate - individual elements\nfor num, color in enumerate(fruitslist, start=1):\n print(num, color) \nprint(' ')\n\nfor num, color in enumerate(fruitslist, start=1):\n print(color) \nprint(' ')\n\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# is it working for a set?\nfruitset = {'banana', 'apple', 'mango', 'grape', 'orange'}\nfor num, color in enumerate(fruitset, start=10):\n print(num, color)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "fruitslist = ['banana', 'apple', 'mango']\nratios = [0.2, 0.3, 0.1, 0.4]\nwinelist = ['merlot', 'chenin', 'chardonnay', 'temperanillo', 'whatever']\nfor fruit, ratio, wine in zip(fruitslist, ratios, winelist):\n print(ratio * 100, fruit, wine)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### note: iter\n\n`iter` object is a container that gives you access to the next object for as long as it’s valid\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "winelist = ['merlot', 'chenin', 'chardonnay', 'temperanillo', 'whatever']\nit_winelist = iter(winelist)\n\nprint(type(it_winelist))\nprint(it_winelist)\n\nnext(it_winelist)\nnext(it_winelist)\nnext(it_winelist)\nnext(it_winelist)\nnext(it_winelist)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "I = iter([2, 4, 6, 8, 10])\nprint(type(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "I = iter([2, 4, 6, 8, 10])\nprint(type(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\nprint(next(I))\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### note: generator\n\nA generator is a function that produces a sequence of results instead of a single value. As generators do not store the sequence that is generated, they are memory-efficient. \n\nMany built in Python functions return generators to minimize use of memory - e.g. `range, zip, open` - A loop can be used to evaluate them.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "zz = zip(range(10), 'abcdefghij')\nprint(zz)\n\nfor i, c in zz:\n print(i, c)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### note: comprehension\n\ncheck http://justinbois.github.io/bootcamp/2023/lessons/l15_comprehensions.html#List-comprehensions\n\nSyntax sugar similar to that of generator expressions can be used to create lists, sets and dictionaries. A powerful functionality within a single line of code; provides a compact way to create lists, dictionaries, sets!\n\nfor a list:\n`newlist = [expression for item in iterable if condition == True]`\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# list comprehension\n\nlc1 = [i for i in range(10)]\nprint(lc1)\n\nlc2 = [i**2 for i in range(10) if i % 2 == 1]\nprint(lc2)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# dictionary comprehension\n\nnames = ['ann', 'jules', 'charles']\nages = [55, 44, 45]\n\ndc = {a1: b1 for a1, b1 in zip(names, ages)}\nprint(dc)\ndc", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "#set comprehension\n\nl1 = list(range(1,11))\nsc = {element**3 for element in l1}\nprint(sc)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/convert_from_decimal.py b/scripts/convert_from_decimal.py new file mode 100644 index 0000000..4b9dd2c --- /dev/null +++ b/scripts/convert_from_decimal.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Aug 29 09:51:15 2019 +taken from Marina von Steinkirch + +@author: u0015831 +""" + +def convert_to_decimal(number, base): + multiplier, result = 1, 0 + while number > 0: + result += number%10*multiplier + multiplier *= base + number = number//10 + return result + +def test_convert_to_decimal(): + number, base = 1001, 2 + assert(convert_to_decimal(number, base) == 9) + +def test_convert_from_decimal(): + number, base = 9, 2 + assert(convert_from_decimal(number, base) == 1001) \ No newline at end of file diff --git a/scripts/convert_to_decimal.py b/scripts/convert_to_decimal.py new file mode 100644 index 0000000..3dd17d2 --- /dev/null +++ b/scripts/convert_to_decimal.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Aug 29 09:51:15 2019 +taken from Marina von Steinkirch + +@author: u0015831 +""" + +def convert_to_decimal(number, base): + multiplier, result = 1, 0 + while number > 0: + result += number%10*multiplier + multiplier *= base + number = number//10 + return result + +def test_convert_to_decimal(): + number, base = 1001, 2 + print ('number = ', number) + print ('base = ', base) + assert(convert_to_decimal(number, base) == 9), 'result must equal 9' + diff --git a/scripts/create_lists.py b/scripts/create_lists.py new file mode 100644 index 0000000..7d3a950 --- /dev/null +++ b/scripts/create_lists.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 23 11:52:06 2019 + +create lists + +""" +# classic approach +squares = [] +for i in range(10): + squares.append(i * i) +squares + +# list comprehension +squares = [i * i for i in range(10)] +squares \ No newline at end of file diff --git a/scripts/debugging_basics.ipynb b/scripts/debugging_basics.ipynb new file mode 100644 index 0000000..c394b82 --- /dev/null +++ b/scripts/debugging_basics.ipynb @@ -0,0 +1,166 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9a57d658", + "metadata": {}, + "source": [ + "# Debugging\n", + "\n", + "A short step into debugging code.\n", + "\n", + "The demo code is taken from Jake Van der Plas https://jakevdp.github.io/PythonDataScienceHandbook/01.06-errors-and-debugging.html\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bc5c5da6", + "metadata": {}, + "outputs": [], + "source": [ + "def func1(a, b):\n", + " return a / b\n", + "\n", + "def func2(x):\n", + " a = x\n", + " b = x - 1\n", + " return func1(a, b)" + ] + }, + { + "cell_type": "markdown", + "id": "2bc0a427", + "metadata": {}, + "source": [ + "## Controlling exceptions\n", + "\n", + "inspired by Jake vdp\n", + "\n", + "when a Python script fails, it will raise an Exception. When the interpreter hits one of these exceptions, information about the cause of the error can be found in the traceback, which can be accessed from within Python. \n", + "\n", + "With the `%xmode` magic function, the level of information can be set by specifying the argument\n", + "- `Plain`: compact form \n", + "- `Context`: default\n", + "- `Verbose`: some extra information\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "5425c8e3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Exception reporting mode: Context\n" + ] + } + ], + "source": [ + "# %xmode Plain\n", + "%xmode Context\n", + "# %xmode Verbose" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "cffba13b", + "metadata": {}, + "outputs": [ + { + "ename": "ZeroDivisionError", + "evalue": "division by zero", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[13], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mfunc2\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n", + "Cell \u001b[1;32mIn[4], line 7\u001b[0m, in \u001b[0;36mfunc2\u001b[1;34m(x)\u001b[0m\n\u001b[0;32m 5\u001b[0m a \u001b[38;5;241m=\u001b[39m x\n\u001b[0;32m 6\u001b[0m b \u001b[38;5;241m=\u001b[39m x \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[1;32m----> 7\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc1\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m\n", + "Cell \u001b[1;32mIn[4], line 2\u001b[0m, in \u001b[0;36mfunc1\u001b[1;34m(a, b)\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc1\u001b[39m(a, b):\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\n", + "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero" + ] + } + ], + "source": [ + "func2(1)" + ] + }, + { + "cell_type": "markdown", + "id": "80b0b903", + "metadata": {}, + "source": [ + "## Debugger\n", + "The magic command `%%debug` enables to interactively use Python’s `pdb` debugger." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "90947921", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NOTE: Enter 'c' at the ipdb> prompt to continue execution.\n", + "> \u001b[1;32m\u001b[0m(3)\u001b[0;36m\u001b[1;34m()\u001b[0m\n", + "\n", + "ipdb> b func2\n", + "*** Line c:\\users\\u0015831\\appdata\\local\\temp\\ipykernel_17956\\4021589855.py:4 does not exist\n", + "ipdb> r\n", + "--Return--\n", + "None\n", + "> \u001b[1;32m\u001b[0m(3)\u001b[0;36m\u001b[1;34m()\u001b[0m\n", + "\n", + "ipdb> n\n", + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n", + "\u001b[1;31mZeroDivisionError\u001b[0m Traceback (most recent call last)\n", + "Cell \u001b[1;32mIn[4], line 7\u001b[0m, in \u001b[0;36mfunc2\u001b[1;34m(x)\u001b[0m\n", + "\u001b[0;32m 5\u001b[0m a \u001b[38;5;241m=\u001b[39m x\n", + "\u001b[0;32m 6\u001b[0m b \u001b[38;5;241m=\u001b[39m x \u001b[38;5;241m-\u001b[39m \u001b[38;5;241m1\u001b[39m\n", + "\u001b[1;32m----> 7\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc1\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m\n", + "\n", + "Cell \u001b[1;32mIn[4], line 2\u001b[0m, in \u001b[0;36mfunc1\u001b[1;34m(a, b)\u001b[0m\n", + "\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc1\u001b[39m(a, b):\n", + "\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43ma\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\n", + "\n", + "\u001b[1;31mZeroDivisionError\u001b[0m: division by zero\n" + ] + } + ], + "source": [ + "%%debug\n", + "\n", + "func2(1)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/scripts/deck.py b/scripts/deck.py new file mode 100644 index 0000000..0babfa5 --- /dev/null +++ b/scripts/deck.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +import random + + +def generate_deck(): + """Return a list containing the cards in a standard, 52-card deck.""" + suits = ["Spades", "Hearts", "Diamonds", "Clubs"] + ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", + "Jack", "Queen", "King", "Ace"] + deck = [] + for s in suits: + for r in ranks: + name = "%s of %s" % (r, s) + deck.append(name) + return deck + + +def draw_random(deck): + """Draw a random card from the given deck.""" + n = len(deck) + i = random.randint(0, n) + k = draw_card(deck, i) + return k + + +def draw_card(deck, x): + """Return card no. x from the deck.""" + return deck[x] + + +def test_with_replacement(): + print("Generating deck") + deck = generate_deck() + + number = 10 + print("Drawing", number, "random cards with replacement:") + drawn = set() + for x in range(number): + card = draw_random(deck) + print(" You drew", card) + drawn.add(card) + unique = len(drawn) + print("Drew", unique, "different cards") + + +test_with_replacement() \ No newline at end of file diff --git a/scripts/demo_mix.xlsx b/scripts/demo_mix.xlsx new file mode 100644 index 0000000..0aac475 Binary files /dev/null and b/scripts/demo_mix.xlsx differ diff --git a/scripts/dict.ipynb b/scripts/dict.ipynb new file mode 100644 index 0000000..84c16ba --- /dev/null +++ b/scripts/dict.ipynb @@ -0,0 +1,312 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "markdown", + "source": "In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "from traceback import print_exc", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Key concepts in programming\n\n- Variables (integers, strings, dates, etc.)\n- Flow control (if then, loop, etc.)\n- Functions (list of steps the code will follow)\n\n\n## data containers\n\nOrganize the data structure into four different families: \n- Ordered data structure: list and tuple\n- Unordered data structure: set and dictionary \n- Mutable: list, set and dictionary \n- Immutable: tuple \n\n\n| Type | Example | Description |\n|------|---------|---------|\n| list | `[1, 2, 3]` | Ordered collection|\n| tuple | `(1, 2, 3)` | Immutable ordered collection|\n| dict | `{'a':1, 'b':2, 'c':3}` | Unordered (key:value) pair mapping|\n| set | `{1, 2, 3}` | Unordered collection of unique values |\n\n\n## operations on any sequence\n\n| Operation | Operator | Description |\n|------|---------|---------|\n| indexing | `[]` | Access an element of a sequence |\n|concatenation | `+` | Combine sequences together|\n| repetition | `*` | Concatenate a repeated number of times|\n| membership | `in` | Ask whether an item is in a sequence |\n| length | `len` | Ask the number of items in the sequence|\n| slicing | `[:]` | Extract a part of a sequence |\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "# Dictionaries\n- {'a':1, 'b':2, 'c':3}\n- **(key,value) mapping**: the key must be immutable, mostly a string. Dictionaries in Python are used to store data values in key-value pairs. Each key-value pair maps the key to its associated value.\n- **mutable**: meaning that we can change, add, or remove items after the dictionary has been created.\n- **nested dictionaries**: A dictionary can contain another dictionary. \n- **ordered?**: as of Python version 3.7, dictionaries are ordered. This means that the items have a defined order, and that order will not change. Note that in Python 3.5 and older dictionaries have no sense of order. In Python 3.6, dictionaries were stored in insertion order as an implementation improvement. In Python 3.7 and beyond, dictionaries are guaranteed to be ordered in the order in which their entries were created. It is therefore advisable be cautious when relying on ordering in dictionaries. For safety’s sake, it is better to assume there is no sense of order.\n- **no indexing**: an index value as in `lists`and `tuples` cannot be used.\n- **no duplicates**: dictionaries do not allow duplicate keys. If you try to use a duplicate key, the old value for that key will be replaced with the new value.\n- **various data types**: the values in dictionary items can be of any data type.", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "Instantiating a dictionary:\n\n- `{}`\n- `dict()`: \n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "help(dict)", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "#First way to setup a dictionary\nzipdict = {'Hasselt': 3500, 'Luik':4000}\n\n#Add a couple of cities to the dictionary\nzipdict['Heverlee'] = 3001\nzipdict['Leuven'] = 3000\nzipdict['Brussel'] = 1000\nzipdict['Gent'] = 9000\n\n# another way\nzipdict.update({'Antwerpen': 2000, 'Brugge': 8000})", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": 1 + }, + { + "cell_type": "code", + "source": "print(zipdict)\n\nprint(zipdict['Leuven'])\n\nprint(zipdict[4])", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "{'Hasselt': 3500, 'Luik': 4000, 'Heverlee': 3001, 'Leuven': 3000, 'Brussel': 1000, 'Gent': 9000, 'Antwerpen': 2000, 'Brugge': 8000}\n3000\n" + }, + { + "ename": "", + "evalue": "4", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mKeyError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[2]\u001b[39m\u001b[32m, line 5\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28mprint\u001b[39m(zipdict)\n\u001b[32m 3\u001b[39m \u001b[38;5;28mprint\u001b[39m(zipdict[\u001b[33m'\u001b[39m\u001b[33mLeuven\u001b[39m\u001b[33m'\u001b[39m])\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[43mzipdict\u001b[49m\u001b[43m[\u001b[49m\u001b[32;43m4\u001b[39;49m\u001b[43m]\u001b[49m)\n", + "\u001b[31mKeyError\u001b[39m: 4" + ], + "output_type": "error" + } + ], + "execution_count": 2 + }, + { + "cell_type": "code", + "source": "basketdict = dict([ \n ('Leuven', 'Bears'),\n ('Hasselt','Limburg United'),\n ('Aalst','Okapi'),\n ('Oostende','BC Oostende')])\n\nprint(basketdict)\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "{'Leuven': 'Bears', 'Hasselt': 'Limburg United', 'Aalst': 'Okapi', 'Oostende': 'BC Oostende'}\n" + } + ], + "execution_count": 3 + }, + { + "cell_type": "markdown", + "source": "Accessing dictionary values\n\n- specify the corresponding key in square brackets `[]`", + "metadata": {} + }, + { + "cell_type": "code", + "source": "basketdict['Aalst']", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "basketdict['Antwerpen']", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "basketdict.get('Aalst')", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "basketdict.get(Aalst)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "ename": "", + "evalue": "name 'Aalst' is not defined", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m basketdict.get(\u001b[43mAalst\u001b[49m)\n", + "\u001b[31mNameError\u001b[39m: name 'Aalst' is not defined" + ], + "output_type": "error" + } + ], + "execution_count": 4 + }, + { + "cell_type": "code", + "source": "basketdict[0]", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "ename": "", + "evalue": "0", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mKeyError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[5]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mbasketdict\u001b[49m\u001b[43m[\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m]\u001b[49m\n", + "\u001b[31mKeyError\u001b[39m: 0" + ], + "output_type": "error" + } + ], + "execution_count": 5 + }, + { + "cell_type": "markdown", + "source": "Built-in functions, operators\n\n- `in` use with key values\n- `len`", + "metadata": {} + }, + { + "cell_type": "code", + "source": "print('len(zipdict): ', len(zipdict))\n\n#Use the function key() - \nif 'Gent' in zipdict:\n print('Gent is in the dictionary', zipdict['Gent'])\nelse:\n print('Gent is not in the dictionary')\n\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "len(zipdict): 8\nGent is in the dictionary 9000\n" + } + ], + "execution_count": 6 + }, + { + "cell_type": "markdown", + "source": "The order in dictionaries is preserved. \n\nIn the example below, elements are added to the dictionary in a specific order: ‘first’, ‘second’, ‘third’, and ‘fourth’. When the dictionary is printed, the elements are displayed in the order they were added. This is because, as of Python 3.7, dictionaries maintain the insertion order of their elements.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# Creating a dictionary\nmy_dict = {}\n\n# Adding elements to the dictionary\nmy_dict['first'] = 1\nmy_dict['second'] = 2\nmy_dict['third'] = 3\nmy_dict['fourth'] = 4\n\n# Printing the dictionary\nfor key, value in my_dict.items():\n print(f\"{key}: {value}\")\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "first: 1\nsecond: 2\nthird: 3\nfourth: 4\n" + } + ], + "execution_count": 7 + }, + { + "cell_type": "markdown", + "source": "Methods\n\n- clear(): clears a dictionary\n- keys(): returns a list of keys\n- values(): returns a list of values\n- pop(): removes a key, and returns its value\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "zipdict = {'Hasselt': 3500,\n 'Luik': 4000,\n 'Heverlee': 3001,\n 'Leuven': 3000,\n 'Brussel': 1000,\n 'Gent': 9000,\n 'Antwerpen': 2000,\n 'Brugge': 8000}\n\n#Use the function keys() - \nkeys = zipdict.keys()\nprint(type(keys))\nprint(keys)\n\nvalues = zipdict.values()\nprint(values)\n\nzipdict.pop('Gent')\nprint(zipdict)\n\nzipdictbis = zipdict\nprint('zipdictbis: ', zipdictbis)\nzipdictbis.clear()\nprint('zipdictbis: ', zipdictbis)\n\n# alias?\nprint('zipdict: ', zipdict)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "\ndict_keys(['Hasselt', 'Luik', 'Heverlee', 'Leuven', 'Brussel', 'Gent', 'Antwerpen', 'Brugge'])\ndict_values([3500, 4000, 3001, 3000, 1000, 9000, 2000, 8000])\n{'Hasselt': 3500, 'Luik': 4000, 'Heverlee': 3001, 'Leuven': 3000, 'Brussel': 1000, 'Antwerpen': 2000, 'Brugge': 8000}\nzipdictbis: {'Hasselt': 3500, 'Luik': 4000, 'Heverlee': 3001, 'Leuven': 3000, 'Brussel': 1000, 'Antwerpen': 2000, 'Brugge': 8000}\nzipdictbis: {}\nzipdict: {}\n" + } + ], + "execution_count": 8 + }, + { + "cell_type": "code", + "source": "basketdict = dict([ \n ('Leuven', 'Bears'),\n ('Hasselt','Limburg United'),\n ('Aalst','Okapi'),\n ('Oostende','BC Oostende')])\n\n#Use the function keys() - \nfor city in basketdict.keys():\n if city[0] == 'L':\n print('city starting with L:', city)\n\n# create a list out of the keys\nkeys = basketdict.keys()\nalist = list(keys)\nalist.sort()\n# print a sorted list\nprint(alist)\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "city starting with L: Leuven\n['Aalst', 'Hasselt', 'Leuven', 'Oostende']\n" + } + ], + "execution_count": 9 + }, + { + "cell_type": "code", + "source": "# create a histogram\n# https://swcarpentry.github.io/python-second-language/06-dict/\nnumbers = [1, 0, 1, 2, 0, 0, 1, 2, 1, 3, 1, 0, 2]\ncount = {}\nprint(type(count))\nfor n in numbers:\n if n not in count:\n count[n] = 1\n else:\n count[n] = count[n] + 1\nprint(count)\nprint(count[1]) # 1 is a key, not an index", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "\n{1: 5, 0: 4, 2: 3, 3: 1}\n5\n" + } + ], + "execution_count": 10 + }, + { + "cell_type": "markdown", + "source": "It is possible to create a nested dictionary: a dictionary within a dictionary. \n\nIn this example, a dictionary is created for an observation, the observations are combined in a parent-dictionary.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "Obs01 = {'name': 'experiment 1', 'val': 23.33, 'temp': 100.0, 'press': 200.0, 'date':'2022-02-02'}\nObs02 = {'name': 'experiment 2', 'val': 27.00, 'temp': 110.0, 'press': 200.0, 'date':'2022-02-02'}\nObs03 = {'name': 'experiment 3', 'val': 27.88, 'temp': 120.0, 'press': 200.0, 'date':'2022-02-03'}\nseries_01 = {'t1': Obs01,\n 't2': Obs02,\n 't3': Obs03} # insert individual dictionaries in a dictionary\n# print result of the 3rd observation\nprint('val = {}, temp = {}'.format(series_01['t3']['val'], series_01['t3']['temp']))", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "val = 27.88, temp = 120.0\n" + } + ], + "execution_count": 11 + }, + { + "cell_type": "markdown", + "source": "### aliasing\n\n\nBecause dictionaries are mutable, you need to be aware of aliasing (as with lists). Whenever two variables refer to the same dictionary object, changes to one affect the other. \n\n\nUse the dictionary copy method", + "metadata": {} + }, + { + "cell_type": "code", + "source": "dict1 = {\"key1\": \"value1\", \"key2\": \"value2\"}\ndict2 = dict1\ndict2[\"key2\"] = \"WHY?!\"\ndict1\n", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "import copy\n\ndict1 = {\"key1\": \"value1\", \"key2\": \"value2\"}\ndict2 = copy.deepcopy(dict1)\ndict2[\"key2\"] = \"WHY?!\"\ndict1", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### A dictionary is an implementation of a hash table\n\nhttp://justinbois.github.io/bootcamp/2023/lessons/l09_dictionaries.html\n\n\nEach entry in the dictionary is stored at a different location in memory. The dictionary itself also has its own address. \n\nDictionaries use a hash function to do this. A hash function converts its input to an integer. \n\nPython’s built-in hash function can be used to convert the keys to integers.\nUnder the hood, Python then converts these integers to integers that could correspond to locations in memory. A collection of elements that can be indexed this way is called a hash table. This is a very common data structure in computing.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# Create dictionary\nmy_dict = {'a': 6, 'b': 7, 'c':12.6}\n\n# Find where they are stored\nprint(id(my_dict))\nprint(id(my_dict['a']))\nprint(id(my_dict['b']))\nprint(id(my_dict['c']))\n\n# python hash function\nprint(hash('a'), hash('b'), hash('c'))\n", + "metadata": {}, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/dictionaries_1.py b/scripts/dictionaries_1.py new file mode 100644 index 0000000..8739f6a --- /dev/null +++ b/scripts/dictionaries_1.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 21 15:58:30 2018 + +dictionaries + +@author: u0015831 +""" + +#A few examples of a dictionary + +#First way to setup a dictionary +zipdict = {} + +#Add a couple of cities to the dictionary +zipdict['Heverlee'] = 3001 +zipdict['Leuven'] = 3000 +zipdict['Brussel'] = 1000 +zipdict['Gent'] = 9000 + +# another way +zipdict.update({'Antwerpen': 2000, 'Brugge': 8000}) + +#Use the function key() - +if 'Gent' in zipdict: + print('Gent is in the dictionary. ZIP: ', zipdict['Gent']) +else: + print('Gent is not in the dictionary') + +#Use the function keys() - +keys = zipdict.keys() +print(keys) +#keys.sort() will this work? +#print(keys) + +# List of codes in a list: +values = zipdict.values() +print(values) +#values.sort() +#print(values) + diff --git a/scripts/fibonacci.py b/scripts/fibonacci.py new file mode 100644 index 0000000..ff5e55e --- /dev/null +++ b/scripts/fibonacci.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Aug 29 11:02:31 2019 +taken from Marina von Steinkirch + +@author: u0015831 +""" + +def fib_generator(): + a, b = 0, 1 + print(a, b) + while True: + print(b) + yield b + a, b = b, a+b + +def fib(n): + ''' + >>> fib(2) + 1 + >>> fib(5) + 5 + >>> fib(7) + 13 + ''' + if n < 3: + return 1 + a, b = 0, 1 + count = 1 + while count < n: + print(count) + count += 1 + a, b = b, a+b + return b + + +def fib_rec(n): + ''' + >>> fib_rec(2) + 1 + >>> fib_rec(5) + 5 + >>> fib_rec(7) + 13 + ''' + if n < 3: + return 1 + return fib_rec(n - 1) + fib_rec(n - 2) \ No newline at end of file diff --git a/scripts/file_basic_input.py b/scripts/file_basic_input.py new file mode 100644 index 0000000..1c2ab3c --- /dev/null +++ b/scripts/file_basic_input.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 5 15:12:20 2019 + +processing a file in a for-loop + +@author: u0015831 +""" + +txtfile = open("test_text.txt","r") + +for aline in txtfile: + values = aline.split() + if len(values) > 10: + print('some text', values[0], values[1], ' and also ', values[10] ) + +txtfile.close() diff --git a/scripts/file_io_2.py b/scripts/file_io_2.py new file mode 100644 index 0000000..275ec69 --- /dev/null +++ b/scripts/file_io_2.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 28 13:44:00 2018 + +@author: u0015831 +""" + +my_file=open('lines_10.txt','r') + +fa = my_file.read() +print(fa) + +my_file.seek(0) # return handle to first position +f3 = my_file.read(3) +print(f3) + +# use readline +frl = my_file.readline() +print(frl) diff --git a/scripts/file_io_3.py b/scripts/file_io_3.py new file mode 100644 index 0000000..cdcd266 --- /dev/null +++ b/scripts/file_io_3.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 28 14:16:29 2018 + +@author: u0015831 +""" + +fin=open('test_text.txt','r') +for line in fin: + line_in = line.rstrip('\r\n') #remove end of line + data = line_in.split() #split line of text + print(data) diff --git a/scripts/file_io_forLoop.py b/scripts/file_io_forLoop.py new file mode 100644 index 0000000..1c2ab3c --- /dev/null +++ b/scripts/file_io_forLoop.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 5 15:12:20 2019 + +processing a file in a for-loop + +@author: u0015831 +""" + +txtfile = open("test_text.txt","r") + +for aline in txtfile: + values = aline.split() + if len(values) > 10: + print('some text', values[0], values[1], ' and also ', values[10] ) + +txtfile.close() diff --git a/scripts/file_io_header.py b/scripts/file_io_header.py new file mode 100644 index 0000000..182a6eb --- /dev/null +++ b/scripts/file_io_header.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jun 3 10:09:14 2019 + +@author: taken from http://www2.hawaii.edu/~takebaya/cent110/file_in/file_in.html +""" + +infile = open("students_header.txt","r") +line1 = infile.readline() +lines = infile.readlines() +infile.close() +outfile = open("data.html","w") +outfile.write("\n \n") +outfile.write(' \n') +outfile.write(' \n') +headers = line1.strip().split(",") +outfile.write(' ') +for header in headers: + outfile.write(' ') +outfile.write('\n \n') +for line in lines: + tokens = line.strip().split(",") + outfile.write(' \n') + outfile.write(' ') + for token in tokens: + outfile.write(' ') + outfile.write('\n \n') +outfile.write('
' + header + '
' + token + '
\n') +outfile.write(' \n') +outfile.close() \ No newline at end of file diff --git a/scripts/file_io_readline.py b/scripts/file_io_readline.py new file mode 100644 index 0000000..009d590 --- /dev/null +++ b/scripts/file_io_readline.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 5 15:12:20 2019 + +processing a file with readline +the file is read into a list + +@author: u0015831 +""" + +txtfile = open("test_text.txt","r") + +aline = txtfile.readline() +values = aline.split() + +while aline: + if len(values) > 10: + print('some text', values[0], values[1], ' and also ', values[10] ) + aline = txtfile.readline() + values = aline.split() + +txtfile.close() diff --git a/scripts/file_io_readlines.py b/scripts/file_io_readlines.py new file mode 100644 index 0000000..ff6be8d --- /dev/null +++ b/scripts/file_io_readlines.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 5 15:12:20 2019 + +processing a file with readlines +the file is read into a list + +@author: u0015831 +""" + +txtfile = open("test_text.txt","r") +lines = txtfile.readlines() +txtfile.close() + +for aline in lines: + values = aline.split() + if len(values) > 10: + print('some text', values[0], values[1], ' and also ', values[10] ) + diff --git a/scripts/file_io_readlines_1.py b/scripts/file_io_readlines_1.py new file mode 100644 index 0000000..bc679f2 --- /dev/null +++ b/scripts/file_io_readlines_1.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jun 3 09:45:37 2019 + +@author: taken from http://www2.hawaii.edu/~takebaya/cent110/file_in/file_in.html +""" + +infile = open("students.txt","r") +lines = infile.readlines() +infile.close() +for line in lines: + tokens = line.split(",") + total = 0 + for i in range(1, len(tokens)): + total = total + float(tokens[i]) + average = total/(len(tokens) - 1) + print(tokens[0],"has an average of: ",average) \ No newline at end of file diff --git a/scripts/file_io_write_1.py b/scripts/file_io_write_1.py new file mode 100644 index 0000000..49883ca --- /dev/null +++ b/scripts/file_io_write_1.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 28 11:04:44 2018 + +@author: u0015831 +""" + +fp = open('testfile-write.txt','w') + +fp.write('Hello World') +fp.write('Hello World \n') + +# write the list +# note, here print is used +# It inserts spaces between arguments and appends the line terminator. +l = [0, 1, 2, 3] +print(l, file=fp) +for i in l: + print(i, file=fp) + +for i in l: + print(i, end=' ', file=fp) + + +# write the individual elements +for i in l: + fp.write(str(i)) + +# write the individual elements with a separator +for i in l: + fp.write(str(i) + '/') + +fp.write('\n') + +fp.close() diff --git a/scripts/file_io_writelines_1.py b/scripts/file_io_writelines_1.py new file mode 100644 index 0000000..3f1b432 --- /dev/null +++ b/scripts/file_io_writelines_1.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 28 11:04:44 2018 + +@author: u0015831 +""" + +fp = open('testfile-writelines.txt','w') + +fp.write('Hello World') +fp.write('Hello World \n') + +# write the list +l = [1, 2, 3] +l_str = map(str, l) +fp.writelines(l_str) + + +fp.close() + diff --git a/scripts/file_read_csv_dict.py b/scripts/file_read_csv_dict.py new file mode 100644 index 0000000..cdc16ad --- /dev/null +++ b/scripts/file_read_csv_dict.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 24 17:35:22 2019 + +source: https://www.alexkras.com/how-to-read-csv-file-in-python/ + +""" + +import csv +with open('MOCK_DATA.csv') as f: + reader = csv.DictReader(f) + data = [r for r in reader] + +print('type(data): ', type(data)) +print(data[0]['id']) \ No newline at end of file diff --git a/scripts/file_read_csv_list.py b/scripts/file_read_csv_list.py new file mode 100644 index 0000000..3f16f9c --- /dev/null +++ b/scripts/file_read_csv_list.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 24 17:32:57 2019 + +source: https://www.alexkras.com/how-to-read-csv-file-in-python/ +""" + +import csv +with open('MOCK_DATA.csv') as f: + reader = csv.reader(f) + next(reader) # skip header + data = [] + for row in reader: + data.append(row) \ No newline at end of file diff --git a/scripts/file_read_from_csv.py b/scripts/file_read_from_csv.py new file mode 100644 index 0000000..0b9720c --- /dev/null +++ b/scripts/file_read_from_csv.py @@ -0,0 +1,15 @@ +from csv import Sniffer, DictReader + +file_name = 'people_data.csv' +with open(file_name, 'rb') as csv_file: + dialect = Sniffer().sniff(csv_file.read(1024)) + csv_file.seek(0) + sum = 0.0 + csv_reader = DictReader(csv_file, fieldnames=None, + restkey='rest', restval=None, + dialect=dialect) + for row in csv_reader: + print('{name} --- {weight}'.format(name=row['name'], + weight=row['weight'])) + sum += float(row['weight']) + print('sum = {0}'.format(sum)) diff --git a/scripts/file_squares.txt b/scripts/file_squares.txt new file mode 100644 index 0000000..08b3b28 --- /dev/null +++ b/scripts/file_squares.txt @@ -0,0 +1,10 @@ +0: 0 +1: 1 +2: 4 +3: 9 +4: 16 +5: 25 +6: 36 +7: 49 +8: 64 +9: 81 diff --git a/scripts/file_write_csv.py b/scripts/file_write_csv.py new file mode 100644 index 0000000..a6638aa --- /dev/null +++ b/scripts/file_write_csv.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 24 17:43:58 2019 + +https://www.tutorialspoint.com/reading-and-writing-csv-file-using-python +""" + +# use writerow +import csv +csvData = [('Peter', '22'), ('Jasmine', '21'), ('Sam', '24')] +csvFile = open('person.csv', 'w', newline='') +obj=csv.writer(csvFile) + +for person in csvData: + obj.writerow(person) + +csvFile.close() + +#use writerows +csvfile = open('persons_bis.csv','w', newline='') +obj = csv.writer(csvfile) +obj.writerows(csvData) +csvFile.close() diff --git a/scripts/first_1.py b/scripts/first_1.py new file mode 100644 index 0000000..a3f3d3a --- /dev/null +++ b/scripts/first_1.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Spyder Editor + +This is a temporary script file. +""" + +a = 1 +b = 2.2 +c = a + b +print(c) diff --git a/scripts/first_15.py b/scripts/first_15.py new file mode 100644 index 0000000..2d75e78 --- /dev/null +++ b/scripts/first_15.py @@ -0,0 +1,4 @@ +a = 1 +b = 3.3 +c = a + b +print(c, a, b) \ No newline at end of file diff --git a/scripts/first_prog_1.py b/scripts/first_prog_1.py new file mode 100644 index 0000000..f2b8f83 --- /dev/null +++ b/scripts/first_prog_1.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +""" + +@author: u0015831 +""" + +a = 8 +b = 9.9 +c = a + b +print('c = ', c) + +#%% +a = 88 +d = 9.76 +r1 = a * d +print('r1 =', r1) + +# ============================================================================= +# +# ============================================================================= +if (a > 50): + print('a is larger than 50') +else: + print('a is smaller or equal to 50') + + \ No newline at end of file diff --git a/scripts/first_sum.py b/scripts/first_sum.py new file mode 100644 index 0000000..938fb48 --- /dev/null +++ b/scripts/first_sum.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 25 09:48:16 2019 + +@author: u0015831 +""" + +a = 1 +b = 7 +c = a + b +print(a+b) + +if (a > 6): + print('a larger than 6') + diff --git a/scripts/for_loop_1.py b/scripts/for_loop_1.py new file mode 100644 index 0000000..93e79e5 --- /dev/null +++ b/scripts/for_loop_1.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 17 16:51:05 2019 +calculate the average of a list of numbers +@author: u0015831 +""" + +#rli = range(1, 10, 2) +#for i in rli: +# print('i=', i) + + +sum=0 +numbers =[1,22,31,45] +for num in numbers: + print(num) + sum=sum+num +avg=sum/len(numbers) +print ('Average:', avg) + + \ No newline at end of file diff --git a/scripts/for_loop_2.py b/scripts/for_loop_2.py new file mode 100644 index 0000000..341d923 --- /dev/null +++ b/scripts/for_loop_2.py @@ -0,0 +1,2 @@ +for i in range(1, 101): + print(i) \ No newline at end of file diff --git a/scripts/for_loop_else.py b/scripts/for_loop_else.py new file mode 100644 index 0000000..ff680fe --- /dev/null +++ b/scripts/for_loop_else.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 12 13:57:24 2023 + +@author: u0015831 +""" + +numbers =[1,2,3,4] +for i in numbers: + print(i) + if i > 2: # try with 8 + break +else: # Not executed as there is a break + print("No Break") diff --git a/scripts/for_loop_index.py b/scripts/for_loop_index.py new file mode 100644 index 0000000..ca240f4 --- /dev/null +++ b/scripts/for_loop_index.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 20 15:57:29 2018 +for loop with index +@author: u0015831 +""" +fruitslist = ['banana', 'apple', 'mango'] +for i in range(len(fruitslist)): + print("Color {}: {}".format(i + 1, fruitslist[i])) +print +# use of enumerate +for line in enumerate(fruitslist, start=1): + print(line) +print# use of enumerate +for num, color in enumerate(fruitslist, start=1): + print("Color {}: {}".format(num, color)) +print +# is this working? +fruitset = {'banana', 'apple', 'mango'} +for num, color in enumerate(fruitset, start=1): + print("Color {}: {}".format(num, color)) \ No newline at end of file diff --git a/scripts/for_loop_list.py b/scripts/for_loop_list.py new file mode 100644 index 0000000..6870485 --- /dev/null +++ b/scripts/for_loop_list.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 20 14:20:38 2018 + +@author: u0015831 +""" + +#my_list = [1, 2, 32] +my_list = (1, 2, 3) + +for i in my_list: + print(my_list[i]) \ No newline at end of file diff --git a/scripts/for_loop_sequence.py b/scripts/for_loop_sequence.py new file mode 100644 index 0000000..fbfb90e --- /dev/null +++ b/scripts/for_loop_sequence.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 20 15:46:16 2018 +for loop on different sequences + +source: https://www.tutorialspoint.com/python/python_for_loop.htm +@author: u0015831 +""" + +for letter in 'Python': # First Example + print('Current Letter :', letter) + +fruitslist = ['banana', 'apple', 'mango'] +for fruit in fruitslist: # Second Example + print('Current fruit :', fruit) +print() +fruitstuple = ('banana', 'apple', 'mango') +for fruit in fruitstuple: # Third Example + print('Current fruit :', fruit) +print() +fruitset = {'banana', 'apple', 'mango'} +for fruit in fruitset: # Fourth Example + print('Current fruit :', fruit) diff --git a/scripts/for_loop_vanrossum_1.py b/scripts/for_loop_vanrossum_1.py new file mode 100644 index 0000000..d965c2e --- /dev/null +++ b/scripts/for_loop_vanrossum_1.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Spyder Editor + +example for loop from Python tutorial R 3.7.0 +""" +words = ['cat', 'window', 'defenestrate'] + + +for w in words[:]: # Loop over a slice copy of the entire list. +#for w in words: # Loop over the sequence, beware for an infinite list!. + if len(w) > 6: + words.insert(0, w) + +print(words) \ No newline at end of file diff --git a/scripts/for_loop_zip.py b/scripts/for_loop_zip.py new file mode 100644 index 0000000..96ca450 --- /dev/null +++ b/scripts/for_loop_zip.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 20 16:25:00 2018 + +source: http://treyhunner.com/2016/04/how-to-loop-with-indexes-in-python/ +@author: u0015831 +""" + +fruitslist = ['banana', 'apple', 'mango'] +ratios = [0.2, 0.3, 0.1, 0.4] +winelist = ['merlot', 'chenin', 'chardonnay', 'temperanillo', 'whatever'] +for fruit, ratio, wine in zip(fruitslist, ratios, winelist): + print('{}% {} more {}'.format(ratio * 100, fruit, wine)) diff --git a/scripts/format_io_1.py b/scripts/format_io_1.py new file mode 100644 index 0000000..75523c1 --- /dev/null +++ b/scripts/format_io_1.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 28 14:53:41 2018 + +source: https://www.digitalocean.com/community/tutorials/how-to-use-string-formatters-in-python-3 +@author: u0015831 +""" + +print("Sammy ate {0:f} percent of a {1}!".format(75, "pizza")) +print("Sammy ate {0:6.2f} percent of a {1}!".format(75, "pizza")) +print("Sammy ate {0:x} percent of a {1}!".format(75, "pizza")) +print("Sammy ate {0:3d} percent of a {1}!".format(75, "pizza")) + +for i in range(3,13): + print("{:3d} {:4d} {:5d}".format(i, i*i, i*i*i)) \ No newline at end of file diff --git a/scripts/format_string.py b/scripts/format_string.py new file mode 100644 index 0000000..58607d7 --- /dev/null +++ b/scripts/format_string.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Sep 1 16:11:26 2023 + +Number formatting in f-strings + +""" + +name = 'Jane' +age = 53 +print('%s is %d years old' % (name, age)) # old school deprecated +print('{} is {} years old'.format(name, age)) +print(f'{name} is {age} years old') # preferred + + +# arithmetic expressions allowed +a = 5 +b = 10 +print(f'a plus b is {a + b} and 2 times a minus b is {2*a-b}') + +# The = specifier will print the expression and its value: +fnum = 2007.12345 +print(f"Simple = {fnum}") +print(f"Decimal Places specified = {fnum=:.2f}") +print(f"Significant Figures={fnum:.3g}") diff --git a/scripts/fstring_01.py b/scripts/fstring_01.py new file mode 100644 index 0000000..58607d7 --- /dev/null +++ b/scripts/fstring_01.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Sep 1 16:11:26 2023 + +Number formatting in f-strings + +""" + +name = 'Jane' +age = 53 +print('%s is %d years old' % (name, age)) # old school deprecated +print('{} is {} years old'.format(name, age)) +print(f'{name} is {age} years old') # preferred + + +# arithmetic expressions allowed +a = 5 +b = 10 +print(f'a plus b is {a + b} and 2 times a minus b is {2*a-b}') + +# The = specifier will print the expression and its value: +fnum = 2007.12345 +print(f"Simple = {fnum}") +print(f"Decimal Places specified = {fnum=:.2f}") +print(f"Significant Figures={fnum:.3g}") diff --git a/scripts/function_1.py b/scripts/function_1.py new file mode 100644 index 0000000..b7dbd7f --- /dev/null +++ b/scripts/function_1.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +""" + +basic example using function + +demo 1: copy main part in front of the function definitions + check the behavior of the IDE + +demo 2: run program in editor / debug mode + +@author: u0015831 +""" + + +# main part, calling the functions + + +def my_func_1 (): + """ + this function writes hello, no input, no output + """ + print('Hello') + +def my_func_2(a, b): + """ + parameters: + a: first part of mathematical manip + b: second part in mathematical manip + + """ + res = a + b + return (res) + +def my_func_3(a, b): + """ + parameters: + a: first part of mathematical manip + b: second part in mathematical manip + """ + res1 = a + b + res2 = a - b + return (res1, res2) + + + +my_func_1() + +my_func_2(5,6) # effect? +r1 = my_func_2(5,6) +print(type(r1)) +print(r1) + +r2 = my_func_3(5,6) +print(type(r2)) +print(r2) + +r3 = my_func_3(b=5,a=6) +print(type(r3)) +print(r3) \ No newline at end of file diff --git a/scripts/function_arg_kwarg.py b/scripts/function_arg_kwarg.py new file mode 100644 index 0000000..a9f7b9c --- /dev/null +++ b/scripts/function_arg_kwarg.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jul 4 10:14:49 2018 + +source: + https://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/ + https://code.tutsplus.com/articles/understanding-args-and-kwargs-in-python--cms-29494 + https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3 +@author: u0015831 +""" + +def test_var_args(farg, *args): + print("formal arg:", farg) + for arg in args: + print("another arg:", arg, " - type", type(arg)) + +def test_var_kwargs(farg, **kwargs): + print("formal arg:", farg) + for key in kwargs: + print("another keyword arg: %s: %s" % (key, kwargs[key])) + +def multiply(*args): + z = 1 + for num in args: + z *= num + print(z) + print('final result: ',z) + + +#using the functions +test_var_args(1, "two", 3) + +test_var_kwargs(farg=1, myarg2="two", myarg3=3) +test_var_kwargs(100, myarg2="two", myarg3=3) +#test_var_kwargs(101, "two", myarg3=3) # only 1 argument + +multiply(2, 3) +multiply(2, 3, 99, 12.7) diff --git a/scripts/function_arg_kwarg_1.py b/scripts/function_arg_kwarg_1.py new file mode 100644 index 0000000..56e7f02 --- /dev/null +++ b/scripts/function_arg_kwarg_1.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 12 13:14:08 2022 + +@author: u0015831 +""" + +def arg_printer(*args, **kwargs): + if args: + print('positional') + for arg in args: + print(arg) + if kwargs: + print('named') + for k, v in kwargs.items(): + print("{}={}".format(k, v)) + +print('first test') +arg_printer(1,2,3) + +print('test 2') +arg_printer(1,2,3,sweater=100,hat=5) + diff --git a/scripts/function_argument_pass_1.py b/scripts/function_argument_pass_1.py new file mode 100644 index 0000000..4f7ed55 --- /dev/null +++ b/scripts/function_argument_pass_1.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 27 11:42:31 2018 + +source: https://cs.nyu.edu/courses/summer16/CSCI-UA.0002-002/slides/Python_Functions.pdf +@author: u0015831 +""" + +def change_me(v): + print ("function got:", v, 'id(v) = ', id(v)) + v = 10 + print ("argument is now:", v, 'id(v) = ', id(v)) + +def change_me_bis(v): + print ("function got:", v, 'id(v) = ', id(v)) + v.append(555) + print ("argument is now:", v, 'id(v) = ', id(v)) + +def change_me_tris(v): + print ("function got:", v, 'id(v) = ', id(v)) + v = v * 3 + print ("argument is now:", v, 'id(v) = ', id(v)) + + +myvar = 5 +myvar2 = [1, 2, 3] + +# testing change_me +print('\n testing change_me') +print ("starting with:", myvar) +print ("starting with id:", id(myvar)) +change_me(myvar) +print ("ending with:", myvar) + +print ("starting with:", myvar2) +print ("starting with id:", id(myvar2)) +change_me(myvar2) +print ("ending with:", myvar2) + + +# testing change_me_bis +print('\n testing change_me_bis') + +print ("starting with:", myvar2) +print ("starting with id:", id(myvar2)) +change_me_bis(myvar2) +print ("ending with:", myvar2) + + + +# testing change_me_tris +print('\n testing change_me_tris') + +myvar = 5 +print ("starting with:", myvar) +change_me_tris(myvar) +print ("ending with:", myvar) + +myvar2 = [1, 2, 3] +print ("starting with:", myvar2) +change_me_tris(myvar2) +print ("ending with:", myvar2) diff --git a/scripts/function_on_list.py b/scripts/function_on_list.py new file mode 100644 index 0000000..5ea0995 --- /dev/null +++ b/scripts/function_on_list.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jun 29 17:00:09 2018 + +function on list + +source: http://www.cs.cornell.edu/courses/cs1110/2018sp/ +""" + + +def add_one(the_list): + """Adds 1 to every elt + Pre: the_list is all numb.""" + for x in the_list: + x = x+1 + +def add_one_bis(the_list): + """Adds 1 to every elt + Pre: the_list is all numb.""" + lenl = len(the_list) + lll = list(range(lenl)) + for i in lll: + the_list[i] = the_list[i]+1 + +grades = [5,4,7] + +add_one(grades) +print(grades) + +add_one_bis(grades) +print(grades) diff --git a/scripts/function_optional_arguments.py b/scripts/function_optional_arguments.py new file mode 100644 index 0000000..7638314 --- /dev/null +++ b/scripts/function_optional_arguments.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 27 11:00:12 2018 + +source: https://www.pythoncentral.io/fun-with-python-function-parameters/ +@author: u0015831 +""" + +def foo(val1, val2, val3, calcSum=True): + # Calculate the sum + if calcSum: + return val1 + val2 - val3 + # Calculate the average instead + else: + return (val1 + val2 + val3) / 3 + +print(foo(10,20,30, True)) +print(foo(10,20,30, False)) +print(foo(10,20,30)) + +print(foo(val1=10,val3=20,val2=30,calcSum=True)) + + +# will this work? +#print(foo(10,20)) +#print(foo(10,20,False)) +#print(foo(val1=10,val3=20,val2=30,True)) diff --git a/scripts/function_pass_mutable.py b/scripts/function_pass_mutable.py new file mode 100644 index 0000000..e4f38f8 --- /dev/null +++ b/scripts/function_pass_mutable.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 12 12:11:11 2022 + +@author: u0015831 +""" + +def myfunction (seq): + print ("Entering sequence inside a function: ", seq, ' id', id(seq)) + seq.append(40) + print ("Modified sequence inside a function: ", seq, ' id', id(seq)) + seq = [1, 2, 3] + print ("New sequence inside a function: ", seq, ' id', id(seq)) + return + +mylist=[10,20,30] +print('mylist before call', mylist, ' id', id(mylist)) +myfunction(mylist) +print('mylist after call', mylist, ' id', id(mylist)) diff --git a/scripts/function_pass_nonmutable.py b/scripts/function_pass_nonmutable.py new file mode 100644 index 0000000..17be7fa --- /dev/null +++ b/scripts/function_pass_nonmutable.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 12 12:09:32 2022 + +@author: u0015831 +""" + +def myfunction(arg): + print ('value received:',arg,'id:',id(arg)) + arg = 8 + print ('value changed:',arg,'id:',id(arg)) + return + +#id() function returns a unique integer corresponding to the identity of an object. + +x=10 +print ('value passed:',x, 'id:',id(x)) + +myfunction(x) +print ('value after function call:',x, 'id:',id(x)) diff --git a/scripts/function_return.py b/scripts/function_return.py new file mode 100644 index 0000000..8cb5286 --- /dev/null +++ b/scripts/function_return.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 12 16:40:19 2023 + +@author: u0015831 +""" + +def test(p1=10): + + if (p1 < 10): + return ('abc', 100) + elif (p1 == 10): + return ('default value') + else: + return 0 + + +# +t1 = test(6) +print(type(t1), t1) + +t1 = test() +print(type(t1), t1) + +t1 = test(1000) +print(type(t1), t1) diff --git a/scripts/function_scope_1.py b/scripts/function_scope_1.py new file mode 100644 index 0000000..3de296f --- /dev/null +++ b/scripts/function_scope_1.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Feb 20 10:21:52 2020 +taken from: https://www.python-course.eu/python3_global_vs_local_variables.php +@author: u0015831 +""" + +def f(): + print(a) + print(s) + +a = 1 +s = "I love Paris in the summer!" +f() \ No newline at end of file diff --git a/scripts/function_scope_2.py b/scripts/function_scope_2.py new file mode 100644 index 0000000..28dcb26 --- /dev/null +++ b/scripts/function_scope_2.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Feb 20 10:28:19 2020 +taken from: https://www.python-course.eu/python3_global_vs_local_variables.php +@author: u0015831 +""" + +def f(): + s = "I love London!" + print(s) + +s = "I love Paris!" +f() +print(s) \ No newline at end of file diff --git a/scripts/function_scope_3.py b/scripts/function_scope_3.py new file mode 100644 index 0000000..1a1de03 --- /dev/null +++ b/scripts/function_scope_3.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Feb 20 10:28:19 2020 +taken from: https://www.python-course.eu/python3_global_vs_local_variables.php +@author: u0015831 +""" + +def f(): + print(s) + s = "I love London!" # considered a local variable + print(s) + +s = "I love Paris!" +f() +print(s) \ No newline at end of file diff --git a/scripts/function_scope_4.py b/scripts/function_scope_4.py new file mode 100644 index 0000000..7194e00 --- /dev/null +++ b/scripts/function_scope_4.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Feb 20 10:28:19 2020 +taken from: https://www.python-course.eu/python3_global_vs_local_variables.php +@author: u0015831 +""" + +def f(): + ''' + example working with global key word + ''' + global s + print(s) + s = "I love London!" # considered a local variable + print(s) + +s = "I love Paris!" +f() +print(s) \ No newline at end of file diff --git a/scripts/function_scope_5.py b/scripts/function_scope_5.py new file mode 100644 index 0000000..8f0d496 --- /dev/null +++ b/scripts/function_scope_5.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 15 09:25:39 2020 + +@author: https://www.tutorialsteacher.com/python/local-and-global-variables-in-python +""" + +def SayHello(): + user='John' + print ("user = ", user) + return + +def SayHello_implicit(): + # user must be known + print ("user = ", user) + return + +def SayHello_global(): + global user + print ("user = ", user) + user = 'Mary' + val_k = 0 + return + + +user = 'Jeff' +SayHello_implicit() +print('user', user) + +user = 'Jeff' +SayHello() +print('user', user) + +user = 'Jeff' +SayHello_global() +print('user', user) +#print(val_k) + diff --git a/scripts/functions.ipynb b/scripts/functions.ipynb new file mode 100644 index 0000000..8e8282e --- /dev/null +++ b/scripts/functions.ipynb @@ -0,0 +1,479 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "code", + "source": "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\nfrom traceback import print_exc", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "# Functions\nFunctions are groups of code that have a name, and can be called\n- A piece of code written to carry out a specified task.\n- This makes code easier to read, maintain and debug.\n- Code can be tested separately.\n- Must be named and created before you can use them.\n- All functions are placed (in general) at the beginning of the programs. \n- The input comes in parentheses after the function name\n - The ordered sequence of variables is strictly called the argument list in the caller and the parameter list in the function definition. \n\n**syntax**\n- Declare the function with the keyword `def` followed by the function name.\n- Write the parameters of the function inside round braces `( )`, and end the declaration with a colon `:`.\n - Empty parentheses when no parameters are used!\n- Add the program statements to be executed.\n - All statements are indented\n- End the function with/without `return` statement.\n - Without the return statement, the function will return an object None.\n - Return multiple values in a tuple ()\n\n```python\ndef function_name(parameters):\n\t\"\"\"docstring\"\"\"\n\tstatement(s)\n return statement\n```\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "Naming rules: \n- Cannot use any of Python’s keywords\n- No spaces\n- First character must be A-Z or a-z or the “_” character\n- After the first character you can use A-Z, a-z, “_” or 0-9\n- Case sensitive\n- Two different functions can’t have the same name", + "metadata": {} + }, + { + "cell_type": "code", + "source": "def greetings(name):\n \"\"\"This function greets the name passed as an argument\"\"\"\n print('Hello, ', name , ' Welcome!')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": 1 + }, + { + "cell_type": "code", + "source": "%whos", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "Variable Type Data/Info\n---------------------------------\ngreetings function \n" + } + ], + "execution_count": 2 + }, + { + "cell_type": "code", + "source": "greetings('jules')\nprint('type greetings: ', type(greetings))\n\nx = greetings('jules')\nprint('type x: ', type(x))", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "Hello, jules Welcome!\ntype greetings: \nHello, jules Welcome!\ntype x: \n" + } + ], + "execution_count": 3 + }, + { + "cell_type": "markdown", + "source": "Once a function is defined a function, call it:\n- Python prompt\n- from another function \n- within Python interpreter environment\n\nTo call a function, type the function name with appropriate parameters.\nThe interpreter must see the function definition before it can be called.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "!notepad greetings_func.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run greetings_func.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Functions can call functions.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "def greetings_more(name):\n \"\"\"This function greets the name passed as an argument\"\"\"\n greetings('Dear')\n greetings(name) ", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": 4 + }, + { + "cell_type": "code", + "source": "%whos\ngreetings_more('Marie')", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "Variable Type Data/Info\n--------------------------------------\ngreetings function \ngreetings_more function \nx NoneType None\nHello, Dear Welcome!\nHello, Marie Welcome!\n" + } + ], + "execution_count": 5 + }, + { + "cell_type": "code", + "source": "!notepad function_1.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run function_1.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "**Passing arguments**\n\nYou can call a function by using the following types of formal arguments\n\n- Required arguments: pass arguments 'by position'\n- Keyword arguments: allows to skip arguments or place them out of order because the Python interpreter is able to use the keywords to match the values with parameters. \n- Default arguments: assume a default value if a value is not provided in the function call.\n- Variable-length arguments\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "A function does not require arguments or returning values", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# no passing of arguments\ndef print_header():\n columns = 40\n print('this is a header')\n#call\nprint_header()", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# no passing of arguments, returning some value\ndef the_ultimate_answer():\n return 42\n#call\nprint('result = ', the_ultimate_answer())", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "result = 42\n" + } + ], + "execution_count": 6 + }, + { + "cell_type": "markdown", + "source": "Code refactoring: define a function once, but call them any number of times.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "def f_avg(num1, num2, num3, num4):\n sum = num1+num2+num3+num4\n avg = sum / 4\n print('first value:', num1)\n print (avg)\nf_avg(100,90,92,77)\nf_avg(100,90,92)", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "def f_avg(num1, num2, num3, num4=999):\n sum = num1+num2+num3+num4\n avg = sum / 4\n print('first value:', num1)\n print (avg)\nf_avg(100,90,92,77)\nf_avg(100,90,92)", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# https://www.tutorialspoint.com/python/python_functions.htm\ndef printinfo(name, age):\n \"This prints a passed info into this function\"\n print(\"Name: \", name)\n print(\"Age \", age)\n return;\n\n# Now you can call printinfo function\nhelp(printinfo)\nprintinfo(age=50, name=\"miki\")\nprintinfo(\"jane\", 45)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "Help on function printinfo in module __main__:\n\nprintinfo(name, age)\n This prints a passed info into this function\n\nName: miki\nAge 50\nName: jane\nAge 45\n" + } + ], + "execution_count": 7 + }, + { + "cell_type": "markdown", + "source": "### Add some flexibility: `*args` and `**kwargs` \n\n`*args`: \nThe number of arguments needs to match. When in doubt on the number of arguments, use the * operator (unpacking operator - * before a variable means “expand this as a sequence”)\n\n\n`**kwargs`:\nworks like *args, but instead of accepting positional arguments it accepts keyword arguments\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "def mySum(*values):\n \"\"\"\n Calculate the sum of values\n Input: integers/floats\n Output: sum value\n \"\"\"\n sumVal = 0\n \n for each in values:\n sumVal += each\n \n return sumVal", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": 8 + }, + { + "cell_type": "code", + "source": "print('run 1: ', mySum(1, 2, 3))\nprint('run 2: ', mySum(1, 2.3, 3.14, 98.7, 110))", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "run 1: 6\nrun 2: 215.14\n" + } + ], + "execution_count": 9 + }, + { + "cell_type": "code", + "source": "# concatenate_2.py\n# source https://realpython.com/python-kwargs-and-args/\ndef concatenate(**words):\n # the iterable object is a standard dict.\n result = \"\"\n for arg in words.values():\n result += arg\n return result\n\nprint(concatenate(a=\"Real\", b=\"Python\", c=\"Is\", d=\"Great\", e=\"!\"))", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "RealPythonIsGreat!\n" + } + ], + "execution_count": 10 + }, + { + "cell_type": "code", + "source": "%run function_arg_kwarg_1.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Passing arguments (by object)\n\nIf the argument is immutable, it will not be changed, even if the function changes it. A local copy will be made within the function block. \n\nIf the variable is mutable, consider 2 cases:\n- Elements of the mutable variable can be changed in place, i.e. the list will be changed even in the caller's scope. \n- If a new list is assigned to the name, the old list will not be affected, i.e. the list in the caller's scope will remain untouched.\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "!notepad function_argument_pass_1.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "def change_me(v):\n print (\"function got:\", v, 'id(v) = ', id(v))\n v = 10\n print (\"argument is now:\", v, 'id(v) = ', id(v))\n\ndef change_me_bis(v):\n print (\"function got:\", v, 'id(v) = ', id(v))\n v.append(555)\n print (\"argument is now:\", v, 'id(v) = ', id(v))\n\ndef change_me_tris(v):\n print (\"function got:\", v, 'id(v) = ', id(v))\n v = v * 3\n print (\"argument is now:\", v, 'id(v) = ', id(v))\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": 11 + }, + { + "cell_type": "code", + "source": "myvar = 5\nprint (\"starting with:\", myvar)\nchange_me(myvar)\nprint (\"ending with:\", myvar)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "starting with: 5\nfunction got: 5 id(v) = 3868540\nargument is now: 10 id(v) = 3868620\nending with: 5\n" + } + ], + "execution_count": 12 + }, + { + "cell_type": "code", + "source": "myvar2 = [1, 2, 3]\nprint (\"starting with:\", myvar2)\nchange_me(myvar2)\nprint (\"ending with:\", myvar2)\n\nprint (\"starting with:\", myvar2)\nchange_me_bis(myvar2)\nprint (\"ending with:\", myvar2)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "starting with: [1, 2, 3]\nfunction got: [1, 2, 3] id(v) = 60858272\nargument is now: 10 id(v) = 3868620\nending with: [1, 2, 3]\nstarting with: [1, 2, 3]\nfunction got: [1, 2, 3] id(v) = 60858272\nargument is now: [1, 2, 3, 555] id(v) = 60858272\nending with: [1, 2, 3, 555]\n" + } + ], + "execution_count": 13 + }, + { + "cell_type": "code", + "source": "myvar = 5\nprint (\"starting with:\", myvar)\nchange_me_tris(myvar)\nprint (\"ending with:\", myvar)\n\nmyvar2 = [1, 2, 3]\nprint (\"starting with:\", myvar2)\nchange_me_tris(myvar2)\nprint (\"ending with:\", myvar2)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "starting with: 5\nfunction got: 5 id(v) = 3868540\nargument is now: 15 id(v) = 3868700\nending with: 5\nstarting with: [1, 2, 3]\nfunction got: [1, 2, 3] id(v) = 69543536\nargument is now: [1, 2, 3, 1, 2, 3, 1, 2, 3] id(v) = 67574144\nending with: [1, 2, 3]\n" + } + ], + "execution_count": 14 + }, + { + "cell_type": "markdown", + "source": "### Return values\n\n- Values are returned by the return statement. It can return an item or an expression. \n- Return: immediate exit.\n- Python functions can return only one item but that item can be any object, in particular a tuple, list, or dictionary.\n- A function may have multiple return statements but only one (the first encountered) will be executed.\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# Function definition is here\ndef calcul(arg1, arg2):\n # Add both the parameters and return them.\"\n calc_sum = arg1 + arg2\n calc_prod = arg1 * arg2\n if (calc_sum >= 10):\n return calc_sum\n if (calc_prod < 0):\n return calc_prod\n return (calc_sum, calc_prod)\n\n\nr1 = calcul(3, 7.89)\nprint(r1)\nr2 = calcul(-3, 7.89)\nprint(r2)\nr3 = calcul(0.56, 7.89)\nprint(r3)\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "10.89\n-23.669999999999998\n(8.45, 4.4184)\n" + } + ], + "execution_count": 15 + }, + { + "cell_type": "markdown", + "source": "### Scope\n- Functions can be considered as a mini program\n- Variables can be created inside functions\n - are considered local to that function. \n - they only exist within that function. \n - Objects outside the scope of the function will not be able to access that variable \n - To create a global variable inside a function, you can use the global keyword.\n Be careful with global variables\n- Variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "Scope variables\n\n- local: variables are defined inside a function body \n- global: variables defined outside", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# var = 'ff'\n# var_bis = 'ffw'\n\ndef ex(s): \n global var \n var = 'abc'\n var_bis = 'def'\n print('inside the function var is ', var)\n print('inside the function var_bis is ', var_bis)\n return s+var\n\n\nprint(ex('f'))\nprint('outside the function var is ', var)\nprint('outside the function var_bis is ', var_bis)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "inside the function var is abc\ninside the function var_bis is def\nfabc\noutside the function var is abc\n" + }, + { + "ename": "", + "evalue": "name 'var_bis' is not defined", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[16]\u001b[39m\u001b[32m, line 15\u001b[39m\n\u001b[32m 13\u001b[39m \u001b[38;5;28mprint\u001b[39m(ex(\u001b[33m'\u001b[39m\u001b[33mf\u001b[39m\u001b[33m'\u001b[39m))\n\u001b[32m 14\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m'\u001b[39m\u001b[33moutside the function var is \u001b[39m\u001b[33m'\u001b[39m, var)\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m'\u001b[39m\u001b[33moutside the function var_bis is \u001b[39m\u001b[33m'\u001b[39m, \u001b[43mvar_bis\u001b[49m)\n", + "\u001b[31mNameError\u001b[39m: name 'var_bis' is not defined" + ], + "output_type": "error" + } + ], + "execution_count": 16 + }, + { + "cell_type": "code", + "source": "!notepad function_scope_5.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run function_scope_5.py", + "metadata": {}, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Module import\n\nIn Python you can reuse code by `import`ing functions from files: import a definition from a module. A file containing the functions is called a module. The file name is the module name with the suffix `.py`.\n\n- Explicit module import : Explicit import of a module preserves the module's content in a namespace. The namespace is then used to refer to its contents with a \".\" between them. E.g.:\n ```python\n import numpy\n arr = numpy.ndarray([1, 2, 3])\n ```\n- Explicit module import by alias. For long module names, use the \"import ... as ...\" \n ```python\n import numpy as np\n arr = np.ndarray([1, 2, 3])\n ```\n- Explicit import of module contents: Sometimes rather than importing the module namespace, just like import a few particular items from the module, use \"from ... import ...“\n ```python\n from numpy import ndarray\n arr = ndarray([1, 2, 3])\n ```\n- Implicit import of module contents: it is sometimes useful to import the entirety of the module contents into the local namespace. This can be done with the \"from ... import *\" \n ```python\n from numpy import *\n arr = ndarray([1, 2, 3])\n ```\nThis pattern should be used sparingly, if at all. The problem is that such imports can sometimes overwrite function names that you do not intend to overwrite, and the implicitness of the statement makes it difficult to determine what has changed.\n\nhttps://nbviewer.jupyter.org/github/jakevdp/WhirlwindTourOfPython/blob/master/13-Modules-and-Packages.ipynb\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "import math\nmath.sin(math.pi)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "execution_count": 17, + "output_type": "execute_result", + "data": { + "text/plain": "1.2246467991473532e-16" + }, + "metadata": {} + } + ], + "execution_count": 17 + }, + { + "cell_type": "code", + "source": "import numpy as np\nnp.sin(np.pi)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "execution_count": 18, + "output_type": "execute_result", + "data": { + "text/plain": "np.float64(1.2246467991473532e-16)" + }, + "metadata": {} + } + ], + "execution_count": 18 + }, + { + "cell_type": "code", + "source": "from math import sin, pi\nsin(pi)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "execution_count": 19, + "output_type": "execute_result", + "data": { + "text/plain": "1.2246467991473532e-16" + }, + "metadata": {} + } + ], + "execution_count": 19 + }, + { + "cell_type": "code", + "source": "from math import *\nsin(pi) ** 2 + cos(pi) ** 2", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "execution_count": 20, + "output_type": "execute_result", + "data": { + "text/plain": "1.0" + }, + "metadata": {} + } + ], + "execution_count": 20 + }, + { + "cell_type": "markdown", + "source": "Lambda expressions create anonymous functions ", + "metadata": {} + }, + { + "cell_type": "code", + "source": "x = lambda a : a + 10\nf = lambda a, b: a + b \nv1 = 8.8\n\nprint('type x:', type(x))\nprint(x(6))\nprint(x(v1))\n\nprint('type f:', type(f))\nprint(f(5.6,6))", + "metadata": {}, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/functions_args_1.py b/scripts/functions_args_1.py new file mode 100644 index 0000000..b793453 --- /dev/null +++ b/scripts/functions_args_1.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jun 26 15:45:23 2018 + +@author: u0015831 +""" +# a regular function definition +def my_sub(a,b): + res = a - b + return (res, a, b) + +# defining a function with default values +def my_min(a=9, b = 2): + res = a - b + return (res, a, b) + +# calling the functions +res = my_sub(1, 2) +print(res) + +res = my_sub(b=10, a=5) +print(res) + +c = 1 +d = 2 +res = my_sub(c, d) +print(res) + +res = my_min() +print(res) + +res = my_min(7, 8) +print(res) diff --git a/scripts/generate_data.py b/scripts/generate_data.py new file mode 100644 index 0000000..a8fcbcd --- /dev/null +++ b/scripts/generate_data.py @@ -0,0 +1,8 @@ +jdef main(): + print('case', 'dim', 'temp') + case_nr = 0 + for dim_nr in [1, 2, 3]: + for temp in [-0.5, 0.0, 0.5]: + case_nr += 1 + print(case_nr, dim_nr, temp) + return 0 diff --git a/scripts/get_help.py b/scripts/get_help.py new file mode 100644 index 0000000..376d68b --- /dev/null +++ b/scripts/get_help.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Nov 6 10:06:04 2019 + +getting help +- dir +- help + +@author: u0015831 +""" + +a = "string" +dir(a) + +help(a.split) diff --git a/scripts/getting_started_jupyter.ipynb b/scripts/getting_started_jupyter.ipynb new file mode 100644 index 0000000..27e5a5a --- /dev/null +++ b/scripts/getting_started_jupyter.ipynb @@ -0,0 +1,328 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Getting Started with Jupyter\n", + "\n", + "See Also: [documentation](https://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Notebook%20Basics.html)\n", + "\n", + "No Python installed? Go to https://try.jupyter.org. \n", + "\n", + "\n", + "Start the notebook server from the command line:\n", + "\n", + "`jupyter notebook`\n", + "\n", + "When the notebook opens in your browser, you will see the Notebook Dashboard, which will show a list of the notebooks, files, and subdirectories in the directory where the notebook server was started. Most of the time, you will wish to start a notebook server in the highest level directory containing notebooks. Often this will be your home directory. Or start the notebook in the folder where you keep your notebook projects.\n", + "\n", + "\n", + "more text" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Basics\n", + "\n", + "This document is a Jupyter notebook, it is built out of cells: text and code. The text cells can be formatted using the *markdown* syntax. The code cells contain code statements, usually Python code. \n", + "It is an interactive environment that enbles you to execute the code cells. \n", + "\n", + "This text block is a *Markdown Cell*. Double click this text and you will be able to edit the text. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Tip: for Mac users, the buttons are different, see the list below\n", + "\n", + "- `Ctrl`: command key ⌘\n", + "- `Shift`: Shift ⇧\n", + "- `Alt`: option ⌥" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## cell mode\n", + "\n", + "Cells can be in 2 modes: **command** mode and **edit** mode. \n", + "\n", + "### Edit mode \n", + "\n", + "- Is indicated by a *green cell border* and a prompt showing in the editor area\n", + "- When a cell is in edit mode, you can type into the cell, like a normal text editor.\n", + "- Enter edit mode by pressing `Enter` or using the mouse to click on a cell’s editor area.\n", + "\n", + "### Command mode\n", + "\n", + "- Is indicated by a *grey cell border with a blue left margin*\n", + "- When you are in command mode, you are able to manipulate the notebook as a whole, but not type into the individual cell. \n", + "- Enter command mode by pressing `Esc` or click the mouse outside the cell’s editor area." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Execute a cell\n", + "\n", + "Running a cell works for both text and code cells.\n", + "\n", + "- `Shift + Enter` runs the current cell, move to cell below, add a new cell when no cell is below\n", + "- `Ctrl + Enter` runs the selected cell \n", + "- `Alt + Enter` runs the current cell, insert a cell below \n", + "\n", + "The piece of code below is a *Code Cell* with a short Python command, computing a value and storing it in a variable. This variable is printed. \n", + "\n", + "To execute the code in the cell below, select it with a click and then either press the `Run` button from the menu bar, or use the keyboard shortcut `Ctrl + enter` " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "my_val = 24 * 69\n", + "print(my_val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Menu / Toolbar\n", + "\n", + "All the actions that you can do on a cell are possible from the Menu / Toolbar. \n", + "\n", + "- You can always start by cleaning up the notebook: `Cell > All Output > Clear`\n", + "- You can run the whole notebook: `Cell > Run All`\n", + "- When in trouble, restart the Kernel: `Kernel > Restart`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1+2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Useful shortcuts while in *command* mode\n", + " \n", + "- `Enter` from command into edit mode\n", + "- `H` show all shortcuts\n", + "- `A` insert cell above\n", + "- `B` insert cell below\n", + "- `X` cut selected cell\n", + "- `C` copy selected cell\n", + "- `V` paste cells below\n", + "- `Shift + V` paste cell above\n", + "- `D D` (press the key twice) delete selected cell\n", + "- `Z` undo cell deletion\n", + "- `Y` change the cell type to Code\n", + "- `M` change the cell type to Markdown\n", + "- `P` open the command palette.\n", + "- `Shift + Space` scroll notebook up\n", + "- `Space` scroll notebook down" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1 < 22.3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "string = 'Hello'\n", + "print(string)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### hands-on\n", + "\n", + "- select a cell, copy it and paste it\n", + "- edit the cell and make some changes\n", + "- execute the cell\n", + "- delete the cell" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "1 <= -22.3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " ## Useful shortcuts while in *edit* mode\n", + " \n", + "- `Esc` from edit into command mode\n", + "- `Tab` code completion or indent\n", + "- `Shift + Tab` tooltip\n", + "- `Ctrl + A` select all\n", + "- `Ctrl + Z` undo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Useful to know\n", + "\n", + "- All cells modify the same global state, so variables that you define by executing a cell can be used in other cells\n", + "- `[prompt number] in front of a code cell`, indicates the execution number. The kernel should have a single, monotonically increasing counter of all execution requests\n", + "- `[*] instead of a prompt number`, indicates that the kernel is busy. Go to the menu Kernel and click Interrupt if you suspect the program . If this does not work click Restart.\n", + "- tab completion works!\n", + "\n", + "### Magic commands\n", + "\n", + "A magic function begins with either a `%` or `%%` sign, and let you perform various useful tasks. Those with a `%` sign work within the environment, and those with a `%%` sign work at the cell level.\n", + "Information of a specific magic function is obtained by putting a `?` behind the command e.g. %magicfunction?\n", + "\n", + "- `%lsmagic`Display the list of magic functions\n", + "- `%time` Times a single statement.\n", + "- `%reset` Delete all variables and names defined in the current namespace.\n", + "- `%run` Run a python script inside a notebook. %run script.py\n", + "- `%who, %who_ls, %whos` Display variables defined in the interactive namespace, with varying levels of verbosity\n", + "- `%pwd`Display the current working directory\n", + "- `!`Run a OS command from within Jupyter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%lsmagic" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%run first_sum.py\n", + "\n", + "%time %run first_sum.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# lauch notepad editor (windows)\n", + "!notepad first_sum.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "%whos" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%cd Temp/PythonDev/\n", + "%pwd" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "who" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "%%time is a cell magic command that measures the execution time of the cell. \n", + "\n", + "The cell contains a Python command that makes the program sleep for two seconds. \n", + "\n", + "The %%time command will measure and print the time it took to execute the cell. \n", + "\n", + "Note that cell magics only work in IPython and Jupyter Notebooks. They are not part of the standard Python language." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%time\n", + "import time\n", + "time.sleep(2) # sleep for two seconds" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/scripts/greetings_bucket.py b/scripts/greetings_bucket.py new file mode 100644 index 0000000..215b734 --- /dev/null +++ b/scripts/greetings_bucket.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 13 16:17:00 2020 + +@author: u0015831 +""" + +def greetings(name): + """This function greets the name passed as an argument""" + print('Hello, ', name , ' Welcome!') + \ No newline at end of file diff --git a/scripts/greetings_calling.py b/scripts/greetings_calling.py new file mode 100644 index 0000000..8422b41 --- /dev/null +++ b/scripts/greetings_calling.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 29 10:12:42 2019 + +basic usage of a function + +@author: u0015831 +""" + +from greetings_bucket import greetings + +# use the function multiple times +greetings('Jan') +greetings('Lieve') +greetings('Jef') + diff --git a/scripts/greetings_func.py b/scripts/greetings_func.py new file mode 100644 index 0000000..b3090d2 --- /dev/null +++ b/scripts/greetings_func.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 29 10:12:42 2019 + +basic usage of a function + +@author: u0015831 +""" + +def greetings(name): + """This function greets the name passed as an argument""" + print('Hello, ', name , ' Welcome!') + + +# use the function multiple times +greetings('Jan') +greetings('Lieve') +greetings('Jef') + diff --git a/scripts/greetings_more_func.py b/scripts/greetings_more_func.py new file mode 100644 index 0000000..832f60a --- /dev/null +++ b/scripts/greetings_more_func.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 29 10:27:05 2019 + +@author: u0015831 +""" + +def greetings_more(name): + """This function greets the name passed as an argument""" + greetings('Dear') + greetings(name) + +def greetings(name): + """This function greets the name passed as an argument""" + print('Hello, ', name , ' Welcome!') + + +greetings_more('Marie') \ No newline at end of file diff --git a/scripts/handson_lists.py b/scripts/handson_lists.py new file mode 100644 index 0000000..7330710 --- /dev/null +++ b/scripts/handson_lists.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jun 19 15:36:15 2018 + +handson lists +@author: u0015831 +""" + +NumList=list(range(10)) + +# Print the length of the list +ll = len(NumList) +print("length list", ll) + +# Change the fourth element to 11 +NumList[3] = 11 + +# Extend the list with L=[20,30,40] +NumList.extend([20, 30, 40]) +print(NumList) + +# Print the index of the item 9 +i9 = NumList.index(9) +print("index of item 9", i9) + +# Remove that item from the list +NumList.remove(9) + +# Print the current length of the list +print("current length of list: ", len(NumList)) + +# Sort the list and then reverse the sorted version +NumList.sort +Lreversed=NumList[::-1] +print(Lreversed) \ No newline at end of file diff --git a/scripts/hello.py b/scripts/hello.py new file mode 100644 index 0000000..97d5019 --- /dev/null +++ b/scripts/hello.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 11:14:17 2019 + +@author: u0015831 +""" + +def hello(): + """ + Prints "Hello World". + Returns: + None + """ + + print('Hello World') + return + +def hello_again(): + """ + Prints "Hello World again". + Returns: + None + """ + + print('Hello World again') + return + +print('The docstring of the function hello: ' + hello.__doc__) +print('The docstring of the function hello_again: ' + hello_again.__doc__) diff --git a/scripts/hello_world.py b/scripts/hello_world.py new file mode 100644 index 0000000..456fdb0 --- /dev/null +++ b/scripts/hello_world.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +# ============================================================================= +# print('hello world') +# print('hello world') +# print('hello world') +# ============================================================================= +print('hello world') # more +print('hello class') # text diff --git a/scripts/hello_world_function.py b/scripts/hello_world_function.py new file mode 100644 index 0000000..aaefb2a --- /dev/null +++ b/scripts/hello_world_function.py @@ -0,0 +1,16 @@ +m# -*- coding: utf-8 -*- +""" +Created on Mon Nov 25 17:02:29 2019 + +@author: u0015831 +""" + + +def hello(): + """Print "Hello World" """ + print("Later World") + +# Main program starts here +# once executed, the function hello is known +# the function can be called at the console +hello() diff --git a/scripts/hello_world_input.py b/scripts/hello_world_input.py new file mode 100644 index 0000000..8dd0958 --- /dev/null +++ b/scripts/hello_world_input.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +print('hello world') + +input('Press Enter to Continue...') \ No newline at end of file diff --git a/scripts/hi_python.py b/scripts/hi_python.py new file mode 100644 index 0000000..7e998a9 --- /dev/null +++ b/scripts/hi_python.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri May 31 14:00:55 2019 + +@author: u0015831 +""" + +print("Hi, this is a Python program") diff --git a/scripts/if_1.py b/scripts/if_1.py new file mode 100644 index 0000000..16c6f35 --- /dev/null +++ b/scripts/if_1.py @@ -0,0 +1,24 @@ +1# -*- coding: utf-8 -*- +""" +Created on Fri Jun 15 09:49:23 2018 + +Basic if statement + +source: http://anh.cs.luc.edu/handsonPythonTutorial/ifstatements.html +@author: u0015831 +""" +ipay = 0 +weight = float(input("How many pounds does your suitcase weigh? ")) +if weight > 50: + print("There is a $25 charge for luggage that heavy.") + ipay = 1 +print("Thank you for your business.") + +balance = float(input("Enter the balance on your account ")) +if ipay == 1: + balance = balance - 25 + if balance < 0: + print("negative balance!") + +print("Your balance is :", balance) + \ No newline at end of file diff --git a/scripts/if_else_1.py b/scripts/if_else_1.py new file mode 100644 index 0000000..df93b76 --- /dev/null +++ b/scripts/if_else_1.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jun 15 09:43:06 2018 + +basic if else statement + +@author: u0015831 +""" + +from random import randint + +# use the input function, specify with int-casting that an integer is expected +x = int(input('Give me a number: ')) +if x < 0: + print(x, 'is negative') +else: + print(x, 'is positive') + + +xr = randint(1, 100) +print('xr = ', xr) +xn = x + xr + +if xn == 0: + print("The sum is equal to 0") +else: + if xn < 0: + print(xn, 'is negative') + else: + print(xn, 'is positive') diff --git a/scripts/import_1.py b/scripts/import_1.py new file mode 100644 index 0000000..b2b4fef --- /dev/null +++ b/scripts/import_1.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 20:48:23 2019 + +@author: u0015831 +""" + +import math +print(math.pi) \ No newline at end of file diff --git a/scripts/input_1.py b/scripts/input_1.py new file mode 100644 index 0000000..340f98b --- /dev/null +++ b/scripts/input_1.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 27 14:22:32 2018 + +source: https://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/io.html +@author: u0015831 +""" + +name = input('Enter your name: ') +print('Hello ' + name + '!') +print(type(name)) +age = input('Enter your age: ') +print(age) +print(type(age)) + +#use typecasting +xString = input("Enter a number: ") +x = float(xString) +yString = input("Enter a second number: ") +y = float(yString) +print('The sum of ', x, ' and ', y, ' is ', x+y, '.') \ No newline at end of file diff --git a/scripts/intro_to_numpy.ipynb b/scripts/intro_to_numpy.ipynb new file mode 100644 index 0000000..f865196 --- /dev/null +++ b/scripts/intro_to_numpy.ipynb @@ -0,0 +1,824 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to Numpy arrays\n", + "\n", + "\n", + "sources:\n", + "\n", + "* https://pythonnumericalmethods.berkeley.edu/notebooks/chapter02.07-Introducing_numpy_arrays.html\n", + "* http://justinbois.github.io/bootcamp/2023/lessons/l21_intro_to_numpy_and_scipy.html\n", + "* https://numpy.org/doc/stable/user/basics.creation.html\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Import the NumPy package with the `np` alias, the convention is to use the `np` abbreviation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## A very brief introduction to NumPy arrays\n", + "\n", + "The central object for NumPy and SciPy is `ndarray`, \"NumPy array.\" This is an array object that is convenient for scientific computing. \n", + "\n", + "NumPy arrays are homogeneous, meaning all elements must be of the same data type. They are similar to Python lists but offer more functionality, especially for numerical operations.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create an array\n", + "\n", + "There are several mechanisms for creating arrays as mentioned in the NumPy documentation:\n", + "\n", + "* Conversion from other Python structures (i.e. lists and tuples)\n", + "* Intrinsic NumPy array creation functions (e.g. arange, ones, zeros, etc.)\n", + "* Replicating, joining, or mutating existing arrays\n", + "* Reading arrays from disk, either from standard or custom formats\n", + "* Creating arrays from raw bytes through the use of strings or buffers\n", + "* Use of special library functions (e.g., random)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Conversion from other Python structures\n", + "\n", + "convert to a NumPy array using `np.array()`\n", + "\n", + "NumPy arrays can be defined using Python sequences such as lists and tuples. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a 1D numpy array\n", + "arr1 = np.array([10, 20, 30, 40])\n", + "\n", + "print(arr1)\n", + "print(type(arr1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Create a 2D numpy array\n", + "arr2 = np.array([[10,20,30],[40,50,60]])\n", + "\n", + "print(arr2)\n", + "print(type(arr2))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a 2D numpy array\n", + "arr3 = np.array([[[10, 20], [30, 40]], [[50, 60], [70, 80]]])\n", + "\n", + "print(arr3)\n", + "print(type(arr3))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a 1D numpy array\n", + "arrt1 = np.array((10.2, 20, 30, 40))\n", + "\n", + "print(arrt1)\n", + "print(type(arrt1))\n", + "\n", + "# Create a 2D numpy array\n", + "arrt2 = np.array(((10, 20, 30, 40),(50.2,60,70,80)))\n", + "\n", + "print(arrt2)\n", + "print(type(arrt2))\n", + "\n", + "# Create a 2D numpy array\n", + "arrt3 = np.array((((10, 20), (30, 40.2)), ((50, 60), (70, 80))))\n", + "\n", + "print(arrt3)\n", + "print(type(arrt3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When using numpy.array to define a new array, consider the `dtype` of the elements in the array, which can be specified explicitly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arr1_int8 = np.array([120, 121, 122], dtype=np.int8)\n", + "print(arr1_int8)\n", + "print(type(arr1_int8))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "help(np.array)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Intrinsic NumPy array creation functions \n", + "\n", + "use `arange`, `ones`, `zeros`, etc.\n", + "check the routines at: https://numpy.org/doc/stable/reference/routines.array-creation.html#routines-array-creation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arr_i_1 = np.arange(10)\n", + "print(arr_i_1)\n", + "\n", + "arr_i_2 = np.arange(2, 10, dtype=float)\n", + "print(arr_i_2)\n", + "\n", + "arr_i_3 = np.arange(2, 3, 0.1)\n", + "print(arr_i_3)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "az_1 = np.zeros(5)\n", + "print(az_1)\n", + "print(az_1.dtype)\n", + "\n", + "az_2 = np.zeros((5,), dtype=int)\n", + "print(az_2)\n", + "print(az_2.dtype)\n", + "\n", + "az_3 = np.zeros((2, 1))\n", + "print(az_3)\n", + "\n", + "az_4 = np.zeros((2, 2))\n", + "print(az_4)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Make a NumPy array filled with zeros the same shape as another NumPy array\n", + "arr22 = np.array([[1, 2], [3, 4]])\n", + "arr_0_22 = np.zeros_like(arr22)\n", + "print(arr_0_22)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arr_d = np.diag([1, 2, 300.])\n", + "print(arr_d)\n", + "\n", + "arr_e = np.eye(3)\n", + "print(arr_e)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reshaping, concatenating arrays\n", + "Once arrays are been created, these can be transformed to create new arrays. \n", + "When you assign an array or its elements to a new variable, you have to explicitly numpy.copy the array, otherwise the variable is a view into the original array." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# reshape with shape \n", + "vec1 = np.linspace(3, 9, 10)\n", + "print(vec1)\n", + "\n", + "vec1.shape = (2,5)\n", + "print(vec1)\n", + "\n", + "# a new 2D array using the reshape() method\n", + "arr_vec1 = vec1.reshape((5, 2))\n", + "print(arr_vec1)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Concatenating arrays\n", + "\n", + "The `np.concatenate()` function accomplishes this. We simply have to pass it a tuple containing the NumPy arrays we want to concatenate." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arr2 = np.array([[10,20,30],[40,50,60]])\n", + "arr2b = np.array([[101,201,301],[401,501,601]])\n", + "\n", + "combi_1 = np.concatenate((arr2,arr2b))\n", + "print(combi_1)\n", + "\n", + "combi_2 = np.concatenate((arr2,arr2b), axis=1)\n", + "print(combi_2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## array object\n", + "An array has several attributes and lots of methods, check it with the `dir` function\n", + "\n", + "* `shape`: Returns the dimensions of the array.\n", + "* `dtype`: Returns the data type of the elements in the array.\n", + "* `size`: Returns the total number of elements in the array." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "dir(np.ndarray)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "help(np.ndarray.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# The data type of stored entries\n", + "print(arr3.dtype)\n", + "print(arrt3.dtype)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# The shape of the array\n", + "print(arr1.shape)\n", + "print(arr2.shape)\n", + "print(arr3.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# The size of the array, showing the number of elements\n", + "print(arr1.size)\n", + "print(arr2.size)\n", + "print(arr3.size)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are also lots of methods. \n", + "\n", + "`astype()` converts the data type of the array." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(arr2)\n", + "print(arr2.dtype)\n", + "\n", + "float_arr2 = arr2.astype(float)\n", + "print(float_arr2)\n", + "print(float_arr2.dtype)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are many others, compute summary statistics" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(arr2.max())\n", + "print(arr2.min())\n", + "print(arr2.sum())\n", + "print(arr2.mean())\n", + "print(arr2.std())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "NumPy arrays can be arguments to NumPy functions, doing the same operations as the methods." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(np.max(arr2))\n", + "print(np.min(arr2))\n", + "print(np.sum(arr2))\n", + "print(np.mean(arr2))\n", + "print(np.std(arr2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Indexing\n", + "\n", + "Getting access to the 1D numpy array is similar to lists or tuples, it has an index to indicate the location. It is 0-based, and accepts negative indices for indexing from the end of the array.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arr = np.array([1, 4, 3])\n", + "\n", + "# get an element at a specific index\n", + "print(arr[1])\n", + "\n", + "# linspace(a,b,n) generates an array of n equally spaced elements starting from a and ending at b.\n", + "vec1 = np.linspace(3, 9, 10)\n", + "print(vec1)\n", + "\n", + "print(vec1[-1])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It is not necessary to separate each dimension’s index into its own set of square brackets." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arr2 = np.array([[10,20,30],[40,50,60]])\n", + "\n", + "print(arr2[1,2])\n", + "print(arr2[1][2])\n", + "\n", + "# stay between the boundaries\n", + "print(arr2[2,3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Slicing NumPy arrays\n", + "\n", + "Slice NumPy arrays like lists and tuples. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arr = np.array([1, 4, 3])\n", + "\n", + "# Reversed array\n", + "arr[::-1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Entries 1 to 2\n", + "arr[1:3]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Fancy indexing\n", + "\n", + "NumPy arrays also allow **fancy indexing**, where we can slice out specific values. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x100 = np.arange(1,101)\n", + "x100[[1, 19, 6]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Boolean indexing can be used with Numpy arrays" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# slice out the big ones\n", + "idx_bool = (x100 > 80)\n", + "print(idx_bool)\n", + "\n", + "big_ones = x100[idx_bool]\n", + "print(big_ones)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Get the indices where the values are high through `np.where()`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.where(x100 > 80)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## NumPy arrays are mutable\n", + "\n", + "NumPy arrays are mutable. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Make an array\n", + "my_ar = np.array([1, 2, 3, 4])\n", + "\n", + "# Change an element\n", + "my_ar[2] = 6\n", + "\n", + "# See the result\n", + "my_ar" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, let's try attaching another variable to the NumPy array." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Attach a new variable\n", + "my_ar2 = my_ar\n", + "\n", + "# Set an entry using the new variable\n", + "my_ar2[3] = 9\n", + "\n", + "# Does the original change? (yes.)\n", + "my_ar" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see how messing with NumPy in functions affects things." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create Array from Existing Array\n", + "Create an array from an existing array by copying array elements into the other array.\n", + "\n", + "Using the `copy()` Method\n", + "To create an array from an existing NumPy array Python provides an in-built method that is the copy() method. In simpler words to copy the array elements into another array. If you make changes in an original array that will not be reflected in a copy method. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create array from existing array\n", + "# Using copy()\n", + "arr_0=np.array([10,20,30])\n", + "print(\"Original array\",arr_0)\n", + "print('id arr_0', id(arr_0))\n", + "\n", + "arr_1 = arr_0\n", + "print('arr_1', arr_1)\n", + "print('id arr_1', id(arr_1))\n", + "\n", + "arr_2=arr_0.copy()\n", + "print('arr_2', arr_2)\n", + "print('id arr_2', id(arr_2))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Slices of NumPy arrays are **views**, not copies\n", + "\n", + "A very important distinction between NumPy arrays and lists is that slices of NumPy arrays are **views** into the original NumPy array, NOT copies." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Make list and array\n", + "my_list = [1, 2, 3, 4]\n", + "print(my_list)\n", + "my_ar = np.array(my_list)\n", + "print(my_ar)\n", + "\n", + "# Slice out of each\n", + "my_list_slice = my_list[1:-1]\n", + "print(my_list_slice)\n", + "my_ar_slice = my_ar[1:-1]\n", + "print(my_ar_slice)\n", + "\n", + "# Mess with the slices\n", + "my_list_slice[0] = 9\n", + "my_ar_slice[0] = 9\n", + "\n", + "# Look at originals\n", + "print(my_list)\n", + "print(my_ar)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Mathematical operations with arrays\n", + "\n", + "Mathematical operations on arrays are done elementwise to all elements" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = np.array([1, 2, 3])\n", + "b = np.array([4, 5, 6])\n", + "\n", + "# Element-wise addition\n", + "c = a + b\n", + "print(c)\n", + "\n", + "# Element-wise multiplication\n", + "d = a * b\n", + "print(d)\n", + "\n", + "# Element-wise division\n", + "e = a / b\n", + "print(e)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Multiply by scalar\n", + "-4 * a" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Raise to power\n", + "b**2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "matrix operations like dot products." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "help(np.dot)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = np.array([[1, 2], [3, 4]])\n", + "b = np.array([[1, 1], [1, 1]])\n", + "c = np.dot(a, b)\n", + "print(c)\n", + "\n", + "\n", + "a = np.array([1, 2, 3])\n", + "b = np.array([4, 5, 6])\n", + "c = np.dot(a, b)\n", + "print(c)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## NumPy mathematical functions\n", + "The NumPy functions also work elementwise on the arrays when it is intuitive to do soNumPy provides a set of universal functions that operate element-wise on arrays, including mathematical, logical, and bitwise operations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Showing all functions in NumPy\n", + "dir(np)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "arrx = np.array([1, 2, 3])\n", + "\n", + "print(np.square(arrx)) # Square each element\n", + "\n", + "print(np.sin(arrx)) # Calculate sine of each element" + ] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/scripts/io.ipynb b/scripts/io.ipynb new file mode 100644 index 0000000..a4981f8 --- /dev/null +++ b/scripts/io.ipynb @@ -0,0 +1,445 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "markdown", + "source": "# IO", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\nfrom traceback import print_exc", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Console IO\nsee also https://realpython.com/python-input-output/\n\n### input\nTake input from the user: `input()`\n\n- a prompt can be included\n- `input()` returns a string. \n- need for a numeric type, convert the string to the appropriate type with the `int()`, `float()`, or `complex()` ", + "metadata": {} + }, + { + "cell_type": "code", + "source": "name = input('Enter your name: ')\nprint('Hello ' + name + '!')\nprint(type(name))\nage = input('Enter your age: ')\nprint(age)\nprint(type(age))\n\n#use typecasting\nxString = input(\"Enter a number: \")\nx = float(xString)\nyString = input(\"Enter a second number: \")\ny = float(yString)\nprint('The sum of ', x, ' and ', y, ' is ', x+y, '.')", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run input_1.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### output\n\nDisplay output to the user: `print()`. print automatically puts a single space between items and a newline at the end.\n\nSyntax: `print(objects, sep=' ', end='\\n', file=sys.stdout, flush=False)`\n\n\n- unformatted \n - list variables separated by comma\n - complex types like lists, dictionaries, etc. can be displayed\n- formatted\n - keywords\n - sophisticated way cfr. Matlab `fprintf`, C `printf`\n\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "fname = 'Louis'\nage = 33\nprint('Name:', fname, ', age:', age)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "l1 = [1, 2, 3]\nnumb = -12\nd1 = {'key1': 1, 'key2': 22}\nprint(l1, numb, d1)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# sep\nprint('text', 42, [1, 'zz', 3])\nprint('text', 42, [1, 'zz', 3], sep='/')\nprint('text', 42, [1, 'zz', 3], sep='...')\n\n# end\nprint('text', 42, [1, 'zz', 3], end='/')\nprint('text', 42, [1, 'zz', 3], end='/\\n')\n\nfor n in range(5):\n print(n)\n\nfor n in range(8):\n print(n, end=(' ' if n < 5 else '\\n'))\n ", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "fill-in-the-braces\n\nSyntax: `S.format(item0, item1, item2, ..., itemk)`\n\n- string type has `format()` method which takes arguments and returns another string which is the original with the method’s arguments inserted into it in certain places. \n- `format()` replaces each pair of curly brackets with the corresponding argument. \n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "s1 = 'The {} in the {}'.format('car', 'room') \nprint(s1)\ns2 = '{2} color {1}, {0} {3}'.format('dark', 'brown', 'yellow', 'red') \nprint(s2)\ns3 = '{c} color {b}, {a} {d}'.format(a='dark', b='brown', c='yellow', d='red') \nprint(s3)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### format specifiers\n\n| Conversion | Description |\n|------|-------------------|\n| d | Signed integer decimal.|\n| i | Signed integer decimal.|\n| o | Unsigned octal.|\n| x | Unsigned hexadecimal(lowercase).|\n| X | Unsigned hexadecimal(uppercase).|\n| e | Floating point exponential format (lowercase).|\n| E | Floating point exponential format (uppercase).|\n| f,F | Floating point.|\n| g | Same as \"e\" if exponent is greater than -4 or less than precision, \"f\" otherwise.|\n| G | Same as \"G\" if exponent is greater than -4 or less than precision, \"F\" otherwise.|\n| c | Single character (accepts integer or single character string).|\n| s | String (converts any python object using str()).|\n\n\nJustification codes\n\n|< |left justifies|\n| > |right justifies|\n| ^| centers|\n\nFilling characters\n\n- Character after : pads with that character\n- `+` before the field width forces a preceding sign\n\n\nEscape characters\n\n| Conversion | Description |\n|------|-------------------|\n|single quote \t| \\'|\n|double quote \t|\\\"|\n|backslash \t\t|\\\\|\n|alert (bell) \t|\t\\a|\n|backspace \t\t|\\b|\n|formfeed \t\t|\\f|\n|newline \t\t|\\n|\n|return \t\t|\\r|\n|tab \t\t\t|\\t|\n|vertical tab \t|\t\\v|\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# formatted output\ncount = 5 \namount = 45.56 \nprint('count is {0} and amount is {1:9.5f}'.format(count, amount))\nprint('count is {0:5d} and amount is {1:9.5f}'.format(count, amount))\nprint('count is {:d} and amount is {:f}'.format(count, amount))\nprint('count is {:05d} and amount is {:09.5f}'.format(count, amount))\nprint('count is {:+5d} and amount is {:09.5f}'.format(count, amount))\n\nperson = 'Louis'\ngreeting = 'Hello, {}!'.format(person)\nprint(greeting)\ngreeting = 'Hello, {0}, Good morning, {0}!'.format(person)\nprint(greeting)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# f-string\ncount = 5 \namount = 45.56 \nprint(f'count is {count} and amount is {amount:9.5f}')\nprint(f'count is {count:5d} and amount is {amount:9.5f}')\nprint(f'count is {count:d} and amount is {amount:f}')\nprint(f'count is {count:05d} and amount is {amount:09.5f}')\nprint(f'count is {count:+5d} and amount is {amount:09.5f}')\n\nperson = 'Louis'\ngreeting = f'Hello, {person}!'\nprint(greeting)\ngreeting = f'Hello, {person}, Good morning, {person}!'\nprint(greeting)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Command line IO\n\n- command line parameters live inside of sys.argv, so import sys is needed. \n- sys.argv is a list in Python, which contains the command-line arguments passed to the script.\n- The name of the program is always the first item (argv[0])\n- The elements of argv are strings\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "!notepad command_line_io.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run command_line_io.py a b 1 hello", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## File IO\n\n### Motivation\n\nStoring data is important when working over multiple sessions and sharing the results with collaborators. When Python closes, all the variables in the memory are lost, data must be stored in some way. \n\n### Steps involved\nWorking with files, involves the steps:\n* Opening the file and associating it with a file handle. (`open`)\n* Using the file handle: read from or write to a file\n* Closing the file handle to commit to a disk file. (Do not forget!) (`close`)\n\nopen a file:\n```python\nf = open(\"name.txt\", mode=\"w\", encoding=\"utf8\")\n```\nThe parameters are:\n* name of the file, it can also contain an absolute or a relative path\n* `mode` argument defines how to access the file. \n\nCharacter | Meaning\n:--------:|--------\n'r' | open for reading (default)\n'w' | open for writing, truncating the file first\n'x' | open for exclusive creation, failing if the file already exists\n'a' | open for writing, appending to the end of the file if it exists\n\n* `encoding` parameter defines the character encoding. It is not mandatory.\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "### Writing to a file\n- `f.write(string)`\n - Copies the value of string to the file\n - Returns the number of characters written\n\n- `f.writelines(list)`\n - Copies the value of each element of sequence to the file\n - Does not add a newline after each string - must be explicitly included in the string", + "metadata": {} + }, + { + "cell_type": "code", + "source": "username = input('Enter your name: ')\nf = open('name_01.txt', mode='w', encoding='utf8')\nnumchar = f.write(username)\nprint(numchar)\nf.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type name_01.txt", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# no automatic generation of 'new lines'\nname1 = 'KU Leuven'\nname2 = 'campus Arenberg'\nlistnames = [name1, name2]\nf = open('name_02.txt', mode='w', encoding='utf8')\nf.write(name1)\nf.write(name2)\nf.write('\\n')\nf.writelines(listnames)\nf.write('\\n')\n# or add a new line for each item\nf.writelines(line + '\\n' for line in listnames)\nf.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type name_02.txt", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "write the squares of the values 0, 1, ..., 9 into a file\n\nremark the use of the `with` statement and the block of code. A close statement is not neede when using this approach", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# write to a file\nfile_name = 'file_squares.txt'\nwith open(file_name, 'w') as text_file:\n for i in range(0, 10):\n# text_file.write('{0}: {1}\\n'.format(i, i*i))\n text_file.write(f'{i}: {i*i}\\n')\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type file_squares.txt", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# add to a file\nfile_name = 'file_squares.txt'\nwith open(file_name, 'a') as text_file:\n for i in range(10, 20):\n text_file.write('{0}: {1}\\n'.format(i, i*i))\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type file_squares.txt", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "%run file_io_write_1.py\n!type testfile-write.txt", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Read from a file\n\n* `f.read()` reads the whole file from the current position to the end of the file as a string\n* `f.read(b)` reads `b` bytes of the file, as data is read, a pointer is set of where the next data will be read\n* `f.readline()` reads the data from the current position in the file to the end of that line. \n* `f.readlines()` reads every line of the file and stores them in a list.\n\nTo read the whole text file line by line, you can use `for` loop with the file object:\n```python\nfor line in f:\n print(line)\n```\n\nCaution: `read`, `readline` and `readlines` do not check memory to perform the task.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "txtfile = open(\"file_squares.txt\",\"r\")\ntxt = txtfile.read()\nprint(txt)\nprint('--')\n# what will be printed?\ntxtbis = txtfile.read()\nprint(txtbis)\ntxtfile.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "txtfile = open(\"file_squares.txt\",\"r\")\ntxt = txtfile.read(5)\nprint(txt)\nprint('--')\n# what will be printed?\ntxtbis = txtfile.read(25)\nprint(txtbis)\ntxtfile.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "txtfile = open(\"file_squares.txt\",\"r\")\ntxt = txtfile.readline()\nprint(txt)\nprint('--')\n# what will be printed?\ntxtbis = txtfile.readline()\nprint(txtbis)\ntxtfile.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "txtfile = open(\"file_squares.txt\",\"r\")\ntxt = txtfile.readlines()\nprint(txt)\nprint('--')\n# what will be printed?\ntxtbis = txtfile.readlines()\nprint(txtbis)\ntxtfile.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "txtfile = open(\"test_text.txt\",\"r\")\n\nfor aline in txtfile:\n values = aline.split()\n if len(values) > 10:\n print('some text', values[0], values[1], ' and also ', values[10] )\n\ntxtfile.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "seek() method\n\n`fileObject.seek(offset[, whence])`\n\nParameters\n\n- offset: position of the read/write pointer within the file.\n- whence: optional parameter, defaults to 0 which means absolute file positioning, 1 which means seek relative to the current position and 2 means seek relative to the file's end.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "txtfile = open(\"file_squares.txt\",\"r\")\n# set the file handle to some spot in the file\ntxtfile.seek(50)\ntxt = txtfile.read()\nprint(txt)\ntxtfile.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type file_io_3.py\n%run file_io_3.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type file_io_readline.py\n%run file_io_readline.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!type file_io_readlines.py\n%run file_io_readlines.py", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "The Pythonic way:\n\n```python\nwith open('file_path', 'w') as file: \n file.write('hello world !') \n```\n\nThe `with` statement automatically takes care of closing the file once it leaves the with block, even in cases of error.\nno need to call `file.close()` when using with statement. \n\n`with` statement itself ensures proper acquisition and release of resources. \n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "Nice example from bernd Klein: Numerisches Python\n\n- open a file as input\n- read the data, split the lines, manipulate the data\n- write the results to another file", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# example from bernd Klein: Numerisches Python\nwith open('./Data/bKlein_bundeslaender.txt') as fh_in, \\\n open('./Data/bKlein_bundeslaender_bis.txt', 'w') as fh_out:\n fh_in.readline() # read header input file\n fh_out.write('Land Surface Population PopulationDensity \\n')\n for line in fh_in:\n land, surf, man, women = line.split() # get a line and split into text components\n surf = float(surf)\n population = int(man) + int(women)\n pDensity = round(population * 1000/ surf, 2)\n fh_out.write(land + \" \" + str(surf) + \" \" + str(population) + \" \" + \\\n str(pDensity) + \"\\n\")\n ", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### IO and data formats\n\nuse the __batteries included__\n\nPython provides the csv library. While you can also just simply use `split` function, to separate lines and data within each line, the CSV module can also be used to make things easy.\nEach row read from the csv file is returned as a list of strings.\n\nhttps://docs.python.org/3/library/csv.html\n\nThe csv module's `reader` and `writer` objects read and write sequences. Read and write data in dictionary form using the `DictReader` and `DictWriter` classes.\n\n- `reader`\treturns a reader object which iterates over lines of a CSV file\n- `writer`\treturns a writer object which writes data into CSV file\n- `DictReader` class operates like a regular reader but maps the information read into a dictionary. The keys for the dictionary can be inferred from the first row of the CSV file\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "import csv\n\nwith open('MOCK_DATA.csv') as csvfile:\n readCSV = csv.reader(csvfile, delimiter=',')\n for row in readCSV:\n print(row)\n print(row[0])", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "import csv\n\nwith open('MOCK_DATA.csv') as csvfile:\n readCSV = csv.reader(csvfile, delimiter=',')\n dates = []\n ipads = []\n for row in readCSV:\n date = row[6]\n ipad = row[5]\n dates.append(date)\n ipads.append(ipad)\n\nprint(dates)\nprint(ipads)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "import csv\nfile_name = 'MOCK_DATA.csv'\nf_csv = open(file_name)\ncsv_data = csv.DictReader(f_csv)\nprint(\"Type of object csv_data: {}\\n\".format(type(csv_data)))\nf_csv.close()", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "import csv\nfile_name = 'MOCK_DATA.csv'\nf_csv = open(file_name)\ncsv_data = csv.DictReader(f_csv)\n\nline_count = 1\ndata_dict = dict()\nfor row in csv_data:\n\n# print('Row {:d}: {} (length: {})'.format(line_count, dict(row), len(row)))\n data_dict[line_count] = row\n line_count += 1\n \nf_csv.close()\n\n# use dictionary\nprint(data_dict[54])\nprint(data_dict[154]['last_name'])\nprint(data_dict[254]['ip_address'])\nprint(data_dict[354]['unit cost'])\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "copy data from a file to another", + "metadata": {} + }, + { + "cell_type": "code", + "source": "import csv\nwith open('MOCK_DATA_out.csv' ,'w') as outFile:\n fileWriter = csv.writer(outFile)\n with open('MOCK_DATA.csv','r') as inFile:\n fileReader = csv.reader(inFile)\n for row in fileReader:\n fileWriter.writerow(row)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!notepad 'MOCK_DATA_out.csv'", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# use writerow\nimport csv\ncsvData = [('Peter', '22'), ('Jasmine', '21'), ('Sam', '24')]\ncsvFile = open('person.csv', 'w', newline='')\nobj=csv.writer(csvFile)\n\nfor person in csvData:\n obj.writerow(person)\n \ncsvFile.close()\n\n#use writerows\ncsvfile = open('persons_bis.csv','w', newline='')\nobj = csv.writer(csvfile)\nobj.writerows(csvData)\ncsvFile.close()\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!notepad 'person.csv'", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "!notepad 'persons_bis.csv'", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/isVow_module.py b/scripts/isVow_module.py new file mode 100644 index 0000000..f2f5375 --- /dev/null +++ b/scripts/isVow_module.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 12 14:42:24 2022 + +source: https://sites.pitt.edu/~naraehan/python3/mbb20.html +@author: u0015831 +""" + + +def isVow(char): + return char.lower() in 'aeiou' + +def main(): + print(isVow('i')) + print(isVow('I')) + print(isVow('K')) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/scripts/isVow_script.py b/scripts/isVow_script.py new file mode 100644 index 0000000..e2250f6 --- /dev/null +++ b/scripts/isVow_script.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 12 14:41:13 2022 + +source: https://sites.pitt.edu/~naraehan/python3/mbb20.html + +@author: u0015831 +""" + + +def isVow(char): + return char.lower() in 'aeiou' + +print(isVow('i')) +print(isVow('I')) +print(isVow('K')) diff --git a/scripts/isVow_using.py b/scripts/isVow_using.py new file mode 100644 index 0000000..c98fb24 --- /dev/null +++ b/scripts/isVow_using.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 12 14:43:11 2022 + +@author: u0015831 +""" + +import isVow_script +import isVow_module + + +# call isVow the bad way +# the code in the script file is fully executed, also the test part +print('regular file') +print(isVow_script.isVow('i')) +print(isVow_script.isVow('y')) + + +# call isVow the right way +# only the function itself will be executed +print('name == main') +print(isVow_module.isVow('i')) +print(isVow_module.isVow('y')) \ No newline at end of file diff --git a/scripts/iterator_1.py b/scripts/iterator_1.py new file mode 100644 index 0000000..98349ed --- /dev/null +++ b/scripts/iterator_1.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jul 5 10:32:20 2018 + +@author: u0015831 +""" +# what is range? +xr = range(10) +print(type(xr)) + +for i in range(10): + print(i, end=' ') + +print('\n') + +for value in [2, 4, 6, 8, 10]: +# do some operation + print(value + 1, end=' ') +print('\n') + +# enumerate +L1 = [2, 4, 6, 8, 10] +for i, val in enumerate(L1): + print(i, val) +print('\n') + +L2 = ['pizza', 'pasta', 'salad', 'nachos'] +print(list(enumerate(L2))) +for i, val in enumerate(L2): + print(i, val) + +# zip +L3 = [12.3, 44.56, 99.9, 768.02, 123, 123.56] +zipped = zip(L1, L2, L3) +print(list(zip(L1, L2, L3))) +for v1, v2, v3 in zipped: + print(v1, v2, v3) +print('\n') + +# unzip +e1, e2, e3 = zip(*zip(L1, L2, L3)) + +# map +square = lambda x: x ** 2 +for val in map(square, range(10)): + print(val, end=' / ') +print('\n') + +# find values up to 10 for which x % 2 is zero +is_even = lambda x: x % 2 == 0 +for val in filter(is_even, range(10)): + print(val, end=' ') +print('\n') + diff --git a/scripts/lambda_func_1.py b/scripts/lambda_func_1.py new file mode 100644 index 0000000..b73a7cc --- /dev/null +++ b/scripts/lambda_func_1.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 12 14:25:31 2022 + +@author: u0015831 +""" + +x = lambda a : a + 10 +f = lambda a, b: a + b +v1 = 8.8 + +print('type x:', type(x)) +print(x(6)) +print(x(v1)) + +print('type f:', type(f)) +print(f(5.6,6)) \ No newline at end of file diff --git a/scripts/lines_10.txt b/scripts/lines_10.txt new file mode 100644 index 0000000..7d3e69b --- /dev/null +++ b/scripts/lines_10.txt @@ -0,0 +1,19 @@ +Inhabit hearing perhaps on ye do no. It maids decay as there he. Smallest on suitable disposed do although blessing he juvenile in. Society or if excited forbade. Here name off yet she long sold easy whom. Differed oh cheerful procured pleasure securing suitable in. Hold rich on an he oh fine. Chapter ability shyness article welcome be do on service. + +Mind what no by kept. Celebrated no he decisively thoroughly. Our asked sex point her she seems. New plenty she horses parish design you. Stuff sight equal of my woody. Him children bringing goodness suitable she entirely put far daughter. + +Parish so enable innate in formed missed. Hand two was eat busy fail. Stand smart grave would in so. Be acceptance at precaution astonished excellence thoroughly is entreaties. Who decisively attachment has dispatched. Fruit defer in party me built under first. Forbade him but savings sending ham general. So play do in near park that pain. + +Attachment apartments in delightful by motionless it no. And now she burst sir learn total. Hearing hearted shewing own ask. Solicitude uncommonly use her motionless not collecting age. The properly servants required mistaken outlived bed and. Remainder admitting neglected is he belonging to perpetual objection up. Has widen too you decay begin which asked equal any. + +It prepare is ye nothing blushes up brought. Or as gravity pasture limited evening on. Wicket around beauty say she. Frankness resembled say not new smallness you discovery. Noisier ferrars yet shyness weather ten colonel. Too him himself engaged husband pursuit musical. Man age but him determine consisted therefore. Dinner to beyond regret wished an branch he. Remain bed but expect suffer little repair. + +Had repulsive dashwoods suspicion sincerity but advantage now him. Remark easily garret nor nay. Civil those mrs enjoy shy fat merry. You greatest jointure saw horrible. He private he on be imagine suppose. Fertile beloved evident through no service elderly is. Blind there if every no so at. Own neglected you preferred way sincerity delivered his attempted. To of message cottage windows do besides against uncivil. + +Led ask possible mistress relation elegance eat likewise debating. By message or am nothing amongst chiefly address. The its enable direct men depend highly. Ham windows sixteen who inquiry fortune demands. Is be upon sang fond must shew. Really boy law county she unable her sister. Feet you off its like like six. Among sex are leave law built now. In built table in an rapid blush. Merits behind on afraid or warmly. + +Ecstatic advanced and procured civility not absolute put continue. Overcame breeding or my concerns removing desirous so absolute. My melancholy unpleasing imprudence considered in advantages so impression. Almost unable put piqued talked likely houses her met. Met any nor may through resolve entered. An mr cause tried oh do shade happy. + +Raising say express had chiefly detract demands she. Quiet led own cause three him. Front no party young abode state up. Saved he do fruit woody of to. Met defective are allowance two perceived listening consulted contained. It chicken oh colonel pressed excited suppose to shortly. He improve started no we manners however effects. Prospect humoured mistress to by proposal marianne attended. Simplicity the far admiration preference everything. Up help home head spot an he room in. + +Extended kindness trifling remember he confined outlived if. Assistance sentiments yet unpleasing say. Open they an busy they my such high. An active dinner wishes at unable hardly no talked on. Immediate him her resolving his favourite. Wished denote abroad at branch at. diff --git a/scripts/list.ipynb b/scripts/list.ipynb new file mode 100644 index 0000000..42834fa --- /dev/null +++ b/scripts/list.ipynb @@ -0,0 +1,419 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "code", + "source": "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\nfrom traceback import print_exc", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Key concepts in programming\n\n- Variables (integers, strings, dates, etc.)\n- Flow control (if then, loop, etc.)\n- Functions (list of steps the code will follow)\n\n\n## data containers\n\nOrganize the data structure into four different families: \n- Ordered data structure: list and tuple\n- Unordered data structure: set and dictionary \n- Mutable: list, set and dictionary \n- Immutable: tuple \n\n\n| Type | Example | Description |\n|------|---------|---------|\n| list | `[1, 2, 3]` | Ordered collection|\n| tuple | `(1, 2, 3)` | Immutable ordered collection|\n| dict | `{'a':1, 'b':2, 'c':3}` | Unordered (key:value) pair mapping|\n| set | `{1, 2, 3}` | Unordered collection of unique values |\n\n\n## operations on any sequence\n\n| Operation | Operator | Description |\n|------|---------|---------|\n| indexing | `[]` | Access an element of a sequence |\n|concatenation | `+` | Combine sequences together|\n| repetition | `*` | Concatenate a repeated number of times|\n| membership | `in` | Ask whether an item is in a sequence |\n| length | `len` | Ask the number of items in the sequence|\n| slicing | `[:]` | Extract a part of a sequence |", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "# Lists\n\nbased on http://ehmatthes.github.io/pcc/cheatsheets/README.html\n\n- use square brackets to define a list,\n- []\n- use commas to separate individual items in the list\n- Syntax: < variable > = [< comma separated expressions >]\n- Lists are **ordered** collections of objects. \n - **heterogeneous**: elements of a list don't have to be the same type. Each element of the list can be of any type.\n - **indexing**: elements can be referenced by an index. \n - **nesting**: lists can be nested to arbitrary depth\n - **mutable**: lists are changeable\n - **duplicates allowed**: lists are indexed, items can have the same value\n \n\n*Note:* \n* is different from the Matlab array, closer to the Matlab cell array\n* is different from the C array\n* tip: use plural names for lists, to make your code easier to read.", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "## creation\n\n- Create the list with brackets `[ ]` \n- Inside the brackets, the elements are separated by a comma (,). \n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "zips = [3001, 3000, 1000, 9000, 8000]\ntest_lists = ['test1','test2',3, [1, 2, 7]] ", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## accessing elements of a list\n\n- Individual elements in a list are accessed according to their index. \n- The index is 0 based.\n- Use square brackets []\n- Syntax: < var name >[< index >], where index is an integer expression\n\nnegative index: \n- -1 corresponds to the last element\n\n\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "first = zips[0]\nprint(first)\nlast = zips[-1]\nprint(last)\nprint(test_lists[2])\nprint(test_lists[3])\nprint(test_lists[3][0])\n\n#Refer to the index of the item you want to modify.\nzips[1] = 8500\nzips[-2] = 2000\nprint(zips)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "whos", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Slicing lists, to create sublists\n\n- Assigning to slices\n- All slice operations return a new list containing the requested elements\n- Syntax: < var name >[< index1 >:< index2 >[:step]]\n - index1: Optional. Starting index of the slice. Defaults to 0.\n - index2: Optional. The last index of the slice or the number of items to get. Defaults to len(sequence).\n - step: Optional. Extended slice syntax. Step value of the slice. Defaults to 1.\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "l = list(range(1, 6))\nprint('l', l)\nl_sub = l[2:4]\nprint('l_sub', l_sub)\nl_sub = l[:4]\nprint('l_sub', l_sub)\nl_sub = l[2:]\nprint('l_sub', l_sub)\nl_sub = l[0:4:3]\nprint('l_sub', l_sub)\nl_sub = l[::2]\nprint('l_sub', l_sub)\nl_sub = l[4:1:-1]\nprint('l_sub', l_sub)\n\nl_r = l[::-1]\nprint('l_r', l_r)\n\n#create a copy\nl_bis = l[:]\nprint('l_bis', l_bis)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Slice assignment is allowed", + "metadata": {} + }, + { + "cell_type": "code", + "source": "l = list(range(1, 6))\nprint('l:', l)\n\n# replace a chunk with the same number of items\nprint(l[::2])\nl[::2] = ['a', 'b', 'c'] \nprint('l:', l)\n\n# replace a chunk with a larger number of items\nprint(l[:3])\nl[:3] = [999, 999, 999, 999, 999]\nprint('l:', l)\n\n# replace a chunk with a smaller number of items\nprint(l[:3])\nl[:3] = [55555]\nprint('l:', l)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "dir(list)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Add elements to the end of a list, \nor insert at wherever position in the list", + "metadata": {} + }, + { + "cell_type": "code", + "source": "print(type(zips))\nprint(dir(zips))\nprint('original: ', zips)\nzips.append(3500)\nzips.insert(0, 3050)\nzips.insert(3, 4000)\nprint('modified: ', zips)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "More operations on lists", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# concatenate with +\nl = [1,2,3] + [4,5,6]\nprint(l)\nl1 = [1, 2]\nl2 = ['a', 'b', 9, True]\nl3 = l1 + l2\nprint('l3', l3)\n\n# multiply a list\nl = [1, 2]\nl3 = l * 3\nprint('l3:', l3)\n\n# multiply to quickly initialize a list\nlist0 = [0]*10\nprint('list0: ', list0)\n\n# beware\nlist1 = [1,2,3]\nlist1_3 = list1*3\nprint(list1, ' / ', list1_3)\nlist1[2]=4\nprint(list1, ' / ', list1_3)\n\nlist1 = [1,2,3]\nlist1_3 = [list1]*3\nprint(list1, ' / ', list1_3)\nlist1[2]=4\nprint(list1, ' / ', list1_3)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Use a list as a stack, appends and pops from the end of list are\nfast!", + "metadata": {} + }, + { + "cell_type": "code", + "source": "stack = [3.01, 40, 'hello']\nprint(stack)\n\n# add elements to the list\nstack.append(6)\nstack.append(7.77)\nprint(stack)\n\n# remove last elements added using pop\nstack.pop()\nprint(stack)\nstack.pop()\nprint(stack)\nstack.pop()\nprint(stack)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Removing elements from a list\n\n* `remove`: delete a specific object in the list. Remove is the only one that searches object (not index based).\n* `del`: delete the object at a specific location (index) in the list.\n* `pop`: delete the object at a specific location (index) in the list and get the object at the specific location.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# remove elements by their position in a list, \n# or by the value of the item. Python removes only the first occurrence of that value\"\nzips = [3050, 3001, 8500, 4000, 1000, 2000, 8000, 3500]\n\nprint('zips: ', zips)\ndel zips[1]\nprint('zips: ', zips)\ndel zips[1:4]\nprint('zips: ', zips)\nzips.remove(8000)\nprint('zips: ', zips)\nzips.remove(8000)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# pop() returns the last element in the list, but any index can be specified.\nrecent_zip = zips.pop()\nprint('zips: ', zips)\nfirst_zip = zips.pop(0)\nprint('zips: ', zips)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# The len() function returns the number of items\nnum_zips = len(zips)\nprint('num_zips = ', num_zips)\n\n# The sort() method changes the order of a list permanently. \n# The sorted() function returns a copy of the list, leaving the original list unchanged. \"\nzips.sort()\nprint('zips (sorted): ', zips)\nzips.sort(reverse=True)\nprint('zips (sorted - reverse): ', zips)\n\nzips = [3050, 3001, 8500, 4000, 1000, 2000, 8000, 3500]\nzs = sorted(zips)\nprint('zips: ', zips)\nprint('zs (using sorted): ', zs)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "zips = [3050, 3001, 8500, 4000, 1000, 2000, 8000, 3500]\n\n#Python loop pulls each item from the list one at a time and stores it in a temporary variable, which you provide a name for.\nfor zip in zips:\n print(zip)\n# number of elements\nnumel = len(zips)\nprint('number of elements in zips: ', numel)\n# Simple statistics are possible on a list containing numerical data.\nsmallest = min(zips)\nlargest = max(zips)\nsumzips = sum(zips)\nprint('min = {}, max = {}, sum = {}'.format(smallest, largest, sumzips))\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Conversion\n\n`list()`: takes sequence types and converts them to lists.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "xl = list('help')\nprint(xl)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## `range`\n\nThe `range` function returns a range object from start to one less than the stop value, a step size can be set (only integers)\n\n`range(start, stop, step)`\n\ncreate a list: convert the range object into a list\n`LR = list(range(2, 9, 3))`\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "R1 = range(2, 9, 3)\nprint(R1)\nprint('type R1', type(R1))\nLR1 = list(R1)\nprint(LR1)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "xr = range(10)\nprint(type(xr))\n\nfor i in range(10):\n print(i, end=' ')\nprint('\\n') \n\n# enumerate\nL1 = [2, 4, 6, 8, 10]\nfor indx, val in enumerate(L1):\n print(indx, val)\nprint('\\n') \n \nL2 = ['pizza', 'pasta', 'salad', 'nachos']\nprint(list(enumerate(L2)))\nfor i, val in enumerate(L2):\n print(i, val)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## membership\n\nCheck if some item is a member of the list\n\nSyntax: < expression > `in` < iterable >): Returns True/False if < expression > is a member of the list", + "metadata": {} + }, + { + "cell_type": "code", + "source": "x = [2, 3, 4, 5, 6, 8]\nprint('3 in x :', 3 in x)\nprint('7 in x :', 7 in x)\n\nl3 = ['help', [1, 2], 5, 2]\nprint(1 in l3)\nprint([1,2] in l3)\nprint('e' in l3)\nprint('help' in l3)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## aliasing\n\nIf variable v1 refers to an object and an assignment is made `v2 = v1`, then both variables refer to the same object.\n", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "It’s important to note that any modifications to the alias object will reflect in the existing object and vice versa, because they both point to the same memory location.\n\nIf the aliased object is mutable, changes made with one alias affect the other!", + "metadata": {} + }, + { + "cell_type": "code", + "source": "v1 = [1, 2, 3]\nv2 = v1\nprint('v1 = ', v1)\nprint('v2 = ', v2)\nprint('v1 is v2 ? ', v1 is v2)\nprint('v1 == v2 ? ', v1 == v2)\nprint(\"Reference of 1st list:\", id(v1))\nprint(\"Reference of 2nd list:\", id(v2))\n\nv2[1] = 101\nprint('v1 = ', v1)\nprint('v2 = ', v2)", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "v1 = [1, 2, 3]\nv2 = [1, 2, 3]\nv1 is v2 ? True\nv1 == v2 ? True\nReference of 1st list: 65839560\nReference of 2nd list: 65839560\nv1 = [1, 101, 3]\nv2 = [1, 101, 3]\n" + } + ], + "execution_count": 5 + }, + { + "cell_type": "markdown", + "source": "### shallow copy\n\nA partial solution is to use the list constructor or the slice operation to make a new list via a shallow copy. But if the list contains other compound types then they won't be independently copied\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# use slicing notation to create a shallow copy\nv1 = [1, 2, 3]\nv2 = v1[:]\nprint('v1 = ', v1)\nprint('v2 = ', v2)\nprint('v1 is v2 ?', v1 is v2)\nprint(\"Reference of 1st list:\", id(v1))\nprint(\"Reference of 2nd list:\", id(v2))\n\nv1[1] = 101\nprint('v1 = ', v1)\nprint('v2 = ', v2)\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "v1 = [1, 2, 3]\nv2 = [1, 2, 3]\nv1 is v2 ? False\nReference of 1st list: 70611952\nReference of 2nd list: 69250880\nv1 = [1, 101, 3]\nv2 = [1, 2, 3]\n" + } + ], + "execution_count": 6 + }, + { + "cell_type": "code", + "source": "# use the list function to create a shallow copy\nv1 = [1, 2, 3]\nv2 = list(v1)\nprint('v1 = ', v1)\nprint('v2 = ', v2)\nprint('v1 is v2 ?', v1 is v2)\nprint(\"Reference of 1st list:\", id(v1))\nprint(\"Reference of 2nd list:\", id(v2))\n\nv1[1] = 101\nprint('v1 = ', v1)\nprint('v2 = ', v2)\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "v1 = [1, 2, 3]\nv2 = [1, 2, 3]\nv1 is v2 ? False\nReference of 1st list: 38315368\nReference of 2nd list: 70698320\nv1 = [1, 101, 3]\nv2 = [1, 2, 3]\n" + } + ], + "execution_count": 8 + }, + { + "cell_type": "code", + "source": "# use the copy function to create a shallow copy\nv1 = [1, 2, 3]\nv2 = v1.copy()\nprint('v1 = ', v1)\nprint('v2 = ', v2)\nprint('v1 is v2 ?', v1 is v2)\nprint(\"Reference of 1st list:\", id(v1))\nprint(\"Reference of 2nd list:\", id(v2))\n\nv1[1] = 101\nprint('v1 = ', v1)\nprint('v2 = ', v2)\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "v1 = [1, 2, 3]\nv2 = [1, 2, 3]\nv1 is v2 ? False\nReference of 1st list: 65832432\nReference of 2nd list: 67340704\nv1 = [1, 101, 3]\nv2 = [1, 2, 3]\n" + } + ], + "execution_count": 9 + }, + { + "cell_type": "code", + "source": "# be careful with a shallow copy on compound types!\n# example taken from: https://cvw.cac.cornell.edu/python-intro/objects-and-oop/lists\n\nmyList = [[1,2,3],4]\nprint(myList)\nmyOtherList = myList.copy() # use the copy method of the list, is a shallow copy\n\nmyList[1] = 'four'\nprint(myList)\nprint (myOtherList)\n\n#OK so far, but now try to change an element in the sublist\nmyList[0][1] = 'two'\nprint (myList)\n\n#This time the item also changes in the shallow copy, because it was in a sublist\nprint (myOtherList)\n", + "metadata": { + "trusted": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": "[[1, 2, 3], 4]\n[[1, 2, 3], 'four']\n[[1, 2, 3], 4]\n[[1, 'two', 3], 'four']\n[[1, 'two', 3], 4]\n" + } + ], + "execution_count": 10 + }, + { + "cell_type": "markdown", + "source": "Safer to avoid aliasing when working with mutable objects.\n\nThe way to make a completely independent copy of a list —a deep copy— is to use the the `copy.deepcopy()` method. \n`copy.deepcopy()` to makes copies of compound objects, as the errors which can occur from shallow copies are often frustrating to debug.\n\nPython’s standard library provides the copy module, which provides functions that can be used to create deep copies of objects.\n\nBeware that (deep)copying a co\n\nhttps://cvw.cac.cornell.edu/python-intro/objects-and-oop/lists", + "metadata": {} + }, + { + "cell_type": "code", + "source": "from copy import deepcopy\nmyList = [[1,2,3],4]\n\n#Making a deep copy, myOtherList\nmyOtherList = deepcopy(myList)\n\n#Reassigning an element of the sublist in myList\nmyList[0][1] = 'two'\nprint(myList)\n#No effect on myOtherList\nprint(myOtherList)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### list unpacking / packing\n\nassign elements of a list to multiple variables.\n\npacking: wraps the arguments into a single variable. Putting the asterisk (*) in front of a variable name, you’ll pack the leftover elements into a list and assign them to a variable", + "metadata": {} + }, + { + "cell_type": "code", + "source": "[a, b, c, d, e] = [1, 2, 3, 4, 5]\nprint(a,b,c, d, e)\n\n# try\n#[a, b, c] = [1, 2, 3, 4, 5]\n\n[a, *b, c] = [1, 2, 3, 4, 5]\nprint(a,b,c)\n\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": " List packing is the process of bundling several values into a single iterable", + "metadata": {} + }, + { + "cell_type": "code", + "source": "num1 = 1\nnum2 = 2\nnum3 = 3\n*num, = num1, num2, num3\nprint(num)\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### list comprehension\n\nComprehension: powerful functionality within a single line of code; provides a compact way to create lists. \n\nThe general syntax of list comprehension is: `[expression for item in list if condition]`. The if condition part is optional. List comprehension provides a more concise and readable way to create lists compared to using loops.\n\nWorks also for dictionaries and sets", + "metadata": {} + }, + { + "cell_type": "code", + "source": "sqlist = [x * x for x in range(15)]\nprint(sqlist)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# with if statement\neven_numbers = [num for num in range(1, 10) if num % 2 == 0]\nprint(even_numbers) # Output: [2, 4, 6, 8]\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# using if else\nnumbers = [1, 2, 3, 4, 5, 6]\neven_odd_list = [\"Even\" if i % 2 == 0 else \"Odd\" for i in numbers]\nprint(even_odd_list) # Output: ['Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even']\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "# example from Python Turial\n[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/list_cheat.py b/scripts/list_cheat.py new file mode 100644 index 0000000..82b425f --- /dev/null +++ b/scripts/list_cheat.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jun 22 11:38:15 2018 + +list_cheat + +beased on http://ehmatthes.github.io/pcc/cheatsheets/README.html +@author: u0015831 +""" + +# Use square brackets to define a list, and use commas to separate individual items in the list. Use plural names for lists, to make your code easier to read. +# [] +zips = [3001, 3000, 1000, 9000, 8000] + +# Individual elements in a list are accessed according to their index. The index is 0 based. +# Use square brackets []" +first = zips[0] +last = zips[-1] + +#Refer to the index of the item you want to modify. +zips[1] = 8500 +zips[-2] = 2000 + +# Add elements to the end of a list, +# or insert at wherever position in the list." +zips.append(3500) +zips.insert(0, 3050) +zips.insert(3,4000) + +# remove elements by their position in a list, +# or by the value of the item. Python removes only the first occurrence of that value" +del zips[1] +zips.remove(4000) + +# pop() returns the last element in the list, but any index can be specified. +recent_zip = zips.pop() +first_zip = zips.pop(0) + +# The len() function returns the number of items +num_zip = len(zips) + +# The sort() method changes the order of a list permanently. +# The sorted() function returns a copy of the list, leaving the original list unchanged. " +zips.sort() +zips.sort(reverse=True) +zs = sorted(zips) + +#Python loop pulls each item from the list one at a time and stores it in a temporary variable, which you provide a name for. +for zip in zips: + print(zip) + +# The range() function starts at 0 by default, and stops below the upper boundary. +# range(start, stop[, step]) +for number in range(1001): + print(number) +# create a list of numbers, interlaced by 100 +numbers = list(range(1, 1000001, 100)) + +# Simple statistics are possible on a list containing numerical data. +smallest = min(zips) +largest = max(zips) +sumzips = sum(zips) + +# A portion of a list is called a slice. To slice a list start with the index of the first item , colon, index after the last item. +first3 = zips[:3] +last3 = zips[-3:] +middle3 = zips[2:5] + +#Copy a list: make a slice from the first to the last element. Remember that a variable name is a label, pointer to some spot in memory +copy_of_zips = zips[:] diff --git a/scripts/list_copy.py b/scripts/list_copy.py new file mode 100644 index 0000000..4dc18a9 --- /dev/null +++ b/scripts/list_copy.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jun 19 16:12:40 2018 + +lists: copying + +@author: u0015831 +""" +# this behavior is specific for any mutable data structure +v1=[1,2,3,4] +v2=v1 +v2[2]=9 +print("v1: ", v1) + +# slicing notation +v1=[1,2,3,4] +C=v1[:] +C[1]=11 +print("v1: ", v1) + +# use list function +v1=[1,2,3,4] +v2=list(v1) +v2[2]=9 +print("v1: ", v1) + +# use copy +v1=[1,2,3,4] +v2=v1.copy() +v2[2]=9 +print("v1: ", v1) + +# more layers +L1 = [1,2,3] +L2 = [4,5,6] +L3 = [7,8,9] + +Lbig = [L1,L2,L3] +LbigAlias = Lbig +LbigAlias2 = Lbig.copy() +LbigShallow = Lbig[:] + +from copy import deepcopy +LbigDeep = deepcopy(Lbig) + +L1[0] = 99 #changes first element of L1 +print(LbigAlias) +print(LbigAlias2) +print(LbigShallow) +print(LbigDeep) diff --git a/scripts/list_nested.py b/scripts/list_nested.py new file mode 100644 index 0000000..51678aa --- /dev/null +++ b/scripts/list_nested.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jul 2 11:46:02 2018 + +nested lists +@author: u0015831 +""" + +a = [1, 2] +b = [3, 4, 5] + +ln1 = [10, a] + +ln2 = [1, 2, a, b, ln1] + +print(ln2) +print(ln2[-1]) +print(ln2[-1][1]) +print(ln2[-1][1][1]) \ No newline at end of file diff --git a/scripts/make_it_upper.py b/scripts/make_it_upper.py new file mode 100644 index 0000000..98e7409 --- /dev/null +++ b/scripts/make_it_upper.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 20:12:22 2019 +source: http://rwet.decontextualize.com/book/functions/ +example: python make_it_upper.py 0: + print(ucfirst(line)) + else: + print(line) \ No newline at end of file diff --git a/scripts/mall_customers.csv b/scripts/mall_customers.csv new file mode 100644 index 0000000..93d04e8 --- /dev/null +++ b/scripts/mall_customers.csv @@ -0,0 +1,201 @@ +CustomerID,Gender,Age,Annual Income (k$),Spending Score +1,Male,19,15,39 +2,Male,21,15,81 +3,Female,20,16,6 +4,Female,23,16,77 +5,Female,31,17,40 +6,Female,22,17,76 +7,Female,35,18,6 +8,Female,23,18,94 +9,Male,64,19,3 +10,Female,30,19,72 +11,Male,67,19,14 +12,Female,35,19,99 +13,Female,58,20,15 +14,Female,24,20,77 +15,Male,37,20,13 +16,Male,22,20,79 +17,Female,35,21,35 +18,Male,20,21,66 +19,Male,52,23,29 +20,Female,35,23,98 +21,Male,35,24,35 +22,Male,25,24,73 +23,Female,46,25,5 +24,Male,31,25,73 +25,Female,54,28,14 +26,Male,29,28,82 +27,Female,45,28,32 +28,Male,35,28,61 +29,Female,40,29,31 +30,Female,23,29,87 +31,Male,60,30,4 +32,Female,21,30,73 +33,Male,53,33,4 +34,Male,18,33,92 +35,Female,49,33,14 +36,Female,21,33,81 +37,Female,42,34,17 +38,Female,30,34,73 +39,Female,36,37,26 +40,Female,20,37,75 +41,Female,65,38,35 +42,Male,24,38,92 +43,Male,48,39,36 +44,Female,31,39,61 +45,Female,49,39,28 +46,Female,24,39,65 +47,Female,50,40,55 +48,Female,27,40,47 +49,Female,29,40,42 +50,Female,31,40,42 +51,Female,49,42,52 +52,Male,33,42,60 +53,Female,31,43,54 +54,Male,59,43,60 +55,Female,50,43,45 +56,Male,47,43,41 +57,Female,51,44,50 +58,Male,69,44,46 +59,Female,27,46,51 +60,Male,53,46,46 +61,Male,70,46,56 +62,Male,19,46,55 +63,Female,67,47,52 +64,Female,54,47,59 +65,Male,63,48,51 +66,Male,18,48,59 +67,Female,43,48,50 +68,Female,68,48,48 +69,Male,19,48,59 +70,Female,32,48,47 +71,Male,70,49,55 +72,Female,47,49,42 +73,Female,60,50,49 +74,Female,60,50,56 +75,Male,59,54,47 +76,Male,26,54,54 +77,Female,45,54,53 +78,Male,40,54,48 +79,Female,23,54,52 +80,Female,49,54,42 +81,Male,57,54,51 +82,Male,38,54,55 +83,Male,67,54,41 +84,Female,46,54,44 +85,Female,21,54,57 +86,Male,48,54,46 +87,Female,55,57,58 +88,Female,22,57,55 +89,Female,34,58,60 +90,Female,50,58,46 +91,Female,68,59,55 +92,Male,18,59,41 +93,Male,48,60,49 +94,Female,40,60,40 +95,Female,32,60,42 +96,Male,24,60,52 +97,Female,47,60,47 +98,Female,27,60,50 +99,Male,48,61,42 +100,Male,20,61,49 +101,Female,23,62,41 +102,Female,49,62,48 +103,Male,67,62,59 +104,Male,26,62,55 +105,Male,49,62,56 +106,Female,21,62,42 +107,Female,66,63,50 +108,Male,54,63,46 +109,Male,68,63,43 +110,Male,66,63,48 +111,Male,65,63,52 +112,Female,19,63,54 +113,Female,38,64,42 +114,Male,19,64,46 +115,Female,18,65,48 +116,Female,19,65,50 +117,Female,63,65,43 +118,Female,49,65,59 +119,Female,51,67,43 +120,Female,50,67,57 +121,Male,27,67,56 +122,Female,38,67,40 +123,Female,40,69,58 +124,Male,39,69,91 +125,Female,23,70,29 +126,Female,31,70,77 +127,Male,43,71,35 +128,Male,40,71,95 +129,Male,59,71,11 +130,Male,38,71,75 +131,Male,47,71,9 +132,Male,39,71,75 +133,Female,25,72,34 +134,Female,31,72,71 +135,Male,20,73,5 +136,Female,29,73,88 +137,Female,44,73,7 +138,Male,32,73,73 +139,Male,19,74,10 +140,Female,35,74,72 +141,Female,57,75,5 +142,Male,32,75,93 +143,Female,28,76,40 +144,Female,32,76,87 +145,Male,25,77,12 +146,Male,28,77,97 +147,Male,48,77,36 +148,Female,32,77,74 +149,Female,34,78,22 +150,Male,34,78,90 +151,Male,43,78,17 +152,Male,39,78,88 +153,Female,44,78,20 +154,Female,38,78,76 +155,Female,47,78,16 +156,Female,27,78,89 +157,Male,37,78,1 +158,Female,30,78,78 +159,Male,34,78,1 +160,Female,30,78,73 +161,Female,56,79,35 +162,Female,29,79,83 +163,Male,19,81,5 +164,Female,31,81,93 +165,Male,50,85,26 +166,Female,36,85,75 +167,Male,42,86,20 +168,Female,33,86,95 +169,Female,36,87,27 +170,Male,32,87,63 +171,Male,40,87,13 +172,Male,28,87,75 +173,Male,36,87,10 +174,Male,36,87,92 +175,Female,52,88,13 +176,Female,30,88,86 +177,Male,58,88,15 +178,Male,27,88,69 +179,Male,59,93,14 +180,Male,35,93,90 +181,Female,37,97,32 +182,Female,32,97,86 +183,Male,46,98,15 +184,Female,29,98,88 +185,Female,41,99,39 +186,Male,30,99,97 +187,Female,54,101,24 +188,Male,28,101,68 +189,Female,41,103,17 +190,Female,36,103,85 +191,Female,34,103,23 +192,Female,32,103,69 +193,Male,33,113,8 +194,Female,38,113,91 +195,Female,47,120,16 +196,Female,35,120,79 +197,Female,45,126,28 +198,Male,32,126,74 +199,Male,32,137,18 +200,Male,30,137,83 \ No newline at end of file diff --git a/scripts/mall_customers.xlsx b/scripts/mall_customers.xlsx new file mode 100644 index 0000000..18cec94 Binary files /dev/null and b/scripts/mall_customers.xlsx differ diff --git a/scripts/matplotlib_first_plot.py b/scripts/matplotlib_first_plot.py new file mode 100644 index 0000000..9fb4a34 --- /dev/null +++ b/scripts/matplotlib_first_plot.py @@ -0,0 +1,21 @@ +# matplotlib_first_plot.py + +# using pyplot functions + +import matplotlib.pyplot as plt + +# Data for plotting +time = [2, 4, 6, 8, 10] +distance = [1, 4, 9, 19, 39] +velocity = [1, 16, 26, 36, 111] + +plt.figure(figsize=(9,7), dpi=100) + +plt.plot(time,distance,'bo-', label='distance') +plt.plot(time,velocity, label='velocity') # scaling, another y-axis??? + +plt.xlabel("Time") +plt.ylabel("Distance") + +plt.legend() +plt.grid(True) \ No newline at end of file diff --git a/scripts/matplotlib_first_plot_oo.py b/scripts/matplotlib_first_plot_oo.py new file mode 100644 index 0000000..59454e7 --- /dev/null +++ b/scripts/matplotlib_first_plot_oo.py @@ -0,0 +1,28 @@ +# matplotlib_first_plot_oo.py + +# using oo approach + +import matplotlib.pyplot as plt + +# Data for plotting +time = [2, 4, 6, 8, 10] +distance = [1, 4, 9, 19, 39] +velocity = [1, 16, 26, 36, 111] + +fig, ax1 = plt.subplots() + +ax1.set_ylabel("distance (m)") +ax1.set_xlabel("time") +ax1.plot(time, distance, "blue") + +ax2 = ax1.twinx() # create another y-axis sharing a common x-axis + + +ax2.set_ylabel("velocity (m/s)") +ax2.set_xlabel("time") +ax2.plot(time, velocity, "green") + +fig.set_size_inches(7,5) +fig.set_dpi(100) + +plt.show() \ No newline at end of file diff --git a/scripts/matplotlib_hierarchy.png b/scripts/matplotlib_hierarchy.png new file mode 100644 index 0000000..f471ea4 Binary files /dev/null and b/scripts/matplotlib_hierarchy.png differ diff --git a/scripts/middle.py b/scripts/middle.py new file mode 100644 index 0000000..d59d891 --- /dev/null +++ b/scripts/middle.py @@ -0,0 +1,31 @@ +# string_extract +""" +Created on Fri Jun 29 14:57:05 2018 + +Source: http://www.cs.cornell.edu/courses/cs1110/2018sp +""" + +def middle(text): + """Returns: middle 3rd of text + Param text: a string with + length divisible by 3"""2+2 + + # Get length of text + size = len(text) + # Start of middle third + start2 = size//3 + # End of middle third + start3 = (2*size)//3 + # Get the substring + middle_third = text[start2:start3] + return middle_third + +def firstparens(text): + """Returns: substring in () + Uses the first set of parens + Param text: a string with ()""" + # Find the open parenthesis + start = text.index('(') + # Find the close parenthesis + end = text.index(‘)’) + return text[start+1:end] \ No newline at end of file diff --git a/scripts/min_max_f.py b/scripts/min_max_f.py new file mode 100644 index 0000000..a50fe52 --- /dev/null +++ b/scripts/min_max_f.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 21 15:19:07 2018 + +usage: +seq = [1, 9, 2, 4, 3, 540] +print min_max(seq) + +string = 'Hello World' +print min_max(string) + +@author: u0015831 +""" + +def min_max(t): + """Returns the smallest and largest + elements of a sequence as a tuple""" + return (min(t), max(t)) + diff --git a/scripts/mod_random.py b/scripts/mod_random.py new file mode 100644 index 0000000..17bd464 --- /dev/null +++ b/scripts/mod_random.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jul 2 15:11:32 2018 + +some examples on random module +@author: u0015831 +""" +# import the module +import random + +# good practice to use the seed function, and timing data as an argument for it. +from datetime import datetime +random.seed(datetime.now()) + +print(random.random()) +print(random.random()) + +print(random.uniform(10, 14)) + +random.randint(1, 100) +random.randint(1, 100) +random.randint(1, 100) +random.randint(1, 100) + +ls = [1, 2, 88, 92, 10, 3, 127] +print(random.choice(ls)) +print(random.choice(ls)) + +print(random.randrange(1,33)) +print(random.randrange(1,33)) +print(random.randrange(1,33)) + +print(ls) +print(random.shuffle(ls)) +print(ls) \ No newline at end of file diff --git a/scripts/module_1.py b/scripts/module_1.py new file mode 100644 index 0000000..45e5b16 --- /dev/null +++ b/scripts/module_1.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jul 5 14:00:38 2018 + +@author: u0015831 +""" + +import math +print(math.cos(math.pi)) + +import numpy as np +print(np.cos(np.pi)) \ No newline at end of file diff --git a/scripts/module_math_1.py b/scripts/module_math_1.py new file mode 100644 index 0000000..d066d84 --- /dev/null +++ b/scripts/module_math_1.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 28 16:20:24 2018 + +@author: u0015831 +""" + +import math +print(math.cos(90.0)) +print(math.pi) +print(math.cos(math.pi)) \ No newline at end of file diff --git a/scripts/multi_return_func.py b/scripts/multi_return_func.py new file mode 100644 index 0000000..21b92d4 --- /dev/null +++ b/scripts/multi_return_func.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 7 16:56:59 2019 +source: https://pythonbasics.org/multiple-return/ +@author: u0015831 +""" + +def getPerson(): + name = "Leona" + age = 35 + country = "UK" + return name,age,country + +name,age,country = getPerson() +print(name) +print(age) +print(country) \ No newline at end of file diff --git a/scripts/my_accum.py b/scripts/my_accum.py new file mode 100644 index 0000000..c9c0c79 --- /dev/null +++ b/scripts/my_accum.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Feb 20 09:43:40 2020 + +@author: u0015831 +""" + +big_sum = 0 # accumumator as global variable + +def my_accum(val): + big_sum = big_sum + val + return +# big_sum = 0 +my_accum(5.7) +my_accum(6) +my_accum(99) +print('big_sum', big_sum) \ No newline at end of file diff --git a/scripts/my_first_script.py b/scripts/my_first_script.py new file mode 100644 index 0000000..0b04221 --- /dev/null +++ b/scripts/my_first_script.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Nov 6 09:26:53 2019 + +My first script +- create some variables +- make some calculations +@author: u0015831 +""" +a = 1 +b = 8.7 + +c = a + b +print('c = ', c) + +d = a / b +print('d = ', d) diff --git a/scripts/my_function_1.py b/scripts/my_function_1.py new file mode 100644 index 0000000..0ce34ee --- /dev/null +++ b/scripts/my_function_1.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 27 10:17:12 2018 + +can I use this file? a la Matlab function? + +@author: u0015831 +""" + +def my_function_1(): + """ this function is printing a message + this function has no passing parameters + is not returning anything + """ + print('I am my_function_1') + \ No newline at end of file diff --git a/scripts/my_module.py b/scripts/my_module.py new file mode 100644 index 0000000..e202920 --- /dev/null +++ b/scripts/my_module.py @@ -0,0 +1,13 @@ +# my_module.py +""" +Created on Thu Jun 28 16:33:19 2018 + +@author: u0015831 +""" + +"""This is a simple module. +It shows how modules work""" +x = 1+2 +x = 3*x + +print(x) \ No newline at end of file diff --git a/scripts/my_script.py b/scripts/my_script.py new file mode 100644 index 0000000..e2ad6cd --- /dev/null +++ b/scripts/my_script.py @@ -0,0 +1,4 @@ +a = 1.1 +b = 2.33 +c = a + b +print(c) \ No newline at end of file diff --git a/scripts/name.txt b/scripts/name.txt new file mode 100644 index 0000000..7fb1d87 --- /dev/null +++ b/scripts/name.txt @@ -0,0 +1 @@ +frank \ No newline at end of file diff --git a/scripts/name_01.txt b/scripts/name_01.txt new file mode 100644 index 0000000..2d95e23 --- /dev/null +++ b/scripts/name_01.txt @@ -0,0 +1 @@ +jef \ No newline at end of file diff --git a/scripts/name_02.txt b/scripts/name_02.txt new file mode 100644 index 0000000..1cd7815 --- /dev/null +++ b/scripts/name_02.txt @@ -0,0 +1,4 @@ +KU Leuvencampus Arenberg +KU Leuvencampus Arenberg +KU Leuven +campus Arenberg diff --git a/scripts/named_tuple.py b/scripts/named_tuple.py new file mode 100644 index 0000000..e29379b --- /dev/null +++ b/scripts/named_tuple.py @@ -0,0 +1,25 @@ + +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 22 17:29:17 2019 + +source: https://www.journaldev.com/22439/python-namedtuple +""" + +from collections import namedtuple + +Employee = namedtuple('Employee', ['name', 'age', 'role']) + +# below are also valid ways to namedtuple +# Employee = namedtuple('Employee', 'name age role') + +emp1 = Employee('Pankaj', 35, 'Editor') +emp2 = Employee(name='David', age=40, role='Author') + +for p in [emp1, emp2]: + print(p) + + +# accessing via name of the field +for p in [emp1, emp2]: + print(p.name, 'is a', p.age, 'years old working as', p.role) \ No newline at end of file diff --git a/scripts/nested_while_error.py b/scripts/nested_while_error.py new file mode 100644 index 0000000..abb8c45 --- /dev/null +++ b/scripts/nested_while_error.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jun 6 17:12:27 2023 + +@author: u0015831 +""" + +count1 = 0 +count2 = 0 +a = 100 +b = 6 + +while count1 < 10: + a = a + 1 + while count2 < 10: + b = b + 1 + count2 = count2 + 1 + print(b) + print(a) + count1 = count1 + 1 +print('the end') \ No newline at end of file diff --git a/scripts/nextSquare.py b/scripts/nextSquare.py new file mode 100644 index 0000000..426f7e8 --- /dev/null +++ b/scripts/nextSquare.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 22 16:30:26 2019 + +source: https://www.geeksforgeeks.org/use-yield-keyword-instead-return-keyword-python/ +""" + +# A Python program to generate squares from 1 +# to 100 using yield and therefore generator + +# An infinite generator function that prints +# next square number. It starts with 1 +def nextSquare(): + i = 1; + + # An Infinite loop to generate squares + while True: + yield i*i + i += 1 # Next execution resumes + # from this point + +# Driver code to test above generator +# function +for num in nextSquare(): + if num > 1000: + break + print(num) \ No newline at end of file diff --git a/scripts/operators.ipynb b/scripts/operators.ipynb new file mode 100644 index 0000000..8deee20 --- /dev/null +++ b/scripts/operators.ipynb @@ -0,0 +1,457 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Operators\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\n", + "from traceback import print_exc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Key concepts in programming\n", + "\n", + "- Variables (integers, strings, dates, etc.)\n", + "- Flow control (if then, loop, etc.)\n", + "- Functions (list of steps the code will follow)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Operators\n", + "## Arithmetic operators\n", + "\n", + "| Operator | Name | Meaning |\n", + "|----------|------|-------------|\n", + "| a + b | addition | sum of a and b|\n", + "| a - b | subtraction | difference of a and b|\n", + "| a * b | multiplication | product of a and b|\n", + "| a / b | true division | quotient of a and b|\n", + "| a // b | floor division | quotient of a and b, removing fractional part|\n", + "| a % b | modulus | remainder after division of a by b|\n", + "| a ** b | exponentiation | a raised to power of b|\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# working with integers\n", + "a = 13\n", + "b = 3\n", + "\n", + "# Output: a + b\n", + "print('a + b =', a + b)\n", + "# Output: a - b\n", + "print('a - b =', a - b)\n", + "# Output: a * b\n", + "print('a * b =', a * b)\n", + "# Output: a / b\n", + "print('a / b =', a / b)\n", + "# Output: a // b\n", + "print('a // b =', a // b)\n", + "# Output: a % b\n", + "print('a % b =', a % b)\n", + "# Output: a ** b\n", + "print('a ** b =', a ** b)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# example with real numbers\n", + "a = 1.2\n", + "b = 8.75\n", + "# Output: a + b\n", + "print('a + b =', a + b)\n", + "# Output: a - b\n", + "print('a - b =', a - b)\n", + "# Output: a * b\n", + "print('a * b =', a * b)\n", + "# Output: a / b\n", + "print('a / b =', a / b)\n", + "# Output: a // b\n", + "print('a // b =', a // b)\n", + "# Output: a % b\n", + "print('a % b =', a % b)\n", + "# Output: a ** b\n", + "print('a ** b =', a ** b)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparison operators\n", + "\n", + "| Operator | Meaning |\n", + "|----------|---------|\n", + "| >\t| Greater than - True if left operand is greater than the right |\n", + "| <\t|Less that - True if left operand is less than the right |\n", + "| == |\tEqual to - True if both operands are equal |\n", + "| != |\tNot equal to - True if operands are not equal |\n", + "| >= |\tGreater than or equal to - True if left operand is greater than or equal to the right |\n", + "| <= |\tLess than or equal to - True if left operand is less than or equal to the right |" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 13\n", + "b = 3.6\n", + "\n", + "# Output: a > b\n", + "print('a > b :', a > b)\n", + "# Output: a < b\n", + "print('a < b :', a < b)\n", + "# Output: a == b\n", + "print('a == b :', a == b)\n", + "# Output: a != b\n", + "print('a != b :', a != b)\n", + "# Output: a >= b\n", + "print('a >= b :', a >= b)\n", + "# Output: a <= b\n", + "print('a <= b :', a <= b)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In Python, we can also use\n", + "```python\n", + "a < b < c\n", + "```\n", + "as a shorthand for\n", + "```python\n", + "a < b and b < c\n", + "```\n", + "and\n", + "```python\n", + "a < b > c\n", + "```\n", + "as a shorthand for\n", + "```python\n", + "a < b and b > c\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"1 < 2 < 3:\", 1 < 2 < 3)\n", + "print(\"1 < 2 < 1:\", 1 < 2 < 1)\n", + "print(\"1 < 2 > 3:\", 1 < 2 > 3)\n", + "print(\"1 < 2 > 1:\", 1 < 2 > 1)\n", + "\n", + "print(\"1 < 2 < 3 < 99 :\", 1 < 2 < 3 < 99)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Logical operators\n", + "\n", + "Logical operators are the `and`, `or`, `not` operators.\n", + "\n", + "| Operator | Meaning |\n", + "|----------|---------|\n", + "| and | True if both the operands are true |\n", + "| or | True if either of the operands is true |\n", + "| not | True if operand is false (complements the operand) |" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = True\n", + "b = False\n", + "\n", + "# Output: a and b\n", + "print('a and b :', a and b)\n", + "# Output: a or b\n", + "print('a or b :', a or b)\n", + "# Output: not a\n", + "print('not a :', not a)\n", + "\n", + "# what happens with numbers?\n", + "a = 1.5\n", + "b = 0\n", + "\n", + "# Output: a and b\n", + "print('a and b :', a and b)\n", + "# Output: a or b\n", + "print('a or b :', a or b)\n", + "# Output: not a\n", + "print('not a :', not a)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Assignment operation\n", + "\n", + "`a = value` (regular assignment)\n", + "\n", + "`a = a + val` is a common operation to increase a variable a by some fixed amount val, we can write:\n", + "`a = a + val`\n", + "\n", + "`a OP= b` is equivalent to `a = a OP b`\n", + "\n", + "| Operator | Example | Meaning |\n", + "|----------|---------|---------|\n", + "| =\t| a = 5\t| a = 5 |\n", + "| += | a += 5 | a = a + 5 |\n", + "| -= | a -= 5\t| a = a - 5 |\n", + "| *= | a *= 5\t| a = a * 5 |\n", + "| /= | a /= 5\t| a = a / 5 |\n", + "| %= | a %= 5\t| a = a % 5 |\n", + "| //= | a //= 5 | a = a // 5 |\n", + "| **= | a **= 5\t| a = a ** 5 |" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 5\n", + "print('a : ', a)\n", + "a += 5\n", + "print('a : ', a)\n", + "a -= 5\n", + "print('a : ', a)\n", + "a *= 5\n", + "print('a : ', a)\n", + "a /= 5\n", + "print('a : ', a)\n", + "a //= 2\n", + "print('a : ', a)\n", + "a **= 5\n", + "print('a : ', a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "x = x + val\n", + "a common operation to increase a variable x by some fixed amount val, we can write:\n", + "\n", + "x = x + val\n", + "\n", + "x += val" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 9.9\n", + "print(x)\n", + "x = x + 8\n", + "print(x)\n", + "x += 5.5\n", + "print(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Special operator\n", + "\n", + "Identity operator `is` is used to check if two values (or variables) are located on the same part of the memory. Two variables that are equal does not imply that they are identical.\n", + "\n", + "| Operator | Meaning |\n", + "|----------|---------|\n", + "|is | True if the operands are identical (refer to the same object) |\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 9\n", + "b = a\n", + "print('a is b', a is b)\n", + "print(id(a))\n", + "print(id(b))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 9\n", + "b = 9\n", + "print('a == b', a == b)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 9.9\n", + "b = 9.9\n", + "print('a is b', a is b)\n", + "print('id(a)', id(a))\n", + "print('id(b)', id(b))\n", + "print('a == b', a == b)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Bit operators\n", + "\n", + "| Operator | Meaning | Description |\n", + "|----------|---------|-------------|\n", + "|`a & b` | Bitwise AND | Bits defined in both a and b |\n", + "|`a \\| b` | Bitwise OR | Bits defined in a or b or both |\n", + "|`a ^ b` | Bitwise XOR | Bits defined in a or b but not both|\n", + "|`a << b` | Shift left | Shift bits of a left by b units |\n", + "|`a >> b` | Shift right | Bits defined in both a and b |\n", + "|`~a` | Bitwise NOT | Bitwise negation of a|\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# example taken from https://www.tutorialspoint.com/python/bitwise_operators_example.htm\n", + "\n", + "a = 60 # 60 = 0011 1100 \n", + "b = 13 # 13 = 0000 1101 \n", + "print('a = ', a, ' bin(a) = ', bin(a))\n", + "print('b = ', b, ' bin(b) = ', bin(b))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = a & b; # 12 = 0000 1100\n", + "print ('Value of c is ', c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = a | b; # 61 = 0011 1101 \n", + "print ('Value of c is ', c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = a ^ b; # 49 = 0011 0001\n", + "print ('Value of c is ', c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = a << 2; # 240 = 1111 0000 - a multiplied by 4\n", + "print ('Value of c is ', c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = a >> 2; # 15 = 0000 1111 - a divided by 4\n", + "print ('Value of c is ', c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c = ~a; # -61 = 1100 0011\n", + "print ('Value of c is ', c)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/scripts/pass_arguments_1.py b/scripts/pass_arguments_1.py new file mode 100644 index 0000000..2f7ad09 --- /dev/null +++ b/scripts/pass_arguments_1.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jul 5 15:08:08 2018 + +@author: u0015831 +""" + +def double_the_values ( l ): + print(" in double_the_values : l = ", l) + for i in range (len( l )): + l [ i ] = l [ i ] * 2 + print(" in double_the_values : changed l to l = ", l) + +l_global = [0 , 1 , 2 , 3 , 10] +print(" In main : s = ", l_global ) +double_the_values ( l_global ) +print(" In main : s = ", l_global ) \ No newline at end of file diff --git a/scripts/pass_by_reference_list.py b/scripts/pass_by_reference_list.py new file mode 100644 index 0000000..dd8dc80 --- /dev/null +++ b/scripts/pass_by_reference_list.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 15 09:10:52 2020 + +@author: https://www.tutorialsteacher.com/python/python-user-defined-function +""" + +def myfunction (seq): + print ("Entering sequence inside a function: ", seq, ' id', id(seq)) + seq.append(40) + print ("Modified sequence inside a function: ", seq, ' id', id(seq)) + seq = [1, 2, 3] + print ("New sequence inside a function: ", seq, ' id', id(seq)) + return + +mylist=[10,20,30] +print('mylist before call', mylist, ' id', id(mylist)) +myfunction(mylist) +print('mylist after call', mylist, ' id', id(mylist)) + +# this will not work +# mytuple=(10,20,30) +# print('mytuple before call', mytuple, ' id', id(mytuple)) +# myfunction(mytuple) +# print('mytuple after call', mytuple, ' id', id(mytuple)) diff --git a/scripts/pass_by_reference_number.py b/scripts/pass_by_reference_number.py new file mode 100644 index 0000000..c1f49af --- /dev/null +++ b/scripts/pass_by_reference_number.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 15 09:04:02 2020 + +@author: https://www.tutorialsteacher.com/python/python-user-defined-function +""" + +def myfunction(arg): + print ('value received:',arg,'id:',id(arg)) + arg = 8 + print ('value changed:',arg,'id:',id(arg)) + return + +#id() function returns a unique integer corresponding to the identity of an object. + +x=10 +print ('value passed:',x, 'id:',id(x)) + +myfunction(x) +print ('value after function call:',x, 'id:',id(x)) diff --git a/scripts/pass_example.py b/scripts/pass_example.py new file mode 100644 index 0000000..401f530 --- /dev/null +++ b/scripts/pass_example.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 11 19:20:37 2023 + +@author: u0015831 +""" + +n = 11 + +# use pass inside if statement +if n > 10: + # TODO complete this code! + # test to comment pass + pass +print('Hello') \ No newline at end of file diff --git a/scripts/people_data.csv b/scripts/people_data.csv new file mode 100644 index 0000000..48f3b73 --- /dev/null +++ b/scripts/people_data.csv @@ -0,0 +1,4 @@ +id,name,age,weight +1,Alice,20,120.6 +2,Freddie,21,190.6 +3,Bob,17,120.0 \ No newline at end of file diff --git a/scripts/person.csv b/scripts/person.csv new file mode 100644 index 0000000..71cf8ed --- /dev/null +++ b/scripts/person.csv @@ -0,0 +1,3 @@ +Peter,22 +Jasmine,21 +Sam,24 diff --git a/scripts/persons_bis.csv b/scripts/persons_bis.csv new file mode 100644 index 0000000..71cf8ed --- /dev/null +++ b/scripts/persons_bis.csv @@ -0,0 +1,3 @@ +Peter,22 +Jasmine,21 +Sam,24 diff --git a/scripts/print_1.py b/scripts/print_1.py new file mode 100644 index 0000000..e441600 --- /dev/null +++ b/scripts/print_1.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jun 28 10:29:50 2018 + +@author: u0015831 +""" + +print('Hello') + +a = 5 +b = 7 +# multiple objects +print('a =', a, ' b', b) +# use separator +l = [10, 1, 33, 34] +print(*l, sep='.') +print(*l, sep='\n') diff --git a/scripts/print_greet.py b/scripts/print_greet.py new file mode 100644 index 0000000..17700e5 --- /dev/null +++ b/scripts/print_greet.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 20:54:12 2019 + +@author: u0015831 +""" + +def print_greet( par ): + print('Greetings My Dear ', par) + return + +# test the function +print_greet('all_of_you') \ No newline at end of file diff --git a/scripts/print_greet_call1.py b/scripts/print_greet_call1.py new file mode 100644 index 0000000..8c29eb2 --- /dev/null +++ b/scripts/print_greet_call1.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Feb 19 08:07:33 2021 + +@author: u0015831 +""" + +from print_greet import print_greet + +print_greet('jan') +print_greet('jules') diff --git a/scripts/print_greet_call2.py b/scripts/print_greet_call2.py new file mode 100644 index 0000000..b1e285f --- /dev/null +++ b/scripts/print_greet_call2.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Feb 19 08:07:33 2021 + +@author: u0015831 +""" + +from print_greet_main import print_greet + +print_greet('jan') +print_greet('jules') diff --git a/scripts/print_greet_main.py b/scripts/print_greet_main.py new file mode 100644 index 0000000..a6ce7fe --- /dev/null +++ b/scripts/print_greet_main.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 20:54:12 2019 + +@author: u0015831 +""" + +def print_greet( par ): + print('Greetings My Dear ', par) + return + +if __name__ == '__main__' : # test the code without if + print_greet('all_of_you') \ No newline at end of file diff --git a/scripts/py_call_matlab.py b/scripts/py_call_matlab.py new file mode 100644 index 0000000..ba3574b --- /dev/null +++ b/scripts/py_call_matlab.py @@ -0,0 +1,10 @@ +p# -*- coding: utf-8 -*- +""" +Created on Mon May 28 11:07:12 2018 + +@author: u0015831 +""" + +import matlab.engine +eng = matlab.engine.start_matlab() +eng.triarea(nargout=0) \ No newline at end of file diff --git a/scripts/python_test.py b/scripts/python_test.py new file mode 100644 index 0000000..e802ea7 --- /dev/null +++ b/scripts/python_test.py @@ -0,0 +1,5 @@ +print("Running test.py") +a = 1 +b = 2.3 +c = a / b +print(c) \ No newline at end of file diff --git a/scripts/python_test_1.py b/scripts/python_test_1.py new file mode 100644 index 0000000..534228f --- /dev/null +++ b/scripts/python_test_1.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 13 10:43:56 2018 + +@author: u0015831 +""" + +x = 5 +y = 7 +z = x + y \ No newline at end of file diff --git a/scripts/quick_start_matplotlib.ipynb b/scripts/quick_start_matplotlib.ipynb new file mode 100644 index 0000000..2eb0577 --- /dev/null +++ b/scripts/quick_start_matplotlib.ipynb @@ -0,0 +1,1117 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# In recent versions of Jupyter notebooks, the command %matplotlib inline is unnecessary \n", + "# as the plots are displayed below the cell by default.\n", + "%matplotlib inline\n", + "\n", + "# Display output in separate window, interactivity is possible\n", + "#%matplotlib\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# matplotlib: an anthology\n", + "\n", + "This tutorial covers some basic usage patterns and best practices to\n", + "help you get started with Matplotlib.\n", + "\n", + "`pyplot` provides a convenient interface to the matplotlib object-oriented plotting library. It is modeled closely after Matlab(TM). Therefore, the majority of plotting commands in pyplot have Matlab(TM) analogs with similar arguments. \n", + "\n", + "resources used:\n", + "\n", + "- https://matplotlib.org/stable/tutorials/introductory/quick_start.html\n", + "- https://www.stat.berkeley.edu/~nelle/teaching/2017-visualization/README.html\n", + "- https://github.com/rougier/matplotlib-tutorial\n", + "- https://github.com/stefmolin/python-data-viz-workshop/blob/main/notebooks/1-getting_started_with_matplotlib.ipynb\n", + "- https://realpython.com/python-matplotlib-guide/\n", + "\n", + "\n", + "## pyplot vs. Object-Oriented interface\n", + "source: https://matplotlib.org/matplotblog/posts/pyplot-vs-object-oriented-interface/\n", + "\n", + "When using matplotlib we have two approaches:\n", + "\n", + "- implicit: pyplot interface / functional interface.\n", + "- explicit: Object-Oriented interface (OO).\n", + "\n", + "Check https://matplotlib.org/stable/users/explain/api_interfaces.html#api-interfaces" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### pyplot interface\n", + "matplotlib on the surface is made to imitate MATLAB's method of generating plots, which is called pyplot. All the pyplot commands make changes and modify the same figure. This is a state-based interface, where the state (i.e., the figure) is preserved through various function calls (i.e., the methods that modify the figure). This interface allows us to quickly and easily generate plots. The state-based nature of the interface allows us to add elements and/or modify the plot as we need, when we need it.\n", + "\n", + "This interface shares a lot of similarities in syntax and methodology with MATLAB.\n", + "The example below draws the graph of distance vs time\n", + "\n", + "```python\n", + "# matplotlib_first_plot.py\n", + "# using pyplot functions\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Data for plotting\n", + "time = [2, 4, 6, 8, 10]\n", + "distance = [1, 4, 9, 19, 39]\n", + "velocity = [1, 16, 26, 36, 111]\n", + "\n", + "plt.figure(figsize=(9,7), dpi=100)\n", + "\n", + "plt.plot(time,distance,'bo-', label='distance')\n", + "plt.plot(time,velocity, label='velocity') # scaling, another y-axis???\n", + "\n", + "plt.xlabel(\"Time\")\n", + "plt.ylabel(\"Distance\")\n", + "\n", + "plt.legend()\n", + "plt.grid(True)\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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6CIuuugibr75Zk488UTWr1/PGWecQVxcHF6vt8P1y5Yt4+KLL2bevHmAcwNfWlrK6NGju1znmDFj2LlzJxs3buy0t+CMM87ggw8+oLi4uNPnt4QLEREREQmchg/1oehoZ9lRcAJAey2P77+/b/YrSElJ4dprr+X222/ntdde4/333+fqq68+ak/En/70Jx577DHef/99tmzZwoIFC0hMTKSwsBBwVioqKSlh165dVFZWAk7wWLRoEStXrmTDhg3ccMMN7Nmzp1t1zpgxg+nTp/O5z32ORYsWsXXrVl566SX++9//AvDNb36TVatWcfPNN7Nu3TpKS0v597//za233tqD1hERERHpH43NofEBpkJBH5s7F555BvLzOx4vKHCO9+U+Bffeey/Tp0/noosu4txzz2Xq1KmMGzeu02szMjL4/e9/z5QpUxgzZgyvvfYazz//PFlZWQDcfffdbNu2jREjRrTub/D973+fM844gzlz5jBz5kxyc3P5zGc+0+06//GPfzB+/Hguv/xyTjrpJO64447WXokxY8awdOlSSktLmTZtGqeffjrf//73ycvLC6xRRERERPrJzv31TLt3Kc+XReH1dXMZyX6m4UP9YO5cuPji/t/ROCUlhQULFrBgwYLWY7fffnvr99u2bWv9/jOf+cwxb+gnTZrEu+++2+FYZmYmzz333DFrWLJkySeOHfmczMxMHn/88aO+xvjx43nllVeO+T4iIiIiweaRpVvYX+9heyxER5njP8FFCgX9JDoaZs50uwoRERER6Q97axr425s7AJiTH/xDiDR8SERERESkl/2+ZAtNzT7OLMxgRJrb1RyfQoGIiIiISC+qqm3kqTXOvk03zSj6xIIzwUihQERERESkFz2+YiuHPV5OzU9nanGW2+V0iUKBiIiIiEgvOVjv4YmVZQDccnYxJhS6CVAoEBERERHpNU+s2kZtYzMnDEpl9uhBbpfTZQoFIiIiIiK9oK6xmcdXbAXg5rOLiQryZUjbUygQEREREekFT60p40C9h+HZyfzPqaG10apCgYiIiIhIDzV4vDxa4vQS3DRzRNBvVnYkhQI5KmPMcXcsdvP1RERERILF397YQWVtI/kZiXzm9Hy3y+k2hQLpN+Xl5VxwwQUAbNu2DWMM69atc7coERERkR5qavbxf0s3A3DjzBHERofeLXaM2wVI5MjN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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "run matplotlib_first_plot.py" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Object-Oriented interface\n", + "When using the OO interface, it helps to know how the matplotlib structures its plots. The final plot that we see as the output is a ‘Figure’ object. The Figure object is the top level container for all the other elements that make up the graphic image. These other elements are called _Artists_. Artists are basically all the elements that are rendered onto the figure. This can include text, patches (like arrows and shapes), etc. The Figure object can be thought of as a canvas, upon which different artists act to create the final graphic image. This Figure can contain any number of various artists.\n", + "\n", + "Each plot that we see in a figure, is an Axes object. The Axes object holds the actual data that we are going to display. It will also contain X- and Y-axis labels, a title. Each Axes object will contain two or more Axis objects.\n", + "The Axis objects set the data limits. It also contains the ticks and ticks labels. ticks are the marks that we see on a axis.\n", + "\n", + "```python\n", + "# matplotlib_first_plot_oo.py\n", + "\n", + "# using oo approach\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Data for plotting\n", + "time = [2, 4, 6, 8, 10]\n", + "distance = [1, 4, 9, 19, 39]\n", + "velocity = [1, 16, 26, 36, 111]\n", + "\n", + "fig, ax1 = plt.subplots()\n", + "\n", + "ax1.set_ylabel(\"distance (m)\")\n", + "ax1.set_xlabel(\"time\")\n", + "ax1.plot(time, distance, \"blue\")\n", + "\n", + "ax2 = ax1.twinx() # create another y-axis sharing a common x-axis\n", + "\n", + "\n", + "ax2.set_ylabel(\"velocity (m/s)\")\n", + "ax2.set_xlabel(\"time\")\n", + "ax2.plot(time, velocity, \"green\")\n", + "\n", + "fig.set_size_inches(7,5)\n", + "fig.set_dpi(100)\n", + "\n", + "plt.show()\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "run matplotlib_first_plot_oo.py" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Showcase example code: Anatomy of a figure\n", + "\n", + "The code below shows the name of several matplotlib elements composing a figure\n", + "\n", + "source: https://matplotlib.org/2.0.2/examples/showcase/anatomy.html" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Anatomy of a figure\n", + "# This figure shows the name of several matplotlib elements composing a figure\n", + "# https://matplotlib.org/2.0.2/examples/showcase/anatomy.html\n", + "\n", + "\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from matplotlib.ticker import AutoMinorLocator, MultipleLocator, FuncFormatter\n", + "\n", + "\n", + "np.random.seed(19680801)\n", + "\n", + "X = np.linspace(0.5, 3.5, 100)\n", + "Y1 = 3+np.cos(X)\n", + "Y2 = 1+np.cos(1+X/0.75)/2\n", + "Y3 = np.random.uniform(Y1, Y2, len(X))\n", + "\n", + "fig = plt.figure(figsize=(8, 8))\n", + "ax = fig.add_subplot(1, 1, 1, aspect=1)\n", + "\n", + "\n", + "def minor_tick(x, pos):\n", + " if not x % 1.0:\n", + " return \"\"\n", + " return \"%.2f\" % x\n", + "\n", + "ax.xaxis.set_major_locator(MultipleLocator(1.000))\n", + "ax.xaxis.set_minor_locator(AutoMinorLocator(4))\n", + "ax.yaxis.set_major_locator(MultipleLocator(1.000))\n", + "ax.yaxis.set_minor_locator(AutoMinorLocator(4))\n", + "ax.xaxis.set_minor_formatter(FuncFormatter(minor_tick))\n", + "\n", + "ax.set_xlim(0, 4)\n", + "ax.set_ylim(0, 4)\n", + "\n", + "ax.tick_params(which='major', width=1.0)\n", + "ax.tick_params(which='major', length=10)\n", + "ax.tick_params(which='minor', width=1.0, labelsize=10)\n", + "ax.tick_params(which='minor', length=5, labelsize=10, labelcolor='0.25')\n", + "\n", + "ax.grid(linestyle=\"--\", linewidth=0.5, color='.25', zorder=-10)\n", + "\n", + "ax.plot(X, Y1, c=(0.25, 0.25, 1.00), lw=2, label=\"Blue signal\", zorder=10)\n", + "ax.plot(X, Y2, c=(1.00, 0.25, 0.25), lw=2, label=\"Red signal\")\n", + "ax.plot(X, Y3, linewidth=0,\n", + " marker='o', markerfacecolor='w', markeredgecolor='k')\n", + "\n", + "ax.set_title(\"Anatomy of a figure\", fontsize=20, verticalalignment='bottom')\n", + "ax.set_xlabel(\"X axis label\")\n", + "ax.set_ylabel(\"Y axis label\")\n", + "\n", + "ax.legend()\n", + "\n", + "\n", + "def circle(x, y, radius=0.15):\n", + " from matplotlib.patches import Circle\n", + " from matplotlib.patheffects import withStroke\n", + " circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1,\n", + " edgecolor='black', facecolor=(0, 0, 0, .0125),\n", + " path_effects=[withStroke(linewidth=5, foreground='w')])\n", + " ax.add_artist(circle)\n", + "\n", + "\n", + "def text(x, y, text):\n", + " ax.text(x, y, text, backgroundcolor=\"white\",\n", + " ha='center', va='top', weight='bold', color='blue')\n", + "\n", + "\n", + "# Minor tick\n", + "circle(0.50, -0.10)\n", + "text(0.50, -0.32, \"Minor tick label\")\n", + "\n", + "# Major tick\n", + "circle(-0.03, 4.00)\n", + "text(0.03, 3.80, \"Major tick\")\n", + "\n", + "# Minor tick\n", + "circle(0.00, 3.50)\n", + "text(0.00, 3.30, \"Minor tick\")\n", + "\n", + "# Major tick label\n", + "circle(-0.15, 3.00)\n", + "text(-0.15, 2.80, \"Major tick label\")\n", + "\n", + "# X Label\n", + "circle(1.80, -0.27)\n", + "text(1.80, -0.45, \"X axis label\")\n", + "\n", + "# Y Label\n", + "circle(-0.27, 1.80)\n", + "text(-0.27, 1.6, \"Y axis label\")\n", + "\n", + "# Title\n", + "circle(1.60, 4.13)\n", + "text(1.60, 3.93, \"Title\")\n", + "\n", + "# Blue plot\n", + "circle(1.75, 2.80)\n", + "text(1.75, 2.60, \"Line\\n(line plot)\")\n", + "\n", + "# Red plot\n", + "circle(1.20, 0.60)\n", + "text(1.20, 0.40, \"Line\\n(line plot)\")\n", + "\n", + "# Scatter plot\n", + "circle(3.20, 1.75)\n", + "text(3.20, 1.55, \"Markers\\n(scatter plot)\")\n", + "\n", + "# Grid\n", + "circle(3.00, 3.00)\n", + "text(3.00, 2.80, \"Grid\")\n", + "\n", + "# Legend\n", + "circle(3.70, 3.80)\n", + "text(3.70, 3.60, \"Legend\")\n", + "\n", + "# Axes\n", + "circle(0.5, 0.5)\n", + "text(0.5, 0.3, \"Axes\")\n", + "\n", + "# Figure\n", + "circle(-0.3, 0.65)\n", + "text(-0.3, 0.45, \"Figure\")\n", + "\n", + "color = 'blue'\n", + "ax.annotate('Spines', xy=(4.0, 0.35), xycoords='data',\n", + " xytext=(3.3, 0.5), textcoords='data',\n", + " weight='bold', color=color,\n", + " arrowprops=dict(arrowstyle='->',\n", + " connectionstyle=\"arc3\",\n", + " color=color))\n", + "\n", + "ax.annotate('', xy=(3.15, 0.0), xycoords='data',\n", + " xytext=(3.45, 0.45), textcoords='data',\n", + " weight='bold', color=color,\n", + " arrowprops=dict(arrowstyle='->',\n", + " connectionstyle=\"arc3\",\n", + " color=color))\n", + "\n", + "ax.text(4.0, -0.4, \"Made with http://matplotlib.org\",\n", + " fontsize=10, ha=\"right\", color='.5')\n", + "\n", + "plt.show()" + ] + }, + { + "attachments": { + "matplotlib_hierarchy.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## matplotlib Object Hierarchy: more\n", + "source: \n", + "- https://realpython.com/python-matplotlib-guide/\n", + "- https://www.janmeppe.com/blog/Plotting-with-Matplotlib/\n", + "\n", + "One important big-picture matplotlib concept is its _object hierarchy_: there is a tree-like structure of matplotlib objects underlying each plot. Basically, the hierarchy is as follows: Figure, Axes, Axis and all other stuff that goes on a plot. \n", + "\n", + "A Figure object is the outermost container for a matplotlib graphic, which can contain multiple Axes objects. One source of confusion is the name: an Axes actually translates into what we think of as an individual plot or graph (rather than the plural of “axis,” as we might expect).\n", + "\n", + "- A Figure object can have multiple Axes objects. This thing right here is what makes the terminology so confusing, think of the Axes object simply as an individual plot or graph.\n", + "- An Axes object has two Axis objects (x-axis and y-axis)\n", + "- Below the Axes in the hierarchy are smaller objects such as tick marks, individual lines, legends, and text boxes. \n", + "Almost every “element” of a chart is its own manipulable Python object, all the way down to the ticks and labels.\n", + "\n", + "![matplotlib_hierarchy.png](attachment:matplotlib_hierarchy.png)\n", + "Chart: object hierarchy (source: https://www.janmeppe.com/blog/Plotting-with-Matplotlib/)\n", + "\n", + "You can only manipulate one Axes object at a time. With pyplot, simple functions are used to add plot elements (lines, images, text, etc.) to the current Axes in the current figure.” \n", + "\n", + "Functions like gca() refer to getCurrentAxes() which basically grabs the current Axes so you can work on it." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Getting started\n", + "\n", + "imports are necessary to use matplotlib. Use some standard shorthands for Matplotlib imports\n", + "\n", + "```python\n", + "\n", + "import matplotlib as mpl\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# use some standard shorthands for Matplotlib imports\n", + "\n", + "import matplotlib as mpl\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A step by step example\n", + "\n", + "source: https://matplotlib.org/stable/tutorials/introductory/quick_start.html#sphx-glr-tutorials-introductory-quick-start-py\n", + "\n", + "matplotlib graphs your data on a `figure` each of which can contain one or more `Axes`, an\n", + "area where points can be specified in terms of coordinates \n", + "\n", + "The simplest way of creating a Figure with an Axes is using `pyplot.subplots`.\n", + "\n", + "Note: With subplot you can arrange plots in a regular grid. You need to specify the number of rows and columns and the number of the plot. Note that the `gridspec` command is a more powerful alternative.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Parts of a Figure\n", + "\n", + "Here are the components of a matplotlib figure." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `figure`\n", + "\n", + "The **whole** figure. The figure keeps\n", + "track of all the child `Axes`, a group of\n", + "'special' Artists (titles, figure legends, colorbars, etc), and\n", + "even nested subfigures.\n", + "\n", + "The easiest way to create a new Figure is with pyplot::\n", + "\n", + "```python\n", + " fig = plt.figure() # an empty figure with no Axes\n", + " fig, ax = plt.subplots() # a figure with a single Axes\n", + " fig, axs = plt.subplots(2, 2) # a figure with a 2x2 grid of Axes\n", + "```\n", + "\n", + "It is often convenient to create the Axes together with the Figure, but you\n", + "can also manually add Axes later on. " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure() # an empty figure with no Axes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "print(type(fig))\n", + "print(type(ax))\n", + "print(dir(ax))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 2 axes columnwise\n", + "fig1, axs = plt.subplots(2,1)\n", + "\n", + "print(type(axs))\n", + "print(type(axs[1]))\n", + "\n", + "\n", + "fig2, (ax1, ax2) = plt.subplots(2,1)\n", + "\n", + "print(type(ax1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#2 axes rowwise\n", + "fig, (ax1, ax2) = plt.subplots(1,2)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `Axes`\n", + "\n", + "An Axes is an Artist attached to a Figure that contains a region for\n", + "plotting data, and usually includes two (or three in the case of 3D)\n", + "`Axis` objects (be aware of the difference\n", + "between **Axes** and **Axis**) that provide ticks and tick labels to\n", + "provide scales for the data in the Axes. Each `Axes` also\n", + "has a title\n", + "(set via `set_title`), an x-label (set via\n", + "`set_xlabel`), and a y-label set via\n", + "`set_ylabel`).\n", + "\n", + "The `Axes` class and its member functions are the primary\n", + "entry point to working with the OOP interface, and have most of the\n", + "plotting methods defined on them " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "time = [2, 4, 6, 8, 10]\n", + "distance = [1, 4, 9, 19, 39]\n", + "\n", + "print(type(time))\n", + "\n", + "fig, ax = plt.subplots()\n", + "ax.plot(time, distance)\n", + "ax.set(xlabel='time',\n", + " ylabel='distance (m)',\n", + " title='Distance Graph')\n", + "\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `Axis`\n", + "\n", + "These objects set the scale and limits and generate ticks (the marks\n", + "on the Axis) and ticklabels (strings labeling the ticks). The location\n", + "of the ticks is determined by a `Locator` object and the\n", + "ticklabel strings are formatted by a `Formatter`. The\n", + "combination of the correct `Locator` and `Formatter` gives very fine\n", + "control over the tick locations and labels." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `Artist`\n", + "\n", + "Basically, everything visible on the Figure is an Artist. When the Figure is rendered, all of the\n", + "Artists are drawn to the **canvas**. Most Artists are tied to an Axes; such\n", + "an Artist cannot be shared by multiple Axes, or moved from one to another." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Input to plotting functions\n", + "\n", + "Plotting functions expect `numpy.array` or `numpy.ma.masked_array` as\n", + "input, or objects that can be passed to `numpy.asarray`(e.g. a Python list, pandas DataFrame). \n", + "Classes that are similar to arrays ('array-like') such as `pandas`\n", + "data objects and `numpy.matrix` may not work as intended. Common convention\n", + "is to convert these to `numpy.array` objects prior to plotting.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "use `Axes.plot` to draw some data on the Axes:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots() # Create a figure containing a single axes.\n", + "ax.plot([2, 4, 6, 8, 10], [1, 4, 9, 19, 39]); # Plot some data on the axes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(19680801) # seed the random number generator.\n", + "data = {'a': np.arange(50),\n", + " 'c': np.random.randint(0, 50, 50),\n", + " 'd': np.random.randn(50)}\n", + "data['b'] = data['a'] + 10 * np.random.randn(50)\n", + "data['d'] = np.abs(data['d']) * 100\n", + "\n", + "fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')\n", + "ax.scatter('a', 'b', c='c', s='d', data=data)\n", + "ax.set_xlabel('entry a')\n", + "ax.set_ylabel('entry b');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Styling Artists\n", + "\n", + "Most plotting methods have styling options for the Artists, accessible either\n", + "when a plotting method is called, or from a \"setter\" on the Artist. \n", + "\n", + "In the\n", + "plot below the *color*, *linewidth*, and *linestyle* of the\n", + "Artists created by `plot` are set, and we set the linestyle of the second line\n", + "after the fact with `set_linestyle`.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAUEAAACyCAYAAADcf30yAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAw4klEQVR4nO2dd3hUVdrAfyehh05o0kIXUIoUCyKCoICrYP0Q29pw7etiXVdlLdhQV3dZFXuhqGtXpCtNqYJU6SABAoHQQoCUeb8/3hnvTDKTMpnJzGTO73nmueeee+6970kmb055ixERLBaLJV5JiLQAFovFEkmsErRYLHGNVYIWiyWusUrQYrHENVYJWiyWuMYqQYvFEtdUiLQA3iQnJ0tKSkqkxbBYLOWMZcuW7ROR+v6uRZUSTElJYenSpZEWw2KxlDOMMdsDXQvJdNgY844xZq8xZrVXXV1jzAxjzEb3sU4o3mWxWCyhJFRrgu8Bg/LVPQTMEpG2wCz3ucVisUQVIVGCIjIXyMhXPRR4311+HxgWindZLBZLKAnn7nBDEdkN4D42COO7LJaAjBsHgwbBTz9FWhJLNBJxExljzEhjzFJjzNL09PRIi2MpZ2Rnw2+/waFDcMMNkJMTaYkihA2UEpBwKsE9xpjGAO7jXn+NRGS8iPQQkR716/vdwbZYgqZiRdizRz9bt8Jnn0Vaogiw8XWYXAn2LYy0JFFJOJXg18D17vL1wFdhfJfF4hdjoFMnVYA5OfDyy3E4KFp+H0huHHa8eITKRGYS8DPQ3hiTaoy5CXgWGGiM2QgMdJ9bLGXOX/4ClSppefFiWBhPAyIR6DYWml4CdbtHWpqoxERTUNUePXqINZa2hIMbb4R339XyFVfAJ59EVh5L2WKMWSYiPfxdi/jGiMUSLnbsgAsugL//Hdq2deo/+wy2bQvNOzZuhCeegBUrQvO8sLH6aZh1Hhz9PdKSRB1WCVrKLUuWwPTp8MwzMHMm9O+v9S4X3H136ZfIDh2C3r3h8cfhxx9LLW7oyTkMy/4Ge+ZA+jzYMxsylkVaqqjDKkFLueWXX5zyaafB6NHO+TffwOTJpXv+G2+Ax6pryZLSPSss7J4G61+GlY9CndO0LuOXwu+JQ6wStJRblnkNerp3hz594Pbbnbq77oK9fg23iub4cd1p9lCxou/13NzgnhtSUr/WY9OLoa5bCR6wSjA/VglayiUivkrwNLcOePZZaN5cy/v3w6OPBvf899+HtDQtN2kC48drOSsLXnoJWrYM3bpjULhyYdd3Wm5ykaME7UiwAFYJWsolO3c6U9UaNaBNG6f85pvQtCm88orvaK645ObC888756NGOSY4116r56mp8PTTpetDqdi/BLIPQPU2ULM9JLWEirXgeBoc2x1BwaIPqwQt5RLv9cBu3SDB65t+/vlqPH333VCtWsmeu28f/O1vsGWLntepA7fc4ly/806n/Pbb8MMPJZc9JKTP1WOj8/RojB0NBsAqQUu5xN9U2JsKJQwnLAIvvAAtWsC//+3U33UXVK/unJ97ripZzz1XX+2MSMuUPXP02OAcp85ujvjFKsFyyvvvw9KlUbJAHwGWL3fK/pRgSfnuO3jgAV3z83DmmTr19cYYNcr2uMHv3g3XX69mOWWGKxfS52u5QV+n3m6O+MUqwXJIRgb8+c/Qs6f+MWZnR1qiwBw4EB4FsX69Uz711MLbLlkCl17qTHH90bOnut8lJECzZvDppzB/PtSsWbDtSSfpPyEP33/vbJyUCQd/hdwjUL01VGvi1HtGgntmw2//ghP5QoCeyIB5V0DarDITNRqwSrAc4u0b27ats2gfbbzxBtSrB127+o6wSktOjq9C8/YWyc8jj0CvXvDFF3DHHYENqBs2hNdeg1WrdKp9+eW+64z5GTwY7rvPOX/ySTWrcbl0Wn3ddbouGRb8TYUBarSF2p3ViPqXe+HLJrDre+f6xv/Cjv9B6pdhEiw6sUqwHLJggVPu3VuPhY1yIkF2to6sRFSxfPFF6J5tjG5IvPWWurQlJQVue+GF2h5g6lT4z38Kf3bHjs5UtyieeAIaNdLyrl3wzjvw0Uc6rf7wQw30mpnpe8+RI7ph889/lmKEvNejBPv61ickwqCl0OczaP5/cO73UL+Pcz2pBdQ7A2p3CfLFMYqIRM2ne/fuYik9ffuKqHoRuf12kSFDtPzTT5GWzOHzzx0ZQWT48MjJct99jhyVK4usWqX1OTki27eX7tkvv+w8u2lTkSNHRDp0cOquu863/d13O9cmTw7iha48kU/riExA5MiW0glfjgCWSgC9Y0eC5YycHA0X5WHzZpgyRcvPPVf0/Wlpal4ydar622bkzxwTIt5+2/d8+vTIbeI89RR0cQ9+TpzQEdrrr+s6Ye/eanMYLCNHQgN3YomEBPj9d3j4Yef6Bx/oB3R0/OqrzrWg1hGzdkJCRajWDJJSghP6yCb4+XrY/E5w98cagbRjJD52JFhyUlNFFi92zhcvdkYSKSkiK1f6jrhmzBCZOFHkxAlt73KJjBolYoxIx46+bT2f1q1FHntM5Pjx0Mi8c6dIQoLvO0aMENm3LzTPD4bVq0WqVPHf/86ddQQXLO++KzJ+vPMzF9ERoOf5SUki27bpqNP7vaecEuQLXS6RrLSi2216R+SHP4nsnS9yLF3k4FqRvFyRrRN1JPllikjuiaKfEwNQyEgw4orP+2OVYPFZt06kTRv9DXbq5NT/61++ikVE5OqrnboaNfTYpIm2HTbM/x++v88994RG9jFjnGc2b67TzlCSmRncfZ9/LlKvXsF+P/igSF5eaGU8ckSkXTvnHddco/WHDzt1CQklVL552SUTYvEdquzWPCuy8U0tL7hWFeE3HfT8t1dK9swopTAlaKfDMUqzZrB9u5bXrHECAfjbFHnmGahaVctHjuhx504NBXX0qO9zq1ZVk5LzzlOzEM/Ocv36vtO4YBHRDQIPY8aU3HC5KFq21N3cc85RE5zicskl6u87dqyauVSvrjvCzz5b+E5wMFSvru57Hj76SJchatRwTHpcLrX1LEDOEdg7Dw6ucur2LYZvT9ZjcWl1PZw1CVKudmwH63TWDZSu7kDwq0bDif0l6VrsEUg7RuJjR4Ilo3dvZ9Tw6ac6CzrpJKduxQqn7aOP+o5uqlbV6WdGhsitt+qocfLkgqOo48dF/v1vkW++CY3M69c7085atUSyskr/zNWrRa68UuSdd7Q/nj5WqRL8CM7l8p2+houLL3bk7d9f33vLLU7dM8/ku2HPPJFJlXWUtmikU7/kTq2bH+QO09Qz9P7dM/Xc5RKZeZ7WLbkruGdGERQyEgzx/2BLWfDTT2pzdsYZzsjvxx915LZrl57XqAGnnOLc88ADajKy2+07f+ONaqMHugkQiMqVff1hS0u7dhrxefx43cTxjFCD5fhxtcnbsUND5ntvrrRtG/wIzpiysa987jn1RsnLg9mz1bD6jDN0lFij6mEq7foG8i6DxCp6w++fguuEGkIntXAe1O1FqN4K2gXxy3LlqYE1QJ1uejQGTnsJpnZT+8G2t0GtDqXrbLQSSDtG4mNHgsXjoosKrlt17CiSmyvy8ccip54qMnBgwfu++05HgCkpuqESLWRmikyapKPR888v2ejtxRedn0HFiiJjxzrnl18ePplDyciRKm+fPiKzZomsWSOSmJAjS586TWQC4lo1xmk8pauOztJ+DM3LU78TmX62sxGSn0W36rV5V4TmfRECuyZYfsjLg3nzCtavXavx8a68UvNdeJIKeTNkiLbZuFFj4JWU7GyYOxceeyy4EFSBOHxYPSgmTlRTmXeKaZlx6JBvuKoXX/Q16WnXLnQyhhOPUfW8efDee3DyyfDSdQ/TvaWu0+3Lcv+ysg/CgV/VBKZer9C8fO8Pjp+xZxToTYf73e3mlNuUnVYJxhirVsHBg1pu2NDZ/ACY43YUSEgIrOSqVg1+I2LBAujbV13ACptCl5TGjXW67uHBBzVkVVGMHesovZQUuPVWX5/h9u1DJ2M4adhQXfE8PsYJqZ9y98Cx5EkF1jefR53TrtOG6QsAUQVYoZTrCB7qeiVgq+sn0kT1Vu44hHvLbRxCqwRjDI+iA1VI/fo55+FO9nPmmc4a3oYNavhbXF59Vd3k1q71f/2RR3RXF1SxeStFf6SmagRnD08+qWt4sagEQXejBw2CKgmHYOFNACR2H0v7s892/mntdccIrH+O/4cEQ72eTtnfSNAYqNNVywdWlPz5abNh3UuQdyIY6coEqwRjjPxK8NxznfNwB/CsUkXzdHiYVcxgI+++qyGn3ngDOnXSJEf5qVrV12/33Xd1o8Afhw/Dn/7kBF3o3BlGjNClgo0bnXaxMh32Yc9sjQBT73RofzfkZasi2TaZE6luJZg/MEJpSGrplP0pQe/6A8v9Xw+EKw8WDIflo2DmOVGb7jPsStAYs80Ys8oYs8IYYzOrl4LDh31He3376ujMw7p1+gknAwY45RkzCm97/LjuLN94o7Nr27y52iD6Y8gQtdXzcN11uobpTU6ORnD51b2ZmZioo8yEBA12esJrwFGnTvH6FFWkuX+oJ7kjOxzZCLPPg8U3U/HwYvJcCVz457OYOzdE7zMGhqyCgfOh2kn+2/yhBFeU7Nn7F8OJdKf8fTf3lD66KKuRYD8R6SoBMsBbisejjzrGv82aaUSTatXgmmu0rk0bJ4lQuPBWgjNn+kY6OXBAo9VkZqqy7twZxo1zrp96qo7uCgtpP24cJCdreedOXefzrMeLqC+ut/J98039ZwC+EVm6dg2md2XEobWwbaL/jYbd0/XYeCAAUrMjB6qcT/qJk0kwLpZv68aUGTVxuUIYh7H2KVC/d+DrjfrDWROg6zMle+5O95A/5VpoPAiyM2DZX4MWM2wE2jYO1QfYBiQXp601kQnMkiXq3+sx/5g40bmWkyMyZ47I/v3hlyMvz9e1bNEirZ8yRU1UArncXX558V3Avv7a995nnlHb3bw8kTvucOoff9z3vsxMkTPPVF/cL78MabdDy7enuF3SXvWtP7JZ6z+pLZKXI3v2iPTqpX0dfdnjIhOQF6++9w+3x0hG3ikWnn7uniGSkyXycZKeZ5YyNE8QEGETGQGmG2OWGWNGlsH7yh25ub4jovPPh+HDnesVKqiLWN264ZclIQEuuMA5f/hhlWvlSv8jk5o1dSf5k098c3EUxkUXwW23OedPPw179jhT3jFjdIr9+OO+9yUlqSH5gQMwdGjJ+1YmZB+EQ6u1vPVD39HgbvcQt1F/SKhAcrIzuu3TXue/c3/T9cCdO303gaKOzG3azwo1dCOnQlXo+hyc8xVUaRBp6XwJpB1D9QFOch8bAL8C5+S7PhJYCixt3rx5uP8hxCR79jguclWqiGzaFFl5Vq8WSUx0RmSff671K1bouTEilSqpK9vOncG94+hRka5d9Xkvv1zwussVtPiRJfU7HQ1NoGDAg7mXaf2G1/+oeust/Rn07fCD/POyR6Vu9X0+0WfK7OewZ47I4ttEtv+veO1/+7f2ZW50WKwTLVFkgNHAfYGu2+lwYPLyNBzTv/4VaUmUu+5ylGDLliLHjjnXXC71XiktR46IvPBC6KPMRJTlD6pyWP6QU+dy6eeLpgWCoR47JtKwofOzbt1apE4d57zMPH88Su3nG0SO7RH5rrPI/BGB28++QNtvfr/w57oKcQ/KPiTy+xciWycFJbI3hSnBsE6HjTFJxpganjJwPrA6nO8sryQkaH7be+6JtCTK6NHqe2yMTs+9kzkZo7u2paV6dc3TEeooMxFlbz4zl+N7YdHNsH0SXLRJd2mrO2YrVapouH0P11zja/+4YUMZyAy6UdNtLLQZCT9dAwdXwvaJGoDVHycN0fD+Jw32rd87D+YPhy0fwL6F8FULmH8liJ+1lMxtMO8S+PXvIe+ON+H+ejUEvjCaxKECMFFEpob5nZYyoG5ddW9r3jzKd2KjidwsyFgKGEg+S//wF1yltoHZByBlhN9d2vvv15Bnx46pN83WrU4yrQ0bfA3mQcOqvf46fPaZBpF4773ir8cGpGZ7/ax60jHjAdg2CU59VMsHVmh4r5bXqo1j+7sLPufIJvj9Y90prtkBslI1KESd06DTQ067/UthsTur/dGtcHwfVEkuZSf8E1YlKCJbgC7hfEd5ZssW9aLwJAKKNi6+ONISxBj7F4ErR+3uKtXSun7TYet7vgmP8lGxoq+PtLcRuPdIMDdXleS4cY695MqV2n7MmBDIf2QTrB4NGDj5XvjtJdg+AU75BxzbCdPPgkp1IeWawF/aphdD9ovQ7BKo1hyOboOdX8PKf0DDcyH5DG2XNsPXLjFjKZw0KASdKIj1GIlSsrPVELp7d/Ww8N5EtMQoe92RL7wVXkIitL4JahbfvcWfEszN1STvL73kazAOmsMkf11Q1GgDvT+BLmM06Grl+nB4vXqSJFSGltdB1cYghSSLqVwPOvxNp/wJidD3K2h/L0iejoqzD2m79vfAuVOhYX8931+CYLElxCrBKMUTLXr5crj55uhOoG4pJvnXA4MkvxL0KMCJE536nj11mWLUKA26UblyqV7p0PwynbYmVITmV2rdtolQpT70eh0uWKTXSkLXZ3Q6fHQbrHA7jVeoBiddAK1v1vP9S0LUgYJYJRileE9zTj89hF9iS2Rw5cC+n7XcIPDUtzh4J5PfsgXuustXAd52GyxapKH5x44No/tgygg9bpugfsIAJgiVklgZzvpQleem8c6IGZyQYRlLwjYdskowSvFWgrEUDcUSgENrIC9LNxdKaSxcrZq6TYKOAr3Dmt12m64JhmqHvlCS3Y7rx9Ng9ROle1atjtDRvTEy8xz48ULdPa7eStcZj++BrB2le0cArBKMUry9AWIyGorFlzpdYeg26BmaQIzvvacxCE/zCgE4bJijAEvLlCnwwgsFE3H5YAx0ce/YVKxR+pd2+rv+kwDYNUV3041xYh6GaUpslWAZMXOmhn/66KPitfceCVolWE5IaqE7oCGgf39VgHPmaJzGBg00VJk/BZiXp9PjJ5/0DcUWiDVr9Lv6wANw7bVFNO7wIAxZCSePCqofPmvdiVWglzsFX0JFqH+Wlj0xDzOsEoxZXC79Mn33nR7feqvw9iJWCcYMe+fq1C2jkFh7/gyBQ4QnLejataoI/fHkk5q86bHHYNKkop+ZlAStWmn5iy/0H3hAEhKh9qlBDT9TUzWq+CmneKVFaNAH+n4H/Wc5yaU864J2JBiDZB+E1G/YPec/XNfjOR686Fnq19zLrbeqo38g0tM1fwZo1rhGjcpEWkswrBqtU7fZAzT/hz82vak5gbd8EDYxPJkD/dG/v1OePr3oZ6WkwNlnO+d//atvFr9Q0aSJBtZITfUNqEuTIb6bR56R4P4lYfmHUp4ckqKHjF9g8V/c3gFCE+C5q/RS64abWeh6k16F5MnJvx4YrcbScc/xvZqACNQDYvYAOO8Hjc/nTdpMtaeTnLKXER0FJiXp+t7WrbB5M7RuXfg9zzyjHieZmTo9fuMNuOOO0Mr12Wfw0EPOVP7hh9UwvABVG2uK0aPb9G+rXmjDktqRYDjYPRUOLAME6p/N9K23MW7G7QBc0vMr3hqfV9AfNm0WLL8fcrPsVDhWyNwK1VpAw/PUV/bEPt3ZTP3at13viaocmw6LiJiVKvm61hVnNNi4Mfzdy2X3scecBF+h4uKLVclu3Kj5sv2lXfiD09+EizaEXAECNu9w2Ni/VOTEAXG5RBo1EgGXbHyxtUbW2DPPt63LJfKV+9riO+SBB5woIaNHR0Z8SzFxuUROHBDJPSYyZ6gTJmvpvSLZxYwiWwa8+qrznRo2LHA779Bcx45phCDPfR98UHo5Jk4Uychwzh95xHn+gAGlf34gsHmHS4ErF3ZOgRMZRbf1pm53qFSbzZshLQ3A8P3qYXot9UvftofXQeZmLW8cxxO3z2DlSvj0U82nYYlijIFKtXURv88XGmnFVID1L8PnDTRCyvFi5A8NM+ef75Rnz9bc1PPnF2z36qvQoYNGq5k7V72VPEybVjoZFiyAq6/WtBBffKF1I0dqhCTQDRh/gWJzcjRq0YUXwjnnCJ+8OiukhtNWCRaGCCz5C/x8rZMwpjDWPg87v/X5BXknxNkhw7SQ+iWIkJGhju0H13yl9ZV1dbvyLzdwavIMLk+5h07pf4KsXaHpjyV0HFoLWTt964yBDqNg4DyofzbkHdMIKT9fBzmHIyOnm3btnPwzhw9Dt26qgPKzeDH89htMmKDTVO8o4tOnF4wePneuhvpaXkQiumPHNBq4iA4K3nxTy82bayRxD/7yWT/+OPzzn2q7+MhZg7gyeQDsLqVG9sIqwcJY+xxsfhsqJ6vVemEc2w0rHoS5Q51RHb5KsH6HM9XpPHMzk15fQ7Nmmm/30Br3GlLP16DeGRqR44fzYcOraleWaH3moo7l98OXTWHH5wWvJZ+hinDoduj2ovrbVqxZ9jJ64Yn76E3+TH6gBtgeundXZelJfJWe7mT5A93M6NdPUx707asbKIF4/HHH7KtGDV+bRu9UCh98oCM/Dz//DM8955x/88tFfL3xvsDpQYMgfpXgru9hZl84ut3/9e2fwK8PA0YjZlSpr/+6Dq6GE36+PVUbQ9vboOsLGm3DTatWmmsXoM85iRpKyFSgfcMVZGVBw1ppNKu6iBO5lXnl08Ec7fKBKsqkFtDhPk29WLkQ+wdL2SOiuTMqJOmILxBJzTViSuubyk62QnjgAWjaVN3p2rRRn3RvDh1ypqOJidCli05VBw502kybpt1/9FE10vaMDI8c0RFder4J07FjOhAYO9ape/55x+0P9Pme84wMxy7x6FFNu+p5R9++cPnf76TDiBegasPS/TC8CbRYGIlPKDdGcnM1A9u+fQEaeBaw511Z8Frm705mrLVjnfqfb9C6jW94vShfXPkApKe7w8QfTRU5cUDy8kROPlkkqfIRubr3h/LgRc8IiDRrJrJ4kUvycmM1iUYc4f27jxFcroLpCnJyRCZPdjYoQKRLF+f65MkigwdraofNm0WefNK3rfenTx9NBSEiMmGCSOPG+p323vzI8xNRf9Qop81112ndnXc6dTVqiGzbFny/iZYcI0V9QqkEb7lFe9eokZ9Uj0e2OkpwyV0Fb55ziTtJzKW+im3DayKfNdJ8CyIimdtEJlcRmfd/Qcm4Ymmm9O+XKwkJ/r9Qjz0mIoc2iCwb5bzTEjmO7xM5uC7SUoScI0d885aAyI03+m87b574fF8HDdIdX2M0CdjHH2u7p54q+H2uUydwTpQlS5x2NWuKLFzom2L23XdL18e4U4ILFvj+8L/9Nl+DtWNVyc25pODNO77Wax9XFzm6w/da7ol8SvF1R1mWFJdLTSpmDZR9aYdl7FgpoAxfeEFEdk3Td3zbseTvsISW+SNE/ldPZP+ySEsScrxNVUBk3LiCbfbv9x3VnXOOSLY7Yd7rr4ssXuy0XbZMpHJl32d6FKQ/XC6RNm1EzjpL5JVXRE4/3VfRljarXmFKsNytCbpc6ubjzeL8QWl//58ePfHQPOQehWV3abnzU1Ctqe/1xEq+7hu73elSGhcM+71lSxHRfI9uhz0/gLiol7CSUaPUbMD78V26AA37QYf7odd4G146kuQe0139E/uhQmkTdkQfd97pe97Dj03y4sUa6Bc0x8yECY6Hx623aiBXD6edpj7NHq69Fq68MvD7jVGznQUL1G1v0SKtT0zUaNnh9Joqd0pwwgRYks/P2kcJHt0B+xdCYlXNhJV7zHHMXvWEKqc63aBdIT5C2QfgwEr18gBofIHPZZcLLrlEg1++9ZbvbtcfVE+BC9dArQ6A/oYvvlhttwYM0ECZAwag0TS6Pa8JeA78Aisfh3mXweGySjNmAWDPLI0HWLd7iULhxwqNGsFTT2n53HP9K8FBg/RvqUMHTbLVtGnBNt7ccANMnap/A2+/XbQMSUl63LfPSQz1l7/o+8JKoCFiJD7BTIddLpFDh5zzCRNEkpN9h+F163oNp9f9yz2FvUzzmk6uput66QtFJiaKTDAi6YsCvzDtR5GJCSKf1Aw4TfVeZE5K0uTpIeH7ns5a5s9/DtFDLcVi4U36c1/5RKQlCSsHDxY99czOLvx6KEhL042R9PTQPI/yOB3euRP+8Q91BL/lFqd+xAg18vzHP6B2ba3LyNDpKQA73FPhZper7VatTpr6b86fNNlLuzsguZDoBnW7AQmO8Wu+qXBWlpoPeLjnnsAhjkpMqz9DytVa3vmNerN4Y6fL4cGVpz9vgKZDIytLmKlVq+ipp98gByGmYUO1P/TYKIaTmFWCBw9qGsKtW+Hrr9VOyUPt2hpDzdsOavFi4FgapC/QzFhNLtQLA+dC32/UFq/qSboWWBgVazphxYGV+wbx5JMamQN0PXLjRi3XqqXJw0NGu9vhzA+hehtdm9rnFY/r4GqY1U+NtiGsMezijv2LNGJMUkuNnWcpV8SsEuzUCTp31vLx4/DllwXb9OqleXuHD9eoGOz5ERD1wvCEA0+sAtWawOBfNQesJx9sYTRW03tJrMrz7/bhscd0E+O229QdyMOLL4YhyY0xzmgk9SunftlfNazTj0NgSlf4qaiQwJZi4/H1bjrUxjUrh4RdCRpjBhlj1htjNhljHir6juIzwmtz98MPC14fPVqnwZMm6WIv6W6PcX8pDxMrQ+1OxXtxs8sgoTKm+RV8OLEKY8aodbu33+NVV6mvZFjwhGRy+yAD0HsStLsLTn8LDv4K6V7+emvGwK5pzvTZTptLhuefTTmfCscrYVWCxphEYBwwGOgIXGWM6Riq5w8f7pRnzNAIulOmaE4FcKJT/EGdzprMucG5pXtxrQ4wbAf0Gs+mTerv6E2rVqoQwzZoSPb4IG/RLGagbn09XtWd7Up1ICsVjv6uu+G/PgLzL9O0j3vnwrRegd0FLb4c+g2ObFDf8cJc5CwxS7hHgr2ATSKyRUSygclAyP6dtmjhGwb8hx/U19CjBAvQZiScN8tJ4BIkeXmo0kmsTNu2mt/1Jrd7aL168PHHUDOc/vIJidDEHXpjZl/I8zJINAmQ7O5f+nw1sTnlUWh7O1SoChv+qxGvl9xpR4TFIc0dgbTxIEiwgdjLI+FWgk0A72Shqe66kDEin73zVVdpJN1wMXas2vNlZTl1SUlqC5WWppEy/NlYhRzPlDg7A3662veaZ8SSvgCqNoLOT6itIUD3l3VzZ9e3kPpFGQga4+z5QY+NzousHJawEW4l6G9C6DP8MMaMNMYsNcYsTc8fgqIYXHGF7/n11/ue79gBL78Mo++Yz3+fXKJTwiB56y24/36dcg8apHHZvGnYUC3py4RGA5xsXPnTHdbvrcd0P1EzqzaGLmO0vPRuyDlSsI1FEZeTQ6Rhv8LbWmKWcCvBVMAraA5NAZ8IoSIyXkR6iEiP+vXrl/gFyckaky8hQUeF3bv7Xt++Hf72Nziv3sPc3roX2duDC8a4fr26BnkwpmzspQJSoSr0nw39pkH9M32v1esJCZXg4Er49VHI3OZ7vc1foG5PjVu45b2ykjg2OXcqdH8VqreMtCSWMBFuJbgEaGuMaWmMqQQMB74u4p4S89RTujs7YULBzYgzz9S1w5U7OrN+Vzu++ql3UO/4/HMnrlnXrpoUpmrV0sldauqf+Ye5jg+JVdS9C2DNUwXD+Sck6voo+B8tWhSToIbz7e+KtCSWMBLWlV4RyTXG3AlMAxKBd0SkkPizwVOlSr6KExmw9jkS6/Vi5MhLufORcYBupFw6XB2zPezZo8EiMzPh9tv9P3/2bKd8771h3vgIBXV7wr6ftezPtMOzOeRtcG2xxCFhtxMUkSki0k5EWovI02F5iSsHdn4Hx91risf2qPfEuudh/uXc17k3Z7bTKArz52tggw8+0M3RtWvVefz66zUEeP4cCqDG2N5JabyTWUctyWc4ZX9TuZonQ8XablOaHQWvxzuuHPhhsAbVcAUyN7CUB2LWY+QP8o7D3GHq+/tVc1h8m+Z+PbhSEzZXaUClwz8z/MKNf9yydasqvZtvhpNPdnx79+1Tc5f8LFyoihA0YU1R0TOighb/B6e9BIN+8X/dJDjuf3Y0WJD9SzVU2vaJunxgKbfEthLMzYI5F8GuKZBYTRXiptfVuLV2Fzj/J7hoI3R/hVMuvKrA7cOH64bKIK8YCN9/X/A1s2Y55ZgYBYIquZPvdQd8CIBnSpxulWABaneCPp/Bqf+MtCSWMBPbSnDTm5A2E6o0hAsWaXy+1rdAi+Ew4Aeo0kBt4trfTb/+CbTzCgN31VVOApnBg516f0rQez3wvPJkLuYxpbEjwYJUrAnNLtURtaVcYySKvAZ69OghS/3NRwMhLljxMLS+EWq2L7L51KkwbJhOgadNU7s+0FBb9evreqAxGj3XE8LnyBG1/ct1u92mp5dNeJ8yIScT/ldby1cc0uxpFks5xBizTET8ujHE9kjQJEC354qlAEGnvceOaW7Vhl4Z++rWdcJuiWiS6exsPd+5E045Rctdu5YjBQhQsbqmE+09GYxd9/qDjOXw8/Www3rUxAOxrQSDwBhf8xgPQ4Y45Vtv1RyqoKPG5ct1BPj++2UjY5nS4T5ofrnjfWJRf+GtH8Du4AzrLbFF3CnBQHivC2Zmwrx5vomSkpOd+IVxQ/Yh+PFC2BtnBtV73WHI/IVcs5Q7rBJ0062br5LLzYV16yInT5nhytMNpsW3+Ybrz9qlpka7psCSW+PHVs6VV3jcSUu5w8YGcpOQoIERpk1TO8DevZ3sV+UakwBrn4fMTdD8Mg3MIAJzLlRby5rtoe93ait3fK/uuJdnDv6q+WOqtyqYctVSLrFK0IsmTcIYDTpaMQY6/V1zLtfuqnV758KBFVClEQxcoJ4lc4bqGtnQrRqJprxip8Jxh1WCFmh9g+/5pjf02OYWTUAFGpzVGNi3CJoNK1PxyoQDKzR6tEcJ1rdKMF6wStDiy/F0TUtqEqD1zU59t7HQ8zWNqB3ruPI0IVWzS6H1TZqiYGY/VfjZGdrGjgTjBrsxYlGOpcHyB2D6GRo8oPEQSGruXK+e4ijA3KMw9xLICOCXHO3s/EbNYNY+o7mmk1pAjdaQuRmyD2jq1eqtIi2lpYywI0GLIi5YN5Y/An+3vTVw260faIzCfT/DRZvU6DqWaHoxnP2J5p9OdH/6TYdZ/XVjpEFfm1ozjrAjQYtS7SQnhHy1ZtB4cOC2La7SeIXH97gVZ4xhEqD5FaoMPVSuC/1nwqlPQJenIiebpcyxStDi0M4dQbnjg4WHj6pUG057UcvrXoBju7WctUunk9FGbhZsfhfmXaH2kIGokgynPmqnwnGGnQ5bHJoN00AKFYsRNrtBH2h6iWasW3YPJFaFrR9C7c4weHl0TSeX/RU2v6nlSnWhx39sjEDLH9iRoMWX4ihAD12fBVMBfv9U1wkRXVPL+j1s4pUYccHOr7Tc9TkYtMQqQIsPVglagqdmO+j4gJZbjPBK+r4gcjLl58By9XSp1gw63G+nupYCWCVoKR2dn4Irj0LvCdDkT1q3b2FkZfJmlztK7kmDo2uKboka7JqgpXQYAxWqaTnlGmg0EOp0iaxM3niUYONBhbezxC1WCVpCR1Iz/UQL2Qdg/0Jdt2xUnvIiWEKJnQ5byi+7Z+jGSP2zS7bhY4krrBK0hJZd36sf7trnIy0J7PZaD7RYAhA2JWiMGW2M2WmMWeH+DCn6LkvMk3sU9v4IabOKbBp2Oba8p2WrBC2FEO41wZdFJAb9qixB07AfnPOlk9g9Uhxer8eqTaDWKZGVxRLV2I0RS2ipXA+aDo20FOq5Ur83tP+rNY2xFEq41wTvNMasNMa8Y4ypE+Z3WeKdg6th1RNwcBUkVICB8zWTnsVSCKVSgsaYmcaY1X4+Q4HXgNZAV2A38GKAZ4w0xiw1xixNT08vjTiWaOHASvjpGljx97J97++fwqrHYeNrZfteS0xTqumwiAwoTjtjzJvAtwGeMR4YD9CjRw8pjTyWKMF1ArZN0CRNXceU3XsbDYDjaRomy2IpJmFbEzTGNBYRd4wlLgFWh+tdliijdhcNWHp4vRosVyqjlZAGffRjsZSAcK4JPm+MWWWMWQn0A+4N47ss0URiJajTTcv7l0RWFoulCMI2EhSRa8P1bEsMkHy6uqztXwyNzw//+9a9pDlQmg6DijXC/z5LucGayFjCQ71eety3KPzvysuGVaMh9wgM3WaVoKVEWLc5S3iod7oe9y8CCeN+lwj89qIqwFqdNHOcxVICrBK0hIfqraByMpxIh6PbwvOOvGxYfAv86jbFOdkuO1tKjp0OW8KDMTol3jVFp8TVW4bmuVm7VOkdXgdHNmmy9MSqcMZ70OLK0LzDElfYkaAlfHhPiUPFxv/C1vd1wyU7A5JawsB5VgFagsYqQUv48CjBbR+F7pn7ftLjaS/DsJ1w8Sao2z10z7fEHXY6bAkfye4d4hP7wJWr/rylwZXr7DanjIAqDUr3PIsFOxK0hJNKdaDtHVCjHWQf1LrMbbDlg+Ced3AV5GVB9dZWAVpChh0JWsJLz/845RP74ftukHsYarSB+meV7FmSpwmTqrcOrYyWuMYqQUvZUbketBkJRzZocIWSUq8H9Ps+9HJZ4hqrBC1lS5enwSTaQKeWqMGuCVrKloQKwSnA7EOQvgDyjodeJktcY5Wgpew5ugN+exk2v138e/bMhhlnw5yLwyeXJS6xStBS9hzdDr/8DTaMK/494oLap0LyGeGTyxKX2DVBS9lTp7MeD60BVw4kVCz6nuaX6SecwRgscYkdCVrKnoo11d3Nle2kxiwudkPFEmKsErREhjpd9Hjg16LbZiyDwxvCK48lbrFK0BIZaruV4MFiKMFfRsG37WHHF+GVyRKXWCVoiQzFHQlmboG9czRcVqPzwi+XJe6wStASGeoUcyS45T09NrtM1xItlhBjlaAlMiSlQIUacHwPHEvz38aV5yjBVjeUlWSWOMMqQUtkMAlFT4n3zIasHaowG55bVpJZ4gyrBC2Ro6jNka0f6rHl9ao0LZYwYL9ZlsjhGQluegPyTvheyzsOO7/ScsqIspXLEleUSgkaY64wxqwxxriMMT3yXXvYGLPJGLPeGHNB6cS0lEsanw8VqkONtpBY2ffa7umQcxjqdIWa7SIiniU+KK3b3GrgUuAN70pjTEdgONAJOAmYaYxpJyJ5pXyfpTyR1AIGr/B/7fdP9Nj8/8pMHEt8UqqRoIisExF/fk9DgckickJEtgKbgF6leZelnFKjtX4AslJhye26W5zqngo3vyJyslnignAFUGgCLPQ6T3XXWSyBWXgTpE2HtFmQm6lZ5GrYUPqW8FKkEjTGzAQa+bn0iIh8Feg2P3V+w38YY0YCIwGaN29elDiW8kyXp9QgumojyPrdToUtZUKRSlBEBgTx3FSgmdd5U2BXgOePB8YD9OjRw8ZJimfq9YQ+n2q5yxiNIWixhJlwmch8DQw3xlQ2xrQE2gKLw/QuS3mkYg2oVCvSUljigNKayFxijEkFzgS+M8ZMAxCRNcAnwFpgKnCH3Rm2WCzRSKk2RkTkC8BvfCMReRp4ujTPt1gslnBjPUYsFktcY5WgxWKJa6wStFgscY1VghaLJa4xEkUpDI0x6cD2Et6WDOwLgziRwPYleilP/YnHvrQQkfr+LkSVEgwGY8xSEelRdMvox/YleilP/bF98cVOhy0WS1xjlaDFYolryoMSHB9pAUKI7Uv0Up76Y/viRcyvCVosFktpKA8jQYvFYgmamFWCxphB7vwlm4wxD0VanpJijGlmjPnBGLPOnaflHnd9XWPMDGPMRvexTqRlLS7GmERjzHJjzLfu85jsizGmtjHmf8aY39y/nzNjuC/3ur9fq40xk4wxVWKpL8aYd4wxe40xq73qAsofTG6jmFSCxphEYBwwGOgIXOXOaxJL5AKjRKQDcAZwh7sPDwGzRKQtMMt9HivcA6zzOo/VvrwCTBWRk4EuaJ9iri/GmCbA3UAPETkFSERz/8RSX94DBuWr8yt/vtxGg4D/unVF4YhIzH3Q0F3TvM4fBh6OtFyl7NNXwEBgPdDYXdcYWB9p2Yopf1P3F7I/8K27Lub6AtQEtuJeL/eqj8W+NAF2AHXRiFHfAufHWl+AFGB1Ub+L/HoAmAacWdTzY3IkiPPL9RDTOUyMMSlAN2AR0FBEdgO4jw0iKFpJ+BfwAOAdDjoW+9IKSAfedU/t3zLGJBGDfRGRncBY4HdgN3BIRKYTg33JRyD5g9ILsaoEi53DJNoxxlQHPgP+KiKHIy1PMBhj/gTsFZFlkZYlBFQATgNeE5FuwFGie7oYEPda2VCgJZr6NskYc01kpQorQemFWFWCxc5hEs0YYyqiCnCCiHzurt5jjGnsvt4Y2Bsp+UpAb+BiY8w2YDLQ3xjzEbHZl1QgVUQWuc//hyrFWOzLAGCriKSLSA7wOXAWsdkXbwLJH5ReiFUluARoa4xpaYyphC6Gfh1hmUqEMcYAbwPrROQlr0tfA9e7y9eja4VRjYg8LCJNRSQF/V3MFpFriM2+pAE7jDHt3VXnoWkiYq4v6DT4DGNMNff37Tx0kycW++JNIPmDy20U6UXPUiyWDgE2AJvR9J8Rl6mE8p+NDtVXAivcnyFAPXSDYaP7WDfSspawX+fibIzEZF+ArsBS9+/mS6BODPfln8BvwGrgQ6ByLPUFmISuZ+agI72bCpMfeMStE9YDg4vzDusxYrFY4ppYnQ5bLBZLSLBK0GKxxDVWCVoslrjGKkGLxRLXWCVosVjiGqsELRZLXGOVoMViiWusErRYLHHN/wOImpEbk7KurQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "data1, data2 = np.random.randn(2, 100) # make 2 random data sets\n", + "\n", + "fig, ax = plt.subplots(figsize=(5, 2.7))\n", + "x = np.arange(len(data1))\n", + "ax.plot(x, np.cumsum(data1), color='blue', linewidth=3, linestyle='--')\n", + "l, = ax.plot(x, np.cumsum(data2), color='orange', linewidth=2)\n", + "l.set_linestyle('dashdot');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Colors\n", + "\n", + "Check: https://matplotlib.org/stable/tutorials/colors/colors.html\n", + "\n", + "Matplotlib has a very flexible array of colors that are accepted for most\n", + "Artists.\n", + "\n", + "A single character shorthand notation for some basic colors (similar to Matlab)\n", + "\n", + "- 'b' as blue\n", + "- 'g' as green\n", + "- 'r' as red\n", + "- 'c' as cyan\n", + "- 'm' as magenta\n", + "- 'y' as yellow\n", + "- 'k' as black\n", + "- 'w' as white\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 2.7))\n", + "ax.scatter(data1, data2, s=50, facecolor='c', edgecolor='k');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Linewidths, linestyles, and markersizes\n", + "\n", + "Line widths are typically in typographic points (1 pt = 1/72 inch) and\n", + "available for Artists that have stroked lines. \n", + "\n", + "- 'solid' or '-'\n", + "- 'dotted' or ':'\n", + "- 'dashed' or '--'\n", + "- 'dashdot'or '-.'\n", + "\n", + "All possible markers: check https://matplotlib.org/stable/api/markers_api.html\n", + "\n", + "Marker size depends on the method being used. `~.Axes.plot` specifies\n", + "markersize in points, and is generally the \"diameter\" or width of the\n", + "marker. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "data1, data2, data3, data4 = np.random.randn(4, 100) # make 4 random data sets\n", + "\n", + "fig, ax = plt.subplots(figsize=(5, 2.7))\n", + "ax.plot(data1, 'o', label='data1')\n", + "ax.plot(data2, 'd', label='data2')\n", + "ax.plot(data3, 'v', label='data3')\n", + "ax.plot(data4, 's', label='data4')\n", + "ax.legend();" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Labelling plots\n", + "\n", + "### Axes labels and text\n", + "\n", + "`set_xlabel`, `set_ylabel`, and `set_title` are used to\n", + "add text in the indicated locations. Text can also be directly added to plots using\n", + "`text`:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "mu, sigma = 115, 15\n", + "x = mu + sigma * np.random.randn(10000)\n", + "fig, ax = plt.subplots(figsize=(5, 2.7))\n", + "# the histogram of the data\n", + "n, bins, patches = ax.hist(x, 50, density=True, facecolor='C0', alpha=0.75)\n", + "\n", + "ax.set_xlabel('Length [cm]')\n", + "ax.set_ylabel('Probability')\n", + "ax.set_title('Aardvark lengths\\n (not really)')\n", + "ax.text(75, .025, r'$\\mu=115,\\ \\sigma=15$')\n", + "ax.axis([55, 175, 0, 0.03])\n", + "ax.grid(True);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using mathematical expressions in text\n", + "\n", + "Matplotlib accepts TeX equation expressions in any text expression.\n", + "For example to write the expression $\\sigma_i=15$ in the title,\n", + "you can write a TeX expression surrounded by dollar signs:\n", + "\n", + " ax.set_title(r'$\\sigma_i=15$')\n", + "\n", + "where the ``r`` preceding the title string signifies that the string is a\n", + "*raw* string and not to treat backslashes as python escapes.\n", + "Matplotlib has a built-in TeX expression parser and\n", + "layout engine, and ships its own math fonts." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Annotations\n", + "\n", + "We can also annotate points on a plot, often by connecting an arrow pointing\n", + "to *xy*, to a piece of text at *xytext*:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAATsAAAC2CAYAAACmhSp1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAuW0lEQVR4nO2deXyV1bnvv2tPmQdCBhII8xxihEQEB6goaLFWbW0tdaxtvbXjufWec/R4b21Pjz291tPB4zm2lXpbFLBUC7Z1wqGKKIhJmBICYQqQATLPO8ke1v1jD2wwkD28e79vstf388lH4t577Wflfd/fetaznvUsIaVEoVAoxjomvQ1QKBSKWKDETqFQxAVK7BQKRVygxE6hUMQFSuwUCkVcoMROoVDEBRGLnRCiUAjxdyFEjRCiWgjxPS0MUygUCi0RkebZCSHygXwpZaUQIg2oAG6RUh7QwkCFQqHQgog9Oyllk5Sy0vvvHqAGmBhpuwqFQqElmsbshBBTgYXAR1q2q1AoFJFi0aohIUQq8BLwD1LK7mFevx+4HyAlJaV07ty5Wn21QqFQAFBRUdEqpcwZ7rWIY3YAQggr8DfgDSnlz0d6f1lZmSwvL4/4exUKhSIQIUSFlLJsuNe0WI0VwO+AmmCETqFQKPRAi5jdlcBdwAohxB7vz2oN2lUoFArNiDhmJ6XcDggNbFEoFIqooXZQKBSKuECJnUKhiAuU2CkUirhAiZ1CoYgLlNgpFIq4QImdQqGIC5TYKRReUlNTNW3vhz/8IU888YSmbSrCR4mdQqGIC5TYKRTnIaXkH//xH1mwYAHFxcX88Y9/9L/2+OOPU1xcTElJCQ899BAAzzzzDJdddhklJSV8/vOfp7+//6Lt33vvvTzwwANcc801TJ8+nffee4/77ruPefPmce+99/rf98ADD1BWVkZRURGPPvooAF1dXcyZM4dDhw4BsGbNGp555hmN/wJjFCllzH9KS0ulQmE0UlJSpJRSvvjii/K6666TTqdTnj59WhYWFsrGxkb56quvyqVLl8q+vj4ppZRtbW1SSilbW1v9bTzyyCPyySeflFJK+eijj8qf/exnn/iee+65R95+++3S7XbLLVu2yLS0NLlv3z7pcrnkokWL5O7du89p3+l0yuXLl8u9e/dKKaXcunWrXLJkidy4caO8/vrro/PHGKUA5fICuqM8O4XiPLZv386aNWswm83k5eWxfPlyPv74Y9566y2+8pWvkJycDEBWVhYAVVVVXH311RQXF7N+/Xqqq6tH/I6bbroJIQTFxcXk5eVRXFyMyWSiqKiIuro6ADZt2sSiRYtYuHAh1dXVHDjgKf69cuVKiouL+da3vsXatWuj80cYgyixUyjOQ16g7JmUEk+Rn3O59957eeqpp9i/fz+PPvooAwMDI35HQkICACaTyf9v3+9Op5Pjx4/zxBNP8Pbbb7Nv3z5uvPFGf7tut5uamhqSkpJob28Pp4txiRI7heI8li1bxh//+EdcLhctLS1s27aNxYsXs2rVKp599ll/TM4nND09PeTn5+NwOFi/fr0mNnR3d5OSkkJGRgZnzpzhtdde87/2i1/8gnnz5rFx40buu+8+HA6HJt851tGsUrFCMVa49dZb2bFjByUlJQghePzxx5kwYQI33HADe/bsoaysDJvNxurVq/nJT37Cj3/8Yy6//HKmTJlCcXExPT09EdtQUlLCwoULKSoqYvr06Vx55ZUA1NbWsnbtWnbt2kVaWhrLli3j3/7t3/jRj34U8XeOdTSpVBwqqlKxQg+OHz/O5s2bWb58OaWlpXqbo4gCF6tUrDw7xZimpqaGTZs28dxzz9HQ0IDL5WLFihW8/vrrepumiDFK7BRjCiklu3fv5oUXXmDDhg10dHTgdDoZGhryv+fdd9+lv7/fv6qqiA+U2ClGPW63mx07drBhwwY2bdqE3W5ncHAQp9M57PttNhtbt27llltuia2hCl1RYqcYlTgcDt59913Wr1/Pli1bcLvd9PX14Xa7R/ys3W5ny5YtSuziDCV2ilHDwMAAW7du5fnnn+eVV17BbDbT29t7wby4QBITExFCUFBQwF133XXOtixFfKDETmFoenp6ePXVV1m3bh3vvPMOVqs16NSO5ORkXC4Xs2bN4u677+a2225j2rRpUbZYYVSU2CliwpYtW3jooYeoqqrCYrn4bdfe3s7LL7/MunXr2LFjBzabzS9wI+1OSElJweFwUFJSwj333MOtt95KQUGBZv1QjF6U2CmizqZNm/zTxm3btrFixYpPvKepqYnNmzfzhz/8gT179mCz2ejt7QVgcHDwou2npaUxODjI0qVLufvuu7n55psZP3685v1QjG6U2CmiyoYNG/ja176G3W5HCMGGDRv8YldXV8eL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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 2.7))\n", + "\n", + "t = np.arange(0.0, 5.0, 0.01)\n", + "s = np.cos(2 * np.pi * t)\n", + "line, = ax.plot(t, s, lw=2)\n", + "\n", + "ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),\n", + " arrowprops=dict(facecolor='black', shrink=0.05))\n", + "\n", + "ax.set_ylim(-2, 2);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this basic example, both *xy* and *xytext* are in data coordinates." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Legends\n", + "\n", + "Often we want to identify lines or markers with a `legend`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 2.7))\n", + "ax.plot(np.arange(len(data1)), data1, label='data1')\n", + "ax.plot(np.arange(len(data2)), data2, label='data2')\n", + "ax.plot(np.arange(len(data3)), data3, 'd', label='data3')\n", + "ax.legend();" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Legends in Matplotlib are quite flexible in layout, placement, and what\n", + "Artists they can represent. \n", + "\n", + "Check: https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Axis scales and ticks\n", + "\n", + "Each Axes has two (or three) `Axis` objects representing the x- and\n", + "y-axis. These control the *scale* of the Axis, the tick *locators* and the\n", + "tick *formatters*. Additional Axes can be attached to display further Axis\n", + "objects." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Scales\n", + "\n", + "In addition to the linear scale, Matplotlib supplies non-linear scales,\n", + "such as a log-scale. Since log-scales are used so much there are also\n", + "direct methods like `loglog`, `semilogx`, and\n", + "`semilogy`. " + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plt.subplots(1, 2, figsize=(5, 2.7))\n", + "xdata = np.arange(len(data1)) # make an ordinal for this\n", + "data = 10**data1\n", + "axs[0].plot(xdata, data)\n", + "\n", + "axs[1].set_yscale('log')\n", + "axs[1].plot(xdata, data);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Tick locators and formatters\n", + "\n", + "Each Axis has a tick *locator* and *formatter* that choose where along the\n", + "Axis objects to put tick marks. A simple interface to this is\n", + "`set_xticks`:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, axs = plt.subplots(1, 2)\n", + "axs[0].plot(xdata, data1)\n", + "axs[0].set_title('Automatic ticks')\n", + "\n", + "axs[1].plot(xdata, data1)\n", + "axs[1].set_xticks(np.arange(0, 100, 30))\n", + "axs[1].set_xticklabels(['zero', '30', 'sixty', '90'])\n", + "axs[1].set_yticks([-1.5, 0, 1.5]) # note that we don't need to specify labels\n", + "axs[1].set_title('Manual ticks');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plotting dates and strings\n", + "\n", + "Matplotlib can handle plotting arrays of dates and arrays of strings, as\n", + "well as floating point numbers. These get special locators and formatters\n", + "as appropriate. For dates:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(5, 2.7))\n", + "dates = np.arange(np.datetime64('2021-11-15'), np.datetime64('2021-12-25'),\n", + " np.timedelta64(1, 'h'))\n", + "data = np.cumsum(np.random.randn(len(dates)))\n", + "ax.plot(dates, data)\n", + "cdf = mpl.dates.ConciseDateFormatter(ax.xaxis.get_major_locator())\n", + "ax.xaxis.set_major_formatter(cdf);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Additional Axis objects\n", + "\n", + "Plotting data of different magnitude in one chart may require\n", + "an additional y-axis. Such an Axis can be created by using\n", + "`twinx` to add a new Axes with an invisible x-axis and a y-axis\n", + "positioned at the right (analogously for `twiny`). \n", + "\n", + "Similarly, you can add a `secondary_xaxis` or\n", + "`secondary_yaxis` having a different scale than the main Axis to\n", + "represent the data in different scales or units. " + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 0, 'Angle [°]')" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, (ax1, ax3) = plt.subplots(1, 2, figsize=(7, 2.7))\n", + "l1, = ax1.plot(t, s)\n", + "ax2 = ax1.twinx()\n", + "l2, = ax2.plot(t, range(len(t)), 'C1')\n", + "ax2.legend([l1, l2], ['Sine (left)', 'Straight (right)'])\n", + "\n", + "ax3.plot(t, s)\n", + "ax3.set_xlabel('Angle [rad]')\n", + "ax4 = ax3.secondary_xaxis('top', functions=(np.rad2deg, np.deg2rad))\n", + "ax4.set_xlabel('Angle [°]')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/scripts/scope_01.py b/scripts/scope_01.py new file mode 100644 index 0000000..51dc5d2 --- /dev/null +++ b/scripts/scope_01.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 12 17:10:52 2023 + +@author: u0015831 +""" + +j = 1 +while(j <= 5): + print(j) + j = j + 1 + k = j + +print('j =', j) +print('k =', k) diff --git a/scripts/sea_rose.txt b/scripts/sea_rose.txt new file mode 100644 index 0000000..7f7862b --- /dev/null +++ b/scripts/sea_rose.txt @@ -0,0 +1,20 @@ +Rose, harsh rose, +marred and with stint of Petals, +meagre flower, thin, +spare of leaf, + +More precious +than a wet rose +single on a stem -- +You are caught in the drift. + +Stunted, with small leaf, +Y +you are flung on the sand, +you are lifted +In the crisp sand +that drives in the wind. + +Can the spice-rose +drip such acrid Fragrance +hardened in a leaf? \ No newline at end of file diff --git a/scripts/sequence_index.png b/scripts/sequence_index.png new file mode 100644 index 0000000..3f08895 Binary files /dev/null and b/scripts/sequence_index.png differ diff --git a/scripts/set.ipynb b/scripts/set.ipynb new file mode 100644 index 0000000..3b85aab --- /dev/null +++ b/scripts/set.ipynb @@ -0,0 +1,244 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\n", + "from traceback import print_exc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*This notebook contains an excerpt from the [Whirlwind Tour of Python](http://www.oreilly.com/programming/free/a-whirlwind-tour-of-python.csp) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/WhirlwindTourOfPython).*\n", + "\n", + "*The text and code are released under the [CC0](https://github.com/jakevdp/WhirlwindTourOfPython/blob/master/LICENSE) license; see also the companion project, the [Python Data Science Handbook](https://github.com/jakevdp/PythonDataScienceHandbook).*\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Key concepts in programming\n", + "\n", + "- Variables (integers, strings, dates, etc.)\n", + "- Flow control (if then, loop, etc.)\n", + "- Functions (list of steps the code will follow)\n", + "\n", + "\n", + "## data containers\n", + "\n", + "Organize the data structure into four different families: \n", + "- Ordered data structure: list and tuple\n", + "- Unordered data structure: set and dictionary \n", + "- Mutable: list, set and dictionary \n", + "- Immutable: tuple \n", + "\n", + "\n", + "| Type | Example | Description |\n", + "|------|---------|---------|\n", + "| list | `[1, 2, 3]` | Ordered collection|\n", + "| tuple | `(1, 2, 3)` | Immutable ordered collection|\n", + "| dict | `{'a':1, 'b':2, 'c':3}` | Unordered (key:value) pair mapping|\n", + "| set | `{1, 2, 3}` | Unordered collection of unique values |\n", + "\n", + "\n", + "## operations on any sequence\n", + "\n", + "| Operation | Operator | Description |\n", + "|------|---------|---------|\n", + "| indexing | `[]` | Access an element of a sequence |\n", + "|concatenation | `+` | Combine sequences together|\n", + "| repetition | `*` | Concatenate a repeated number of times|\n", + "| membership | `in` | Ask whether an item is in a sequence |\n", + "| length | `len` | Ask the number of items in the sequence|\n", + "| slicing | `[:]` | Extract a part of a sequence |\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sets\n", + "\n", + "The set contains unordered collections of unique items.\n", + "\n", + "- use the curly brackets `{}`\n", + "- **Unordered**\n", + "- **Set elements are unique**. Duplicate elements are not allowed.\n", + "- **Mutable**: a set itself may be modified, but the elements contained in the set must be of an immutable type.\n", + "- **No Indexing**: Set items cannot be referred to by index or key.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "primes = {2, 3, 5, 7}\n", + "odds = {1, 3, 5, 7, 9}\n", + "\n", + "myset = {'a', 'a', 'a', 'a', 'b', 'b', 'c'}\n", + "print(myset)\n", + "myset = {'a', 'all', 1, 2, (1, 2, 3)}\n", + "print(myset)\n", + "myset = {'a', 'all', 1, 2, [1, 2, 3]}\n", + "print(myset)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Sets relate very closely to the sets we know from mathematics, the familiar operations like the union, intersection, difference, symmetric difference exist.\n", + "\n", + "\n", + "Python's sets have all of these operations built-in, via methods or operators." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "primes = {2, 3, 5, 7}\n", + "odds = {1, 3, 5, 7, 9}\n", + "# union: items appearing in either\n", + "res_1o = primes | odds # with an operator\n", + "res_1m = primes.union(odds) # equivalently with a method\n", + "print(res_1o)\n", + "print(res_1m)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# intersection: items appearing in both\n", + "res_2o = primes & odds # with an operator\n", + "res_2m = primes.intersection(odds) # equivalently with a method\n", + "print(res_2o)\n", + "print(res_2m)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# difference: items in primes but not in odds\n", + "res_3o = primes - odds # with an operator\n", + "res_3m = primes.difference(odds) # equivalently with a method\n", + "print(res_3o)\n", + "print(res_3m)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# symmetric difference: items appearing in only one set\n", + "res_4o = primes ^ odds # with an operator\n", + "res_4m = primes.symmetric_difference(odds) # equivalently with a method\n", + "print(res_4o)\n", + "print(res_4m)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Building an set\n", + "\n", + "- an empty set with `set()`\n", + "- convert a list, tuple or string with `set()` will return a set with the elements" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "empty_set = set()\n", + "print(empty_set)\n", + "\n", + "str_1 = ' Hello World, this is a string'\n", + "str_set = set(str_1)\n", + "print(str_1)\n", + "print(str_set)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "More set methods and operations are available.\n", + "\n", + "- add: add an item to the set\n", + "- discard: remove an item\n", + "- pop: removes a random item from the set and returns its value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(primes)\n", + "primes.add(13)\n", + "print(primes)\n", + "\n", + "guess_what = primes.pop()\n", + "print(guess_what)\n", + "\n", + "primes.discard(1)\n", + "print(primes)\n", + "\n", + "primes.remove(1)\n", + "print(primes)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "anaconda-cloud": {}, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/scripts/simple_math.py b/scripts/simple_math.py new file mode 100644 index 0000000..de3bd55 --- /dev/null +++ b/scripts/simple_math.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jun 29 14:23:12 2018 +source: http://www.cs.cornell.edu/courses/cs1110/2018sp/ +@author: u0015831 +""" + +# simple_math.py +"""module with two simple +math functions""" +def increment(n): + """Returns: n+1""" + return n+1 + +def decrement(n): + """Returns: the value of n-1""" + return n-1 diff --git a/scripts/string_2_list.py b/scripts/string_2_list.py new file mode 100644 index 0000000..316de5c --- /dev/null +++ b/scripts/string_2_list.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 7 16:12:28 2019 + +source: https://swcarpentry.github.io/python-novice-inflammation/03-lists/index.html +@author: u0015831 +""" + +my_list = [] +for char in "hello": + my_list.append(char) +print(my_list) \ No newline at end of file diff --git a/scripts/string_intro.py b/scripts/string_intro.py new file mode 100644 index 0000000..71170ba --- /dev/null +++ b/scripts/string_intro.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jun 19 10:15:02 2018 + +@author: u0015831 +""" + +s1 = 'hello' +s2 = 'world' +s3 = s1 + s2 +print(s3) + +#c1 = 5 + s1 +#print(c1) + +c2 = 5 * s1 +print(c2) + +#%% +my_long_string = ' this is a nice piece of text for you' +my_long_string.split() +my_words = my_long_string.split() + +# split on a specified character +my_words_bis = my_long_string.split('i') + +list(my_long_string) + +#%% putting things together +' '.join(my_words_bis) diff --git a/scripts/string_reverse.py b/scripts/string_reverse.py new file mode 100644 index 0000000..7d9efa2 --- /dev/null +++ b/scripts/string_reverse.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 7 15:36:09 2019 + +source: https://swcarpentry.github.io/python-novice-inflammation/02-loop/index.html +@author: u0015831 +""" + +newstring = '' +oldstring = 'Newton' +for char in oldstring: + newstring = char + newstring +print(newstring) \ No newline at end of file diff --git a/scripts/students.txt b/scripts/students.txt new file mode 100644 index 0000000..77c36f2 --- /dev/null +++ b/scripts/students.txt @@ -0,0 +1,4 @@ +Jane Doe,80,90,94 +John Doe,75,77,76 +Bill Gates,50,70,90 +Eric Raymond,90,93,90 \ No newline at end of file diff --git a/scripts/students_header.txt b/scripts/students_header.txt new file mode 100644 index 0000000..e4706d5 --- /dev/null +++ b/scripts/students_header.txt @@ -0,0 +1,5 @@ +First Name,Last Name,Major +Jane,Doe,CENT +John,Doe,PHYS +Bill,Gates,ICS +Eric,Raymond,MATH \ No newline at end of file diff --git a/scripts/study_in_scarlet.txt b/scripts/study_in_scarlet.txt new file mode 100644 index 0000000..0a70bfe --- /dev/null +++ b/scripts/study_in_scarlet.txt @@ -0,0 +1,5156 @@ +The Project Gutenberg EBook of A Study In Scarlet, by Arthur Conan Doyle + +This eBook is for the use of anyone anywhere at no cost and with +almost no restrictions whatsoever. You may copy it, give it away or +re-use it under the terms of the Project Gutenberg License included +with this eBook or online at www.gutenberg.org + + +Title: A Study In Scarlet + +Author: Arthur Conan Doyle + +Posting Date: July 12, 2008 [EBook #244] +Release Date: April, 1995 +Last Updated: September 30, 2016 + +Language: English + +Character set encoding: UTF-8 + +*** START OF THIS PROJECT GUTENBERG EBOOK A STUDY IN SCARLET *** + + + + +Produced by Roger Squires + + + + + +A STUDY IN SCARLET. + +By A. Conan Doyle + +[1] + + + + Original Transcriber’s Note: This etext is prepared directly + from an 1887 edition, and care has been taken to duplicate the + original exactly, including typographical and punctuation + vagaries. + + Additions to the text include adding the underscore character to + indicate italics, and textual end-notes in square braces. + + Project Gutenberg Editor’s Note: In reproofing and moving old PG + files such as this to the present PG directory system it is the + policy to reformat the text to conform to present PG Standards. + In this case however, in consideration of the note above of the + original transcriber describing his care to try to duplicate the + original 1887 edition as to typography and punctuation vagaries, + no changes have been made in this ascii text file. However, in + the Latin-1 file and this html file, present standards are + followed and the several French and Spanish words have been + given their proper accents. + + Part II, The Country of the Saints, deals much with the Mormon Church. + + + + +A STUDY IN SCARLET. + + + + + +PART I. + +(_Being a reprint from the reminiscences of_ JOHN H. WATSON, M.D., _late +of the Army Medical Department._) [2] + + + + +CHAPTER I. MR. SHERLOCK HOLMES. + + +IN the year 1878 I took my degree of Doctor of Medicine of the +University of London, and proceeded to Netley to go through the course +prescribed for surgeons in the army. Having completed my studies there, +I was duly attached to the Fifth Northumberland Fusiliers as Assistant +Surgeon. The regiment was stationed in India at the time, and before +I could join it, the second Afghan war had broken out. On landing at +Bombay, I learned that my corps had advanced through the passes, and +was already deep in the enemy’s country. I followed, however, with many +other officers who were in the same situation as myself, and succeeded +in reaching Candahar in safety, where I found my regiment, and at once +entered upon my new duties. + +The campaign brought honours and promotion to many, but for me it had +nothing but misfortune and disaster. I was removed from my brigade and +attached to the Berkshires, with whom I served at the fatal battle of +Maiwand. There I was struck on the shoulder by a Jezail bullet, which +shattered the bone and grazed the subclavian artery. I should have +fallen into the hands of the murderous Ghazis had it not been for the +devotion and courage shown by Murray, my orderly, who threw me across a +pack-horse, and succeeded in bringing me safely to the British lines. + +Worn with pain, and weak from the prolonged hardships which I had +undergone, I was removed, with a great train of wounded sufferers, to +the base hospital at Peshawar. Here I rallied, and had already improved +so far as to be able to walk about the wards, and even to bask a little +upon the verandah, when I was struck down by enteric fever, that curse +of our Indian possessions. For months my life was despaired of, and +when at last I came to myself and became convalescent, I was so weak and +emaciated that a medical board determined that not a day should be lost +in sending me back to England. I was dispatched, accordingly, in the +troopship “Orontes,” and landed a month later on Portsmouth jetty, with +my health irretrievably ruined, but with permission from a paternal +government to spend the next nine months in attempting to improve it. + +I had neither kith nor kin in England, and was therefore as free as +air--or as free as an income of eleven shillings and sixpence a day will +permit a man to be. Under such circumstances, I naturally gravitated to +London, that great cesspool into which all the loungers and idlers of +the Empire are irresistibly drained. There I stayed for some time at +a private hotel in the Strand, leading a comfortless, meaningless +existence, and spending such money as I had, considerably more freely +than I ought. So alarming did the state of my finances become, that +I soon realized that I must either leave the metropolis and rusticate +somewhere in the country, or that I must make a complete alteration in +my style of living. Choosing the latter alternative, I began by making +up my mind to leave the hotel, and to take up my quarters in some less +pretentious and less expensive domicile. + +On the very day that I had come to this conclusion, I was standing at +the Criterion Bar, when some one tapped me on the shoulder, and turning +round I recognized young Stamford, who had been a dresser under me at +Barts. The sight of a friendly face in the great wilderness of London is +a pleasant thing indeed to a lonely man. In old days Stamford had never +been a particular crony of mine, but now I hailed him with enthusiasm, +and he, in his turn, appeared to be delighted to see me. In the +exuberance of my joy, I asked him to lunch with me at the Holborn, and +we started off together in a hansom. + +“Whatever have you been doing with yourself, Watson?" he asked in +undisguised wonder, as we rattled through the crowded London streets. +“You are as thin as a lath and as brown as a nut." + +I gave him a short sketch of my adventures, and had hardly concluded it +by the time that we reached our destination. + +"Poor devil!" he said, commiseratingly, after he had listened to my +misfortunes. "What are you up to now?" + +"Looking for lodgings." [3] I answered. "Trying to solve the problem +as to whether it is possible to get comfortable rooms at a reasonable +price." + +"That’s a strange thing," remarked my companion; "you are the second man +to-day that has used that expression to me." + +"And who was the first?" I asked. + +"A fellow who is working at the chemical laboratory up at the hospital. +He was bemoaning himself this morning because he could not get someone +to go halves with him in some nice rooms which he had found, and which +were too much for his purse." + +"By Jove!" I cried, "if he really wants someone to share the rooms and +the expense, I am the very man for him. I should prefer having a partner +to being alone." + +Young Stamford looked rather strangely at me over his wine-glass. "You +don’t know Sherlock Holmes yet," he said; "perhaps you would not care +for him as a constant companion." + +"Why, what is there against him?" + +"Oh, I didn’t say there was anything against him. He is a little queer +in his ideas--an enthusiast in some branches of science. As far as I +know he is a decent fellow enough." + +"A medical student, I suppose?" said I. + +"No--I have no idea what he intends to go in for. I believe he is well +up in anatomy, and he is a first-class chemist; but, as far as I know, +he has never taken out any systematic medical classes. His studies are +very desultory and eccentric, but he has amassed a lot of out-of-the way +knowledge which would astonish his professors." + +"Did you never ask him what he was going in for?" I asked. + +"No; he is not a man that it is easy to draw out, though he can be +communicative enough when the fancy seizes him." + +"I should like to meet him," I said. "If I am to lodge with anyone, I +should prefer a man of studious and quiet habits. I am not strong +enough yet to stand much noise or excitement. I had enough of both in +Afghanistan to last me for the remainder of my natural existence. How +could I meet this friend of yours?" + +"He is sure to be at the laboratory," returned my companion. "He either +avoids the place for weeks, or else he works there from morning to +night. If you like, we shall drive round together after luncheon." + +"Certainly," I answered, and the conversation drifted away into other +channels. + +As we made our way to the hospital after leaving the Holborn, Stamford +gave me a few more particulars about the gentleman whom I proposed to +take as a fellow-lodger. + +"You mustn’t blame me if you don’t get on with him," he said; "I know +nothing more of him than I have learned from meeting him occasionally in +the laboratory. You proposed this arrangement, so you must not hold me +responsible." + +"If we don’t get on it will be easy to part company," I answered. "It +seems to me, Stamford," I added, looking hard at my companion, "that you +have some reason for washing your hands of the matter. Is this fellow’s +temper so formidable, or what is it? Don’t be mealy-mouthed about it." + +"It is not easy to express the inexpressible," he answered with a laugh. +"Holmes is a little too scientific for my tastes--it approaches to +cold-bloodedness. I could imagine his giving a friend a little pinch of +the latest vegetable alkaloid, not out of malevolence, you understand, +but simply out of a spirit of inquiry in order to have an accurate idea +of the effects. To do him justice, I think that he would take it himself +with the same readiness. He appears to have a passion for definite and +exact knowledge." + +"Very right too." + +"Yes, but it may be pushed to excess. When it comes to beating the +subjects in the dissecting-rooms with a stick, it is certainly taking +rather a bizarre shape." + +"Beating the subjects!" + +"Yes, to verify how far bruises may be produced after death. I saw him +at it with my own eyes." + +"And yet you say he is not a medical student?" + +"No. Heaven knows what the objects of his studies are. But here we +are, and you must form your own impressions about him." As he spoke, we +turned down a narrow lane and passed through a small side-door, which +opened into a wing of the great hospital. It was familiar ground to me, +and I needed no guiding as we ascended the bleak stone staircase and +made our way down the long corridor with its vista of whitewashed +wall and dun-coloured doors. Near the further end a low arched passage +branched away from it and led to the chemical laboratory. + +This was a lofty chamber, lined and littered with countless bottles. +Broad, low tables were scattered about, which bristled with retorts, +test-tubes, and little Bunsen lamps, with their blue flickering flames. +There was only one student in the room, who was bending over a distant +table absorbed in his work. At the sound of our steps he glanced round +and sprang to his feet with a cry of pleasure. "I’ve found it! I’ve +found it," he shouted to my companion, running towards us with a +test-tube in his hand. "I have found a re-agent which is precipitated +by hoemoglobin, [4] and by nothing else." Had he discovered a gold mine, +greater delight could not have shone upon his features. + +"Dr. Watson, Mr. Sherlock Holmes," said Stamford, introducing us. + +"How are you?" he said cordially, gripping my hand with a strength +for which I should hardly have given him credit. "You have been in +Afghanistan, I perceive." + +"How on earth did you know that?" I asked in astonishment. + +"Never mind," said he, chuckling to himself. "The question now is about +hoemoglobin. No doubt you see the significance of this discovery of +mine?" + +"It is interesting, chemically, no doubt," I answered, "but +practically----" + +"Why, man, it is the most practical medico-legal discovery for years. +Don’t you see that it gives us an infallible test for blood stains. Come +over here now!" He seized me by the coat-sleeve in his eagerness, and +drew me over to the table at which he had been working. "Let us have +some fresh blood," he said, digging a long bodkin into his finger, and +drawing off the resulting drop of blood in a chemical pipette. "Now, I +add this small quantity of blood to a litre of water. You perceive that +the resulting mixture has the appearance of pure water. The proportion +of blood cannot be more than one in a million. I have no doubt, however, +that we shall be able to obtain the characteristic reaction." As he +spoke, he threw into the vessel a few white crystals, and then added +some drops of a transparent fluid. In an instant the contents assumed a +dull mahogany colour, and a brownish dust was precipitated to the bottom +of the glass jar. + +"Ha! ha!" he cried, clapping his hands, and looking as delighted as a +child with a new toy. "What do you think of that?" + +"It seems to be a very delicate test," I remarked. + +"Beautiful! beautiful! The old Guiacum test was very clumsy and +uncertain. So is the microscopic examination for blood corpuscles. The +latter is valueless if the stains are a few hours old. Now, this appears +to act as well whether the blood is old or new. Had this test been +invented, there are hundreds of men now walking the earth who would long +ago have paid the penalty of their crimes." + +"Indeed!" I murmured. + +"Criminal cases are continually hinging upon that one point. A man is +suspected of a crime months perhaps after it has been committed. His +linen or clothes are examined, and brownish stains discovered upon them. +Are they blood stains, or mud stains, or rust stains, or fruit stains, +or what are they? That is a question which has puzzled many an expert, +and why? Because there was no reliable test. Now we have the Sherlock +Holmes’ test, and there will no longer be any difficulty." + +His eyes fairly glittered as he spoke, and he put his hand over his +heart and bowed as if to some applauding crowd conjured up by his +imagination. + +"You are to be congratulated," I remarked, considerably surprised at his +enthusiasm. + +"There was the case of Von Bischoff at Frankfort last year. He would +certainly have been hung had this test been in existence. Then there was +Mason of Bradford, and the notorious Muller, and Lefevre of Montpellier, +and Samson of New Orleans. I could name a score of cases in which it +would have been decisive." + +"You seem to be a walking calendar of crime," said Stamford with a +laugh. "You might start a paper on those lines. Call it the ‘Police News +of the Past.’" + +"Very interesting reading it might be made, too," remarked Sherlock +Holmes, sticking a small piece of plaster over the prick on his finger. +"I have to be careful," he continued, turning to me with a smile, "for I +dabble with poisons a good deal." He held out his hand as he spoke, and +I noticed that it was all mottled over with similar pieces of plaster, +and discoloured with strong acids. + +"We came here on business," said Stamford, sitting down on a high +three-legged stool, and pushing another one in my direction with +his foot. "My friend here wants to take diggings, and as you were +complaining that you could get no one to go halves with you, I thought +that I had better bring you together." + +Sherlock Holmes seemed delighted at the idea of sharing his rooms with +me. "I have my eye on a suite in Baker Street," he said, "which would +suit us down to the ground. You don’t mind the smell of strong tobacco, +I hope?" + +"I always smoke ‘ship’s’ myself," I answered. + +"That’s good enough. I generally have chemicals about, and occasionally +do experiments. Would that annoy you?" + +"By no means." + +"Let me see--what are my other shortcomings. I get in the dumps at +times, and don’t open my mouth for days on end. You must not think I am +sulky when I do that. Just let me alone, and I’ll soon be right. What +have you to confess now? It’s just as well for two fellows to know the +worst of one another before they begin to live together." + +I laughed at this cross-examination. "I keep a bull pup," I said, "and +I object to rows because my nerves are shaken, and I get up at all sorts +of ungodly hours, and I am extremely lazy. I have another set of vices +when I’m well, but those are the principal ones at present." + +"Do you include violin-playing in your category of rows?" he asked, +anxiously. + +"It depends on the player," I answered. "A well-played violin is a treat +for the gods--a badly-played one----" + +"Oh, that’s all right," he cried, with a merry laugh. "I think we may +consider the thing as settled--that is, if the rooms are agreeable to +you." + +"When shall we see them?" + +"Call for me here at noon to-morrow, and we’ll go together and settle +everything," he answered. + +"All right--noon exactly," said I, shaking his hand. + +We left him working among his chemicals, and we walked together towards +my hotel. + +"By the way," I asked suddenly, stopping and turning upon Stamford, "how +the deuce did he know that I had come from Afghanistan?" + +My companion smiled an enigmatical smile. "That’s just his little +peculiarity," he said. "A good many people have wanted to know how he +finds things out." + +"Oh! a mystery is it?" I cried, rubbing my hands. "This is very piquant. +I am much obliged to you for bringing us together. ‘The proper study of +mankind is man,’ you know." + +"You must study him, then," Stamford said, as he bade me good-bye. +"You’ll find him a knotty problem, though. I’ll wager he learns more +about you than you about him. Good-bye." + +"Good-bye," I answered, and strolled on to my hotel, considerably +interested in my new acquaintance. + + + + +CHAPTER II. THE SCIENCE OF DEDUCTION. + + +WE met next day as he had arranged, and inspected the rooms at No. 221B, +[5] Baker Street, of which he had spoken at our meeting. They +consisted of a couple of comfortable bed-rooms and a single large +airy sitting-room, cheerfully furnished, and illuminated by two broad +windows. So desirable in every way were the apartments, and so moderate +did the terms seem when divided between us, that the bargain was +concluded upon the spot, and we at once entered into possession. +That very evening I moved my things round from the hotel, and on the +following morning Sherlock Holmes followed me with several boxes and +portmanteaus. For a day or two we were busily employed in unpacking and +laying out our property to the best advantage. That done, we +gradually began to settle down and to accommodate ourselves to our new +surroundings. + +Holmes was certainly not a difficult man to live with. He was quiet +in his ways, and his habits were regular. It was rare for him to be +up after ten at night, and he had invariably breakfasted and gone out +before I rose in the morning. Sometimes he spent his day at the chemical +laboratory, sometimes in the dissecting-rooms, and occasionally in long +walks, which appeared to take him into the lowest portions of the City. +Nothing could exceed his energy when the working fit was upon him; but +now and again a reaction would seize him, and for days on end he would +lie upon the sofa in the sitting-room, hardly uttering a word or moving +a muscle from morning to night. On these occasions I have noticed such +a dreamy, vacant expression in his eyes, that I might have suspected him +of being addicted to the use of some narcotic, had not the temperance +and cleanliness of his whole life forbidden such a notion. + +As the weeks went by, my interest in him and my curiosity as to his +aims in life, gradually deepened and increased. His very person and +appearance were such as to strike the attention of the most casual +observer. In height he was rather over six feet, and so excessively +lean that he seemed to be considerably taller. His eyes were sharp and +piercing, save during those intervals of torpor to which I have alluded; +and his thin, hawk-like nose gave his whole expression an air of +alertness and decision. His chin, too, had the prominence and squareness +which mark the man of determination. His hands were invariably +blotted with ink and stained with chemicals, yet he was possessed of +extraordinary delicacy of touch, as I frequently had occasion to observe +when I watched him manipulating his fragile philosophical instruments. + +The reader may set me down as a hopeless busybody, when I confess how +much this man stimulated my curiosity, and how often I endeavoured +to break through the reticence which he showed on all that concerned +himself. Before pronouncing judgment, however, be it remembered, how +objectless was my life, and how little there was to engage my attention. +My health forbade me from venturing out unless the weather was +exceptionally genial, and I had no friends who would call upon me and +break the monotony of my daily existence. Under these circumstances, I +eagerly hailed the little mystery which hung around my companion, and +spent much of my time in endeavouring to unravel it. + +He was not studying medicine. He had himself, in reply to a question, +confirmed Stamford’s opinion upon that point. Neither did he appear to +have pursued any course of reading which might fit him for a degree in +science or any other recognized portal which would give him an entrance +into the learned world. Yet his zeal for certain studies was remarkable, +and within eccentric limits his knowledge was so extraordinarily ample +and minute that his observations have fairly astounded me. Surely no man +would work so hard or attain such precise information unless he had some +definite end in view. Desultory readers are seldom remarkable for the +exactness of their learning. No man burdens his mind with small matters +unless he has some very good reason for doing so. + +His ignorance was as remarkable as his knowledge. Of contemporary +literature, philosophy and politics he appeared to know next to nothing. +Upon my quoting Thomas Carlyle, he inquired in the naivest way who he +might be and what he had done. My surprise reached a climax, however, +when I found incidentally that he was ignorant of the Copernican Theory +and of the composition of the Solar System. That any civilized human +being in this nineteenth century should not be aware that the earth +travelled round the sun appeared to be to me such an extraordinary fact +that I could hardly realize it. + +"You appear to be astonished," he said, smiling at my expression of +surprise. "Now that I do know it I shall do my best to forget it." + +"To forget it!" + +"You see," he explained, "I consider that a man’s brain originally is +like a little empty attic, and you have to stock it with such furniture +as you choose. A fool takes in all the lumber of every sort that he +comes across, so that the knowledge which might be useful to him gets +crowded out, or at best is jumbled up with a lot of other things so that +he has a difficulty in laying his hands upon it. Now the skilful workman +is very careful indeed as to what he takes into his brain-attic. He will +have nothing but the tools which may help him in doing his work, but of +these he has a large assortment, and all in the most perfect order. It +is a mistake to think that that little room has elastic walls and can +distend to any extent. Depend upon it there comes a time when for every +addition of knowledge you forget something that you knew before. It is +of the highest importance, therefore, not to have useless facts elbowing +out the useful ones." + +"But the Solar System!" I protested. + +"What the deuce is it to me?" he interrupted impatiently; "you say +that we go round the sun. If we went round the moon it would not make a +pennyworth of difference to me or to my work." + +I was on the point of asking him what that work might be, but something +in his manner showed me that the question would be an unwelcome one. I +pondered over our short conversation, however, and endeavoured to draw +my deductions from it. He said that he would acquire no knowledge which +did not bear upon his object. Therefore all the knowledge which he +possessed was such as would be useful to him. I enumerated in my own +mind all the various points upon which he had shown me that he was +exceptionally well-informed. I even took a pencil and jotted them down. +I could not help smiling at the document when I had completed it. It ran +in this way-- + + +SHERLOCK HOLMES--his limits. + + 1. Knowledge of Literature.--Nil. + 2. Philosophy.--Nil. + 3. Astronomy.--Nil. + 4. Politics.--Feeble. + 5. Botany.--Variable. Well up in belladonna, + opium, and poisons generally. + Knows nothing of practical gardening. + 6. Geology.--Practical, but limited. + Tells at a glance different soils + from each other. After walks has + shown me splashes upon his trousers, + and told me by their colour and + consistence in what part of London + he had received them. + 7. Chemistry.--Profound. + 8. Anatomy.--Accurate, but unsystematic. + 9. Sensational Literature.--Immense. He appears + to know every detail of every horror + perpetrated in the century. + 10. Plays the violin well. + 11. Is an expert singlestick player, boxer, and swordsman. + 12. Has a good practical knowledge of British law. + + +When I had got so far in my list I threw it into the fire in despair. +"If I can only find what the fellow is driving at by reconciling all +these accomplishments, and discovering a calling which needs them all," + I said to myself, "I may as well give up the attempt at once." + +I see that I have alluded above to his powers upon the violin. These +were very remarkable, but as eccentric as all his other accomplishments. +That he could play pieces, and difficult pieces, I knew well, because +at my request he has played me some of Mendelssohn’s Lieder, and other +favourites. When left to himself, however, he would seldom produce any +music or attempt any recognized air. Leaning back in his arm-chair of +an evening, he would close his eyes and scrape carelessly at the fiddle +which was thrown across his knee. Sometimes the chords were sonorous and +melancholy. Occasionally they were fantastic and cheerful. Clearly they +reflected the thoughts which possessed him, but whether the music aided +those thoughts, or whether the playing was simply the result of a whim +or fancy was more than I could determine. I might have rebelled against +these exasperating solos had it not been that he usually terminated them +by playing in quick succession a whole series of my favourite airs as a +slight compensation for the trial upon my patience. + +During the first week or so we had no callers, and I had begun to think +that my companion was as friendless a man as I was myself. Presently, +however, I found that he had many acquaintances, and those in the most +different classes of society. There was one little sallow rat-faced, +dark-eyed fellow who was introduced to me as Mr. Lestrade, and who came +three or four times in a single week. One morning a young girl called, +fashionably dressed, and stayed for half an hour or more. The same +afternoon brought a grey-headed, seedy visitor, looking like a Jew +pedlar, who appeared to me to be much excited, and who was closely +followed by a slip-shod elderly woman. On another occasion an old +white-haired gentleman had an interview with my companion; and on +another a railway porter in his velveteen uniform. When any of these +nondescript individuals put in an appearance, Sherlock Holmes used to +beg for the use of the sitting-room, and I would retire to my bed-room. +He always apologized to me for putting me to this inconvenience. "I have +to use this room as a place of business," he said, "and these people +are my clients." Again I had an opportunity of asking him a point blank +question, and again my delicacy prevented me from forcing another man to +confide in me. I imagined at the time that he had some strong reason for +not alluding to it, but he soon dispelled the idea by coming round to +the subject of his own accord. + +It was upon the 4th of March, as I have good reason to remember, that I +rose somewhat earlier than usual, and found that Sherlock Holmes had not +yet finished his breakfast. The landlady had become so accustomed to my +late habits that my place had not been laid nor my coffee prepared. With +the unreasonable petulance of mankind I rang the bell and gave a curt +intimation that I was ready. Then I picked up a magazine from the table +and attempted to while away the time with it, while my companion munched +silently at his toast. One of the articles had a pencil mark at the +heading, and I naturally began to run my eye through it. + +Its somewhat ambitious title was "The Book of Life," and it attempted to +show how much an observant man might learn by an accurate and systematic +examination of all that came in his way. It struck me as being a +remarkable mixture of shrewdness and of absurdity. The reasoning was +close and intense, but the deductions appeared to me to be far-fetched +and exaggerated. The writer claimed by a momentary expression, a twitch +of a muscle or a glance of an eye, to fathom a man’s inmost thoughts. +Deceit, according to him, was an impossibility in the case of one +trained to observation and analysis. His conclusions were as infallible +as so many propositions of Euclid. So startling would his results appear +to the uninitiated that until they learned the processes by which he had +arrived at them they might well consider him as a necromancer. + +"From a drop of water," said the writer, "a logician could infer the +possibility of an Atlantic or a Niagara without having seen or heard of +one or the other. So all life is a great chain, the nature of which is +known whenever we are shown a single link of it. Like all other arts, +the Science of Deduction and Analysis is one which can only be acquired +by long and patient study nor is life long enough to allow any mortal +to attain the highest possible perfection in it. Before turning to +those moral and mental aspects of the matter which present the greatest +difficulties, let the enquirer begin by mastering more elementary +problems. Let him, on meeting a fellow-mortal, learn at a glance to +distinguish the history of the man, and the trade or profession to +which he belongs. Puerile as such an exercise may seem, it sharpens the +faculties of observation, and teaches one where to look and what to look +for. By a man’s finger nails, by his coat-sleeve, by his boot, by his +trouser knees, by the callosities of his forefinger and thumb, by his +expression, by his shirt cuffs--by each of these things a man’s calling +is plainly revealed. That all united should fail to enlighten the +competent enquirer in any case is almost inconceivable." + +"What ineffable twaddle!" I cried, slapping the magazine down on the +table, "I never read such rubbish in my life." + +"What is it?" asked Sherlock Holmes. + +"Why, this article," I said, pointing at it with my egg spoon as I sat +down to my breakfast. "I see that you have read it since you have marked +it. I don’t deny that it is smartly written. It irritates me though. It +is evidently the theory of some arm-chair lounger who evolves all these +neat little paradoxes in the seclusion of his own study. It is not +practical. I should like to see him clapped down in a third class +carriage on the Underground, and asked to give the trades of all his +fellow-travellers. I would lay a thousand to one against him." + +"You would lose your money," Sherlock Holmes remarked calmly. "As for +the article I wrote it myself." + +"You!" + +"Yes, I have a turn both for observation and for deduction. The +theories which I have expressed there, and which appear to you to be so +chimerical are really extremely practical--so practical that I depend +upon them for my bread and cheese." + +"And how?" I asked involuntarily. + +"Well, I have a trade of my own. I suppose I am the only one in the +world. I’m a consulting detective, if you can understand what that is. +Here in London we have lots of Government detectives and lots of private +ones. When these fellows are at fault they come to me, and I manage to +put them on the right scent. They lay all the evidence before me, and I +am generally able, by the help of my knowledge of the history of +crime, to set them straight. There is a strong family resemblance about +misdeeds, and if you have all the details of a thousand at your finger +ends, it is odd if you can’t unravel the thousand and first. Lestrade +is a well-known detective. He got himself into a fog recently over a +forgery case, and that was what brought him here." + +"And these other people?" + +"They are mostly sent on by private inquiry agencies. They are +all people who are in trouble about something, and want a little +enlightening. I listen to their story, they listen to my comments, and +then I pocket my fee." + +"But do you mean to say," I said, "that without leaving your room you +can unravel some knot which other men can make nothing of, although they +have seen every detail for themselves?" + +"Quite so. I have a kind of intuition that way. Now and again a case +turns up which is a little more complex. Then I have to bustle about and +see things with my own eyes. You see I have a lot of special knowledge +which I apply to the problem, and which facilitates matters wonderfully. +Those rules of deduction laid down in that article which aroused your +scorn, are invaluable to me in practical work. Observation with me is +second nature. You appeared to be surprised when I told you, on our +first meeting, that you had come from Afghanistan." + +"You were told, no doubt." + +"Nothing of the sort. I _knew_ you came from Afghanistan. From long +habit the train of thoughts ran so swiftly through my mind, that I +arrived at the conclusion without being conscious of intermediate steps. +There were such steps, however. The train of reasoning ran, ‘Here is a +gentleman of a medical type, but with the air of a military man. Clearly +an army doctor, then. He has just come from the tropics, for his face is +dark, and that is not the natural tint of his skin, for his wrists are +fair. He has undergone hardship and sickness, as his haggard face says +clearly. His left arm has been injured. He holds it in a stiff and +unnatural manner. Where in the tropics could an English army doctor have +seen much hardship and got his arm wounded? Clearly in Afghanistan.’ The +whole train of thought did not occupy a second. I then remarked that you +came from Afghanistan, and you were astonished." + +"It is simple enough as you explain it," I said, smiling. "You remind +me of Edgar Allen Poe’s Dupin. I had no idea that such individuals did +exist outside of stories." + +Sherlock Holmes rose and lit his pipe. "No doubt you think that you are +complimenting me in comparing me to Dupin," he observed. "Now, in my +opinion, Dupin was a very inferior fellow. That trick of his of breaking +in on his friends’ thoughts with an apropos remark after a quarter of +an hour’s silence is really very showy and superficial. He had some +analytical genius, no doubt; but he was by no means such a phenomenon as +Poe appeared to imagine." + +"Have you read Gaboriau’s works?" I asked. "Does Lecoq come up to your +idea of a detective?" + +Sherlock Holmes sniffed sardonically. "Lecoq was a miserable bungler," + he said, in an angry voice; "he had only one thing to recommend him, and +that was his energy. That book made me positively ill. The question was +how to identify an unknown prisoner. I could have done it in twenty-four +hours. Lecoq took six months or so. It might be made a text-book for +detectives to teach them what to avoid." + +I felt rather indignant at having two characters whom I had admired +treated in this cavalier style. I walked over to the window, and stood +looking out into the busy street. "This fellow may be very clever," I +said to myself, "but he is certainly very conceited." + +"There are no crimes and no criminals in these days," he said, +querulously. "What is the use of having brains in our profession. I know +well that I have it in me to make my name famous. No man lives or has +ever lived who has brought the same amount of study and of natural +talent to the detection of crime which I have done. And what is the +result? There is no crime to detect, or, at most, some bungling villainy +with a motive so transparent that even a Scotland Yard official can see +through it." + +I was still annoyed at his bumptious style of conversation. I thought it +best to change the topic. + +"I wonder what that fellow is looking for?" I asked, pointing to a +stalwart, plainly-dressed individual who was walking slowly down the +other side of the street, looking anxiously at the numbers. He had +a large blue envelope in his hand, and was evidently the bearer of a +message. + +"You mean the retired sergeant of Marines," said Sherlock Holmes. + +"Brag and bounce!" thought I to myself. "He knows that I cannot verify +his guess." + +The thought had hardly passed through my mind when the man whom we were +watching caught sight of the number on our door, and ran rapidly across +the roadway. We heard a loud knock, a deep voice below, and heavy steps +ascending the stair. + +"For Mr. Sherlock Holmes," he said, stepping into the room and handing +my friend the letter. + +Here was an opportunity of taking the conceit out of him. He little +thought of this when he made that random shot. "May I ask, my lad," I +said, in the blandest voice, "what your trade may be?" + +"Commissionaire, sir," he said, gruffly. "Uniform away for repairs." + +"And you were?" I asked, with a slightly malicious glance at my +companion. + +"A sergeant, sir, Royal Marine Light Infantry, sir. No answer? Right, +sir." + +He clicked his heels together, raised his hand in a salute, and was +gone. + + + + +CHAPTER III. THE LAURISTON GARDEN MYSTERY [6] + + +I CONFESS that I was considerably startled by this fresh proof of the +practical nature of my companion’s theories. My respect for his powers +of analysis increased wondrously. There still remained some lurking +suspicion in my mind, however, that the whole thing was a pre-arranged +episode, intended to dazzle me, though what earthly object he could have +in taking me in was past my comprehension. When I looked at him he +had finished reading the note, and his eyes had assumed the vacant, +lack-lustre expression which showed mental abstraction. + +"How in the world did you deduce that?" I asked. + +"Deduce what?" said he, petulantly. + +"Why, that he was a retired sergeant of Marines." + +"I have no time for trifles," he answered, brusquely; then with a smile, +"Excuse my rudeness. You broke the thread of my thoughts; but perhaps +it is as well. So you actually were not able to see that that man was a +sergeant of Marines?" + +"No, indeed." + +"It was easier to know it than to explain why I knew it. If you +were asked to prove that two and two made four, you might find some +difficulty, and yet you are quite sure of the fact. Even across the +street I could see a great blue anchor tattooed on the back of the +fellow’s hand. That smacked of the sea. He had a military carriage, +however, and regulation side whiskers. There we have the marine. He was +a man with some amount of self-importance and a certain air of command. +You must have observed the way in which he held his head and swung +his cane. A steady, respectable, middle-aged man, too, on the face of +him--all facts which led me to believe that he had been a sergeant." + +"Wonderful!" I ejaculated. + +"Commonplace," said Holmes, though I thought from his expression that he +was pleased at my evident surprise and admiration. "I said just now that +there were no criminals. It appears that I am wrong--look at this!" He +threw me over the note which the commissionaire had brought. [7] + +"Why," I cried, as I cast my eye over it, "this is terrible!" + +"It does seem to be a little out of the common," he remarked, calmly. +"Would you mind reading it to me aloud?" + +This is the letter which I read to him---- + + +"MY DEAR MR. SHERLOCK HOLMES,-- + +"There has been a bad business during the night at 3, Lauriston Gardens, +off the Brixton Road. Our man on the beat saw a light there about two in +the morning, and as the house was an empty one, suspected that something +was amiss. He found the door open, and in the front room, which is bare +of furniture, discovered the body of a gentleman, well dressed, and +having cards in his pocket bearing the name of ‘Enoch J. Drebber, +Cleveland, Ohio, U.S.A.’ There had been no robbery, nor is there any +evidence as to how the man met his death. There are marks of blood in +the room, but there is no wound upon his person. We are at a loss as to +how he came into the empty house; indeed, the whole affair is a puzzler. +If you can come round to the house any time before twelve, you will find +me there. I have left everything _in statu quo_ until I hear from you. +If you are unable to come I shall give you fuller details, and would +esteem it a great kindness if you would favour me with your opinion. +Yours faithfully, + +"TOBIAS GREGSON." + + +"Gregson is the smartest of the Scotland Yarders," my friend remarked; +"he and Lestrade are the pick of a bad lot. They are both quick and +energetic, but conventional--shockingly so. They have their knives +into one another, too. They are as jealous as a pair of professional +beauties. There will be some fun over this case if they are both put +upon the scent." + +I was amazed at the calm way in which he rippled on. "Surely there is +not a moment to be lost," I cried, "shall I go and order you a cab?" + +"I’m not sure about whether I shall go. I am the most incurably lazy +devil that ever stood in shoe leather--that is, when the fit is on me, +for I can be spry enough at times." + +"Why, it is just such a chance as you have been longing for." + +"My dear fellow, what does it matter to me. Supposing I unravel the +whole matter, you may be sure that Gregson, Lestrade, and Co. will +pocket all the credit. That comes of being an unofficial personage." + +"But he begs you to help him." + +"Yes. He knows that I am his superior, and acknowledges it to me; but +he would cut his tongue out before he would own it to any third person. +However, we may as well go and have a look. I shall work it out on my +own hook. I may have a laugh at them if I have nothing else. Come on!" + +He hustled on his overcoat, and bustled about in a way that showed that +an energetic fit had superseded the apathetic one. + +"Get your hat," he said. + +"You wish me to come?" + +"Yes, if you have nothing better to do." A minute later we were both in +a hansom, driving furiously for the Brixton Road. + +It was a foggy, cloudy morning, and a dun-coloured veil hung over the +house-tops, looking like the reflection of the mud-coloured streets +beneath. My companion was in the best of spirits, and prattled away +about Cremona fiddles, and the difference between a Stradivarius and +an Amati. As for myself, I was silent, for the dull weather and the +melancholy business upon which we were engaged, depressed my spirits. + +"You don’t seem to give much thought to the matter in hand," I said at +last, interrupting Holmes’ musical disquisition. + +"No data yet," he answered. "It is a capital mistake to theorize before +you have all the evidence. It biases the judgment." + +"You will have your data soon," I remarked, pointing with my finger; +"this is the Brixton Road, and that is the house, if I am not very much +mistaken." + +"So it is. Stop, driver, stop!" We were still a hundred yards or so from +it, but he insisted upon our alighting, and we finished our journey upon +foot. + +Number 3, Lauriston Gardens wore an ill-omened and minatory look. It was +one of four which stood back some little way from the street, two being +occupied and two empty. The latter looked out with three tiers of vacant +melancholy windows, which were blank and dreary, save that here and +there a "To Let" card had developed like a cataract upon the bleared +panes. A small garden sprinkled over with a scattered eruption of sickly +plants separated each of these houses from the street, and was traversed +by a narrow pathway, yellowish in colour, and consisting apparently of a +mixture of clay and of gravel. The whole place was very sloppy from the +rain which had fallen through the night. The garden was bounded by a +three-foot brick wall with a fringe of wood rails upon the top, and +against this wall was leaning a stalwart police constable, surrounded by +a small knot of loafers, who craned their necks and strained their eyes +in the vain hope of catching some glimpse of the proceedings within. + +I had imagined that Sherlock Holmes would at once have hurried into the +house and plunged into a study of the mystery. Nothing appeared to be +further from his intention. With an air of nonchalance which, under the +circumstances, seemed to me to border upon affectation, he lounged up +and down the pavement, and gazed vacantly at the ground, the sky, the +opposite houses and the line of railings. Having finished his scrutiny, +he proceeded slowly down the path, or rather down the fringe of grass +which flanked the path, keeping his eyes riveted upon the ground. Twice +he stopped, and once I saw him smile, and heard him utter an exclamation +of satisfaction. There were many marks of footsteps upon the wet clayey +soil, but since the police had been coming and going over it, I was +unable to see how my companion could hope to learn anything from it. +Still I had had such extraordinary evidence of the quickness of his +perceptive faculties, that I had no doubt that he could see a great deal +which was hidden from me. + +At the door of the house we were met by a tall, white-faced, +flaxen-haired man, with a notebook in his hand, who rushed forward and +wrung my companion’s hand with effusion. "It is indeed kind of you to +come," he said, "I have had everything left untouched." + +"Except that!" my friend answered, pointing at the pathway. "If a herd +of buffaloes had passed along there could not be a greater mess. No +doubt, however, you had drawn your own conclusions, Gregson, before you +permitted this." + +"I have had so much to do inside the house," the detective said +evasively. "My colleague, Mr. Lestrade, is here. I had relied upon him +to look after this." + +Holmes glanced at me and raised his eyebrows sardonically. "With two +such men as yourself and Lestrade upon the ground, there will not be +much for a third party to find out," he said. + +Gregson rubbed his hands in a self-satisfied way. "I think we have done +all that can be done," he answered; "it’s a queer case though, and I +knew your taste for such things." + +"You did not come here in a cab?" asked Sherlock Holmes. + +"No, sir." + +"Nor Lestrade?" + +"No, sir." + +"Then let us go and look at the room." With which inconsequent remark he +strode on into the house, followed by Gregson, whose features expressed +his astonishment. + +A short passage, bare planked and dusty, led to the kitchen and offices. +Two doors opened out of it to the left and to the right. One of these +had obviously been closed for many weeks. The other belonged to the +dining-room, which was the apartment in which the mysterious affair had +occurred. Holmes walked in, and I followed him with that subdued feeling +at my heart which the presence of death inspires. + +It was a large square room, looking all the larger from the absence +of all furniture. A vulgar flaring paper adorned the walls, but it was +blotched in places with mildew, and here and there great strips had +become detached and hung down, exposing the yellow plaster beneath. +Opposite the door was a showy fireplace, surmounted by a mantelpiece of +imitation white marble. On one corner of this was stuck the stump of a +red wax candle. The solitary window was so dirty that the light was +hazy and uncertain, giving a dull grey tinge to everything, which was +intensified by the thick layer of dust which coated the whole apartment. + +All these details I observed afterwards. At present my attention was +centred upon the single grim motionless figure which lay stretched upon +the boards, with vacant sightless eyes staring up at the discoloured +ceiling. It was that of a man about forty-three or forty-four years of +age, middle-sized, broad shouldered, with crisp curling black hair, and +a short stubbly beard. He was dressed in a heavy broadcloth frock coat +and waistcoat, with light-coloured trousers, and immaculate collar +and cuffs. A top hat, well brushed and trim, was placed upon the floor +beside him. His hands were clenched and his arms thrown abroad, while +his lower limbs were interlocked as though his death struggle had been a +grievous one. On his rigid face there stood an expression of horror, +and as it seemed to me, of hatred, such as I have never seen upon human +features. This malignant and terrible contortion, combined with the low +forehead, blunt nose, and prognathous jaw gave the dead man a singularly +simious and ape-like appearance, which was increased by his writhing, +unnatural posture. I have seen death in many forms, but never has +it appeared to me in a more fearsome aspect than in that dark grimy +apartment, which looked out upon one of the main arteries of suburban +London. + +Lestrade, lean and ferret-like as ever, was standing by the doorway, and +greeted my companion and myself. + +"This case will make a stir, sir," he remarked. "It beats anything I +have seen, and I am no chicken." + +"There is no clue?" said Gregson. + +"None at all," chimed in Lestrade. + +Sherlock Holmes approached the body, and, kneeling down, examined it +intently. "You are sure that there is no wound?" he asked, pointing to +numerous gouts and splashes of blood which lay all round. + +"Positive!" cried both detectives. + +"Then, of course, this blood belongs to a second individual--[8] +presumably the murderer, if murder has been committed. It reminds me of +the circumstances attendant on the death of Van Jansen, in Utrecht, in +the year ‘34. Do you remember the case, Gregson?" + +"No, sir." + +"Read it up--you really should. There is nothing new under the sun. It +has all been done before." + +As he spoke, his nimble fingers were flying here, there, and everywhere, +feeling, pressing, unbuttoning, examining, while his eyes wore the same +far-away expression which I have already remarked upon. So swiftly was +the examination made, that one would hardly have guessed the minuteness +with which it was conducted. Finally, he sniffed the dead man’s lips, +and then glanced at the soles of his patent leather boots. + +"He has not been moved at all?" he asked. + +"No more than was necessary for the purposes of our examination." + +"You can take him to the mortuary now," he said. "There is nothing more +to be learned." + +Gregson had a stretcher and four men at hand. At his call they entered +the room, and the stranger was lifted and carried out. As they raised +him, a ring tinkled down and rolled across the floor. Lestrade grabbed +it up and stared at it with mystified eyes. + +"There’s been a woman here," he cried. "It’s a woman’s wedding-ring." + +He held it out, as he spoke, upon the palm of his hand. We all gathered +round him and gazed at it. There could be no doubt that that circlet of +plain gold had once adorned the finger of a bride. + +"This complicates matters," said Gregson. "Heaven knows, they were +complicated enough before." + +"You’re sure it doesn’t simplify them?" observed Holmes. "There’s +nothing to be learned by staring at it. What did you find in his +pockets?" + +"We have it all here," said Gregson, pointing to a litter of objects +upon one of the bottom steps of the stairs. "A gold watch, No. 97163, by +Barraud, of London. Gold Albert chain, very heavy and solid. Gold ring, +with masonic device. Gold pin--bull-dog’s head, with rubies as eyes. +Russian leather card-case, with cards of Enoch J. Drebber of Cleveland, +corresponding with the E. J. D. upon the linen. No purse, but loose +money to the extent of seven pounds thirteen. Pocket edition of +Boccaccio’s ‘Decameron,’ with name of Joseph Stangerson upon the +fly-leaf. Two letters--one addressed to E. J. Drebber and one to Joseph +Stangerson." + +"At what address?" + +"American Exchange, Strand--to be left till called for. They are both +from the Guion Steamship Company, and refer to the sailing of their +boats from Liverpool. It is clear that this unfortunate man was about to +return to New York." + +"Have you made any inquiries as to this man, Stangerson?" + +"I did it at once, sir," said Gregson. "I have had advertisements +sent to all the newspapers, and one of my men has gone to the American +Exchange, but he has not returned yet." + +"Have you sent to Cleveland?" + +"We telegraphed this morning." + +"How did you word your inquiries?" + +"We simply detailed the circumstances, and said that we should be glad +of any information which could help us." + +"You did not ask for particulars on any point which appeared to you to +be crucial?" + +"I asked about Stangerson." + +"Nothing else? Is there no circumstance on which this whole case appears +to hinge? Will you not telegraph again?" + +"I have said all I have to say," said Gregson, in an offended voice. + +Sherlock Holmes chuckled to himself, and appeared to be about to make +some remark, when Lestrade, who had been in the front room while we +were holding this conversation in the hall, reappeared upon the scene, +rubbing his hands in a pompous and self-satisfied manner. + +"Mr. Gregson," he said, "I have just made a discovery of the highest +importance, and one which would have been overlooked had I not made a +careful examination of the walls." + +The little man’s eyes sparkled as he spoke, and he was evidently in +a state of suppressed exultation at having scored a point against his +colleague. + +"Come here," he said, bustling back into the room, the atmosphere of +which felt clearer since the removal of its ghastly inmate. "Now, stand +there!" + +He struck a match on his boot and held it up against the wall. + +"Look at that!" he said, triumphantly. + +I have remarked that the paper had fallen away in parts. In this +particular corner of the room a large piece had peeled off, leaving a +yellow square of coarse plastering. Across this bare space there was +scrawled in blood-red letters a single word-- + + RACHE. + + +"What do you think of that?" cried the detective, with the air of a +showman exhibiting his show. "This was overlooked because it was in the +darkest corner of the room, and no one thought of looking there. The +murderer has written it with his or her own blood. See this smear where +it has trickled down the wall! That disposes of the idea of suicide +anyhow. Why was that corner chosen to write it on? I will tell you. See +that candle on the mantelpiece. It was lit at the time, and if it was +lit this corner would be the brightest instead of the darkest portion of +the wall." + +"And what does it mean now that you _have_ found it?" asked Gregson in a +depreciatory voice. + +"Mean? Why, it means that the writer was going to put the female name +Rachel, but was disturbed before he or she had time to finish. You mark +my words, when this case comes to be cleared up you will find that a +woman named Rachel has something to do with it. It’s all very well for +you to laugh, Mr. Sherlock Holmes. You may be very smart and clever, but +the old hound is the best, when all is said and done." + +"I really beg your pardon!" said my companion, who had ruffled the +little man’s temper by bursting into an explosion of laughter. "You +certainly have the credit of being the first of us to find this out, +and, as you say, it bears every mark of having been written by the other +participant in last night’s mystery. I have not had time to examine this +room yet, but with your permission I shall do so now." + +As he spoke, he whipped a tape measure and a large round magnifying +glass from his pocket. With these two implements he trotted noiselessly +about the room, sometimes stopping, occasionally kneeling, and once +lying flat upon his face. So engrossed was he with his occupation that +he appeared to have forgotten our presence, for he chattered away to +himself under his breath the whole time, keeping up a running fire +of exclamations, groans, whistles, and little cries suggestive of +encouragement and of hope. As I watched him I was irresistibly reminded +of a pure-blooded well-trained foxhound as it dashes backwards and +forwards through the covert, whining in its eagerness, until it comes +across the lost scent. For twenty minutes or more he continued his +researches, measuring with the most exact care the distance between +marks which were entirely invisible to me, and occasionally applying his +tape to the walls in an equally incomprehensible manner. In one place +he gathered up very carefully a little pile of grey dust from the floor, +and packed it away in an envelope. Finally, he examined with his glass +the word upon the wall, going over every letter of it with the most +minute exactness. This done, he appeared to be satisfied, for he +replaced his tape and his glass in his pocket. + +"They say that genius is an infinite capacity for taking pains," he +remarked with a smile. "It’s a very bad definition, but it does apply to +detective work." + +Gregson and Lestrade had watched the manoeuvres [9] of their amateur +companion with considerable curiosity and some contempt. They evidently +failed to appreciate the fact, which I had begun to realize, that +Sherlock Holmes’ smallest actions were all directed towards some +definite and practical end. + +"What do you think of it, sir?" they both asked. + +"It would be robbing you of the credit of the case if I was to presume +to help you," remarked my friend. "You are doing so well now that it +would be a pity for anyone to interfere." There was a world of +sarcasm in his voice as he spoke. "If you will let me know how your +investigations go," he continued, "I shall be happy to give you any help +I can. In the meantime I should like to speak to the constable who found +the body. Can you give me his name and address?" + +Lestrade glanced at his note-book. "John Rance," he said. "He is off +duty now. You will find him at 46, Audley Court, Kennington Park Gate." + +Holmes took a note of the address. + +"Come along, Doctor," he said; "we shall go and look him up. I’ll tell +you one thing which may help you in the case," he continued, turning to +the two detectives. "There has been murder done, and the murderer was a +man. He was more than six feet high, was in the prime of life, had +small feet for his height, wore coarse, square-toed boots and smoked a +Trichinopoly cigar. He came here with his victim in a four-wheeled cab, +which was drawn by a horse with three old shoes and one new one on his +off fore leg. In all probability the murderer had a florid face, and the +finger-nails of his right hand were remarkably long. These are only a +few indications, but they may assist you." + +Lestrade and Gregson glanced at each other with an incredulous smile. + +"If this man was murdered, how was it done?" asked the former. + +"Poison," said Sherlock Holmes curtly, and strode off. "One other thing, +Lestrade," he added, turning round at the door: "‘Rache,’ is the German +for ‘revenge;’ so don’t lose your time looking for Miss Rachel." + +With which Parthian shot he walked away, leaving the two rivals +open-mouthed behind him. + + + + +CHAPTER IV. WHAT JOHN RANCE HAD TO TELL. + + +IT was one o’clock when we left No. 3, Lauriston Gardens. Sherlock +Holmes led me to the nearest telegraph office, whence he dispatched a +long telegram. He then hailed a cab, and ordered the driver to take us +to the address given us by Lestrade. + +"There is nothing like first hand evidence," he remarked; "as a matter +of fact, my mind is entirely made up upon the case, but still we may as +well learn all that is to be learned." + +"You amaze me, Holmes," said I. "Surely you are not as sure as you +pretend to be of all those particulars which you gave." + +"There’s no room for a mistake," he answered. "The very first thing +which I observed on arriving there was that a cab had made two ruts with +its wheels close to the curb. Now, up to last night, we have had no rain +for a week, so that those wheels which left such a deep impression must +have been there during the night. There were the marks of the horse’s +hoofs, too, the outline of one of which was far more clearly cut than +that of the other three, showing that that was a new shoe. Since the cab +was there after the rain began, and was not there at any time during the +morning--I have Gregson’s word for that--it follows that it must have +been there during the night, and, therefore, that it brought those two +individuals to the house." + +"That seems simple enough," said I; "but how about the other man’s +height?" + +"Why, the height of a man, in nine cases out of ten, can be told from +the length of his stride. It is a simple calculation enough, though +there is no use my boring you with figures. I had this fellow’s stride +both on the clay outside and on the dust within. Then I had a way of +checking my calculation. When a man writes on a wall, his instinct leads +him to write about the level of his own eyes. Now that writing was just +over six feet from the ground. It was child’s play." + +"And his age?" I asked. + +"Well, if a man can stride four and a-half feet without the smallest +effort, he can’t be quite in the sere and yellow. That was the breadth +of a puddle on the garden walk which he had evidently walked across. +Patent-leather boots had gone round, and Square-toes had hopped over. +There is no mystery about it at all. I am simply applying to ordinary +life a few of those precepts of observation and deduction which I +advocated in that article. Is there anything else that puzzles you?" + +"The finger nails and the Trichinopoly," I suggested. + +"The writing on the wall was done with a man’s forefinger dipped in +blood. My glass allowed me to observe that the plaster was slightly +scratched in doing it, which would not have been the case if the man’s +nail had been trimmed. I gathered up some scattered ash from the floor. +It was dark in colour and flakey--such an ash as is only made by a +Trichinopoly. I have made a special study of cigar ashes--in fact, I +have written a monograph upon the subject. I flatter myself that I can +distinguish at a glance the ash of any known brand, either of cigar +or of tobacco. It is just in such details that the skilled detective +differs from the Gregson and Lestrade type." + +"And the florid face?" I asked. + +"Ah, that was a more daring shot, though I have no doubt that I was +right. You must not ask me that at the present state of the affair." + +I passed my hand over my brow. "My head is in a whirl," I remarked; "the +more one thinks of it the more mysterious it grows. How came these two +men--if there were two men--into an empty house? What has become of the +cabman who drove them? How could one man compel another to take poison? +Where did the blood come from? What was the object of the murderer, +since robbery had no part in it? How came the woman’s ring there? Above +all, why should the second man write up the German word RACHE before +decamping? I confess that I cannot see any possible way of reconciling +all these facts." + +My companion smiled approvingly. + +"You sum up the difficulties of the situation succinctly and well," he +said. "There is much that is still obscure, though I have quite made up +my mind on the main facts. As to poor Lestrade’s discovery it was simply +a blind intended to put the police upon a wrong track, by suggesting +Socialism and secret societies. It was not done by a German. The A, if +you noticed, was printed somewhat after the German fashion. Now, a real +German invariably prints in the Latin character, so that we may safely +say that this was not written by one, but by a clumsy imitator who +overdid his part. It was simply a ruse to divert inquiry into a wrong +channel. I’m not going to tell you much more of the case, Doctor. You +know a conjuror gets no credit when once he has explained his trick, +and if I show you too much of my method of working, you will come to the +conclusion that I am a very ordinary individual after all." + +"I shall never do that," I answered; "you have brought detection as near +an exact science as it ever will be brought in this world." + +My companion flushed up with pleasure at my words, and the earnest way +in which I uttered them. I had already observed that he was as sensitive +to flattery on the score of his art as any girl could be of her beauty. + +"I’ll tell you one other thing," he said. "Patent leathers [10] and +Square-toes came in the same cab, and they walked down the pathway +together as friendly as possible--arm-in-arm, in all probability. +When they got inside they walked up and down the room--or rather, +Patent-leathers stood still while Square-toes walked up and down. I +could read all that in the dust; and I could read that as he walked he +grew more and more excited. That is shown by the increased length of his +strides. He was talking all the while, and working himself up, no doubt, +into a fury. Then the tragedy occurred. I’ve told you all I know myself +now, for the rest is mere surmise and conjecture. We have a good working +basis, however, on which to start. We must hurry up, for I want to go to +Halle’s concert to hear Norman Neruda this afternoon." + +This conversation had occurred while our cab had been threading its way +through a long succession of dingy streets and dreary by-ways. In the +dingiest and dreariest of them our driver suddenly came to a stand. +"That’s Audley Court in there," he said, pointing to a narrow slit in +the line of dead-coloured brick. "You’ll find me here when you come +back." + +Audley Court was not an attractive locality. The narrow passage led us +into a quadrangle paved with flags and lined by sordid dwellings. We +picked our way among groups of dirty children, and through lines of +discoloured linen, until we came to Number 46, the door of which +was decorated with a small slip of brass on which the name Rance was +engraved. On enquiry we found that the constable was in bed, and we were +shown into a little front parlour to await his coming. + +He appeared presently, looking a little irritable at being disturbed in +his slumbers. "I made my report at the office," he said. + +Holmes took a half-sovereign from his pocket and played with it +pensively. "We thought that we should like to hear it all from your own +lips," he said. + +"I shall be most happy to tell you anything I can," the constable +answered with his eyes upon the little golden disk. + +"Just let us hear it all in your own way as it occurred." + +Rance sat down on the horsehair sofa, and knitted his brows as though +determined not to omit anything in his narrative. + +"I’ll tell it ye from the beginning," he said. "My time is from ten at +night to six in the morning. At eleven there was a fight at the ‘White +Hart’; but bar that all was quiet enough on the beat. At one o’clock it +began to rain, and I met Harry Murcher--him who has the Holland Grove +beat--and we stood together at the corner of Henrietta Street a-talkin’. +Presently--maybe about two or a little after--I thought I would take +a look round and see that all was right down the Brixton Road. It was +precious dirty and lonely. Not a soul did I meet all the way down, +though a cab or two went past me. I was a strollin’ down, thinkin’ +between ourselves how uncommon handy a four of gin hot would be, when +suddenly the glint of a light caught my eye in the window of that same +house. Now, I knew that them two houses in Lauriston Gardens was empty +on account of him that owns them who won’t have the drains seen to, +though the very last tenant what lived in one of them died o’ typhoid +fever. I was knocked all in a heap therefore at seeing a light in +the window, and I suspected as something was wrong. When I got to the +door----" + +"You stopped, and then walked back to the garden gate," my companion +interrupted. "What did you do that for?" + +Rance gave a violent jump, and stared at Sherlock Holmes with the utmost +amazement upon his features. + +"Why, that’s true, sir," he said; "though how you come to know it, +Heaven only knows. Ye see, when I got up to the door it was so still and +so lonesome, that I thought I’d be none the worse for some one with me. +I ain’t afeared of anything on this side o’ the grave; but I thought +that maybe it was him that died o’ the typhoid inspecting the drains +what killed him. The thought gave me a kind o’ turn, and I walked back +to the gate to see if I could see Murcher’s lantern, but there wasn’t no +sign of him nor of anyone else." + +"There was no one in the street?" + +"Not a livin’ soul, sir, nor as much as a dog. Then I pulled myself +together and went back and pushed the door open. All was quiet inside, +so I went into the room where the light was a-burnin’. There was a +candle flickerin’ on the mantelpiece--a red wax one--and by its light I +saw----" + +"Yes, I know all that you saw. You walked round the room several times, +and you knelt down by the body, and then you walked through and tried +the kitchen door, and then----" + +John Rance sprang to his feet with a frightened face and suspicion in +his eyes. "Where was you hid to see all that?" he cried. "It seems to me +that you knows a deal more than you should." + +Holmes laughed and threw his card across the table to the constable. +"Don’t get arresting me for the murder," he said. "I am one of the +hounds and not the wolf; Mr. Gregson or Mr. Lestrade will answer for +that. Go on, though. What did you do next?" + +Rance resumed his seat, without however losing his mystified expression. +"I went back to the gate and sounded my whistle. That brought Murcher +and two more to the spot." + +"Was the street empty then?" + +"Well, it was, as far as anybody that could be of any good goes." + +"What do you mean?" + +The constable’s features broadened into a grin. "I’ve seen many a drunk +chap in my time," he said, "but never anyone so cryin’ drunk as +that cove. He was at the gate when I came out, a-leanin’ up agin the +railings, and a-singin’ at the pitch o’ his lungs about Columbine’s +New-fangled Banner, or some such stuff. He couldn’t stand, far less +help." + +"What sort of a man was he?" asked Sherlock Holmes. + +John Rance appeared to be somewhat irritated at this digression. "He was +an uncommon drunk sort o’ man," he said. "He’d ha’ found hisself in the +station if we hadn’t been so took up." + +"His face--his dress--didn’t you notice them?" Holmes broke in +impatiently. + +"I should think I did notice them, seeing that I had to prop him up--me +and Murcher between us. He was a long chap, with a red face, the lower +part muffled round----" + +"That will do," cried Holmes. "What became of him?" + +"We’d enough to do without lookin’ after him," the policeman said, in an +aggrieved voice. "I’ll wager he found his way home all right." + +"How was he dressed?" + +"A brown overcoat." + +"Had he a whip in his hand?" + +"A whip--no." + +"He must have left it behind," muttered my companion. "You didn’t happen +to see or hear a cab after that?" + +"No." + +"There’s a half-sovereign for you," my companion said, standing up and +taking his hat. "I am afraid, Rance, that you will never rise in the +force. That head of yours should be for use as well as ornament. You +might have gained your sergeant’s stripes last night. The man whom you +held in your hands is the man who holds the clue of this mystery, and +whom we are seeking. There is no use of arguing about it now; I tell you +that it is so. Come along, Doctor." + +We started off for the cab together, leaving our informant incredulous, +but obviously uncomfortable. + +"The blundering fool," Holmes said, bitterly, as we drove back to our +lodgings. "Just to think of his having such an incomparable bit of good +luck, and not taking advantage of it." + +"I am rather in the dark still. It is true that the description of this +man tallies with your idea of the second party in this mystery. But why +should he come back to the house after leaving it? That is not the way +of criminals." + +"The ring, man, the ring: that was what he came back for. If we have no +other way of catching him, we can always bait our line with the ring. I +shall have him, Doctor--I’ll lay you two to one that I have him. I must +thank you for it all. I might not have gone but for you, and so have +missed the finest study I ever came across: a study in scarlet, eh? +Why shouldn’t we use a little art jargon. There’s the scarlet thread of +murder running through the colourless skein of life, and our duty is +to unravel it, and isolate it, and expose every inch of it. And now +for lunch, and then for Norman Neruda. Her attack and her bowing +are splendid. What’s that little thing of Chopin’s she plays so +magnificently: Tra-la-la-lira-lira-lay." + +Leaning back in the cab, this amateur bloodhound carolled away like a +lark while I meditated upon the many-sidedness of the human mind. + + + + +CHAPTER V. OUR ADVERTISEMENT BRINGS A VISITOR. + + +OUR morning’s exertions had been too much for my weak health, and I was +tired out in the afternoon. After Holmes’ departure for the concert, I +lay down upon the sofa and endeavoured to get a couple of hours’ sleep. +It was a useless attempt. My mind had been too much excited by all that +had occurred, and the strangest fancies and surmises crowded into +it. Every time that I closed my eyes I saw before me the distorted +baboon-like countenance of the murdered man. So sinister was the +impression which that face had produced upon me that I found it +difficult to feel anything but gratitude for him who had removed its +owner from the world. If ever human features bespoke vice of the most +malignant type, they were certainly those of Enoch J. Drebber, of +Cleveland. Still I recognized that justice must be done, and that the +depravity of the victim was no condonment [11] in the eyes of the law. + +The more I thought of it the more extraordinary did my companion’s +hypothesis, that the man had been poisoned, appear. I remembered how he +had sniffed his lips, and had no doubt that he had detected something +which had given rise to the idea. Then, again, if not poison, what +had caused the man’s death, since there was neither wound nor marks of +strangulation? But, on the other hand, whose blood was that which lay so +thickly upon the floor? There were no signs of a struggle, nor had the +victim any weapon with which he might have wounded an antagonist. As +long as all these questions were unsolved, I felt that sleep would be +no easy matter, either for Holmes or myself. His quiet self-confident +manner convinced me that he had already formed a theory which explained +all the facts, though what it was I could not for an instant conjecture. + +He was very late in returning--so late, that I knew that the concert +could not have detained him all the time. Dinner was on the table before +he appeared. + +"It was magnificent," he said, as he took his seat. "Do you remember +what Darwin says about music? He claims that the power of producing and +appreciating it existed among the human race long before the power of +speech was arrived at. Perhaps that is why we are so subtly influenced +by it. There are vague memories in our souls of those misty centuries +when the world was in its childhood." + +"That’s rather a broad idea," I remarked. + +"One’s ideas must be as broad as Nature if they are to interpret +Nature," he answered. "What’s the matter? You’re not looking quite +yourself. This Brixton Road affair has upset you." + +"To tell the truth, it has," I said. "I ought to be more case-hardened +after my Afghan experiences. I saw my own comrades hacked to pieces at +Maiwand without losing my nerve." + +"I can understand. There is a mystery about this which stimulates the +imagination; where there is no imagination there is no horror. Have you +seen the evening paper?" + +"No." + +"It gives a fairly good account of the affair. It does not mention the +fact that when the man was raised up, a woman’s wedding ring fell upon +the floor. It is just as well it does not." + +"Why?" + +"Look at this advertisement," he answered. "I had one sent to every +paper this morning immediately after the affair." + +He threw the paper across to me and I glanced at the place indicated. It +was the first announcement in the "Found" column. "In Brixton Road, +this morning," it ran, "a plain gold wedding ring, found in the roadway +between the ‘White Hart’ Tavern and Holland Grove. Apply Dr. Watson, +221B, Baker Street, between eight and nine this evening." + +"Excuse my using your name," he said. "If I used my own some of these +dunderheads would recognize it, and want to meddle in the affair." + +"That is all right," I answered. "But supposing anyone applies, I have +no ring." + +"Oh yes, you have," said he, handing me one. "This will do very well. It +is almost a facsimile." + +"And who do you expect will answer this advertisement." + +"Why, the man in the brown coat--our florid friend with the square toes. +If he does not come himself he will send an accomplice." + +"Would he not consider it as too dangerous?" + +"Not at all. If my view of the case is correct, and I have every reason +to believe that it is, this man would rather risk anything than lose the +ring. According to my notion he dropped it while stooping over Drebber’s +body, and did not miss it at the time. After leaving the house he +discovered his loss and hurried back, but found the police already in +possession, owing to his own folly in leaving the candle burning. He had +to pretend to be drunk in order to allay the suspicions which might have +been aroused by his appearance at the gate. Now put yourself in that +man’s place. On thinking the matter over, it must have occurred to him +that it was possible that he had lost the ring in the road after leaving +the house. What would he do, then? He would eagerly look out for the +evening papers in the hope of seeing it among the articles found. His +eye, of course, would light upon this. He would be overjoyed. Why should +he fear a trap? There would be no reason in his eyes why the finding +of the ring should be connected with the murder. He would come. He will +come. You shall see him within an hour?" + +"And then?" I asked. + +"Oh, you can leave me to deal with him then. Have you any arms?" + +"I have my old service revolver and a few cartridges." + +"You had better clean it and load it. He will be a desperate man, +and though I shall take him unawares, it is as well to be ready for +anything." + +I went to my bedroom and followed his advice. When I returned with +the pistol the table had been cleared, and Holmes was engaged in his +favourite occupation of scraping upon his violin. + +"The plot thickens," he said, as I entered; "I have just had an answer +to my American telegram. My view of the case is the correct one." + +"And that is?" I asked eagerly. + +"My fiddle would be the better for new strings," he remarked. "Put your +pistol in your pocket. When the fellow comes speak to him in an ordinary +way. Leave the rest to me. Don’t frighten him by looking at him too +hard." + +"It is eight o’clock now," I said, glancing at my watch. + +"Yes. He will probably be here in a few minutes. Open the door slightly. +That will do. Now put the key on the inside. Thank you! This is a +queer old book I picked up at a stall yesterday--‘De Jure inter +Gentes’--published in Latin at Liege in the Lowlands, in 1642. Charles’ +head was still firm on his shoulders when this little brown-backed +volume was struck off." + +"Who is the printer?" + +"Philippe de Croy, whoever he may have been. On the fly-leaf, in very +faded ink, is written ‘Ex libris Guliolmi Whyte.’ I wonder who William +Whyte was. Some pragmatical seventeenth century lawyer, I suppose. His +writing has a legal twist about it. Here comes our man, I think." + +As he spoke there was a sharp ring at the bell. Sherlock Holmes rose +softly and moved his chair in the direction of the door. We heard the +servant pass along the hall, and the sharp click of the latch as she +opened it. + +"Does Dr. Watson live here?" asked a clear but rather harsh voice. We +could not hear the servant’s reply, but the door closed, and some one +began to ascend the stairs. The footfall was an uncertain and shuffling +one. A look of surprise passed over the face of my companion as he +listened to it. It came slowly along the passage, and there was a feeble +tap at the door. + +"Come in," I cried. + +At my summons, instead of the man of violence whom we expected, a very +old and wrinkled woman hobbled into the apartment. She appeared to be +dazzled by the sudden blaze of light, and after dropping a curtsey, she +stood blinking at us with her bleared eyes and fumbling in her pocket +with nervous, shaky fingers. I glanced at my companion, and his face +had assumed such a disconsolate expression that it was all I could do to +keep my countenance. + +The old crone drew out an evening paper, and pointed at our +advertisement. "It’s this as has brought me, good gentlemen," she said, +dropping another curtsey; "a gold wedding ring in the Brixton Road. It +belongs to my girl Sally, as was married only this time twelvemonth, +which her husband is steward aboard a Union boat, and what he’d say if +he come ‘ome and found her without her ring is more than I can think, he +being short enough at the best o’ times, but more especially when he +has the drink. If it please you, she went to the circus last night along +with----" + +"Is that her ring?" I asked. + +"The Lord be thanked!" cried the old woman; "Sally will be a glad woman +this night. That’s the ring." + +"And what may your address be?" I inquired, taking up a pencil. + +"13, Duncan Street, Houndsditch. A weary way from here." + +"The Brixton Road does not lie between any circus and Houndsditch," said +Sherlock Holmes sharply. + +The old woman faced round and looked keenly at him from her little +red-rimmed eyes. "The gentleman asked me for _my_ address," she said. +"Sally lives in lodgings at 3, Mayfield Place, Peckham." + +"And your name is----?" + +"My name is Sawyer--her’s is Dennis, which Tom Dennis married her--and +a smart, clean lad, too, as long as he’s at sea, and no steward in the +company more thought of; but when on shore, what with the women and what +with liquor shops----" + +"Here is your ring, Mrs. Sawyer," I interrupted, in obedience to a sign +from my companion; "it clearly belongs to your daughter, and I am glad +to be able to restore it to the rightful owner." + +With many mumbled blessings and protestations of gratitude the old crone +packed it away in her pocket, and shuffled off down the stairs. Sherlock +Holmes sprang to his feet the moment that she was gone and rushed into +his room. He returned in a few seconds enveloped in an ulster and +a cravat. "I’ll follow her," he said, hurriedly; "she must be an +accomplice, and will lead me to him. Wait up for me." The hall door had +hardly slammed behind our visitor before Holmes had descended the stair. +Looking through the window I could see her walking feebly along the +other side, while her pursuer dogged her some little distance behind. +"Either his whole theory is incorrect," I thought to myself, "or else he +will be led now to the heart of the mystery." There was no need for him +to ask me to wait up for him, for I felt that sleep was impossible until +I heard the result of his adventure. + +It was close upon nine when he set out. I had no idea how long he might +be, but I sat stolidly puffing at my pipe and skipping over the pages +of Henri Murger’s "Vie de Bohème." Ten o’clock passed, and I heard the +footsteps of the maid as they pattered off to bed. Eleven, and the +more stately tread of the landlady passed my door, bound for the same +destination. It was close upon twelve before I heard the sharp sound of +his latch-key. The instant he entered I saw by his face that he had not +been successful. Amusement and chagrin seemed to be struggling for the +mastery, until the former suddenly carried the day, and he burst into a +hearty laugh. + +"I wouldn’t have the Scotland Yarders know it for the world," he cried, +dropping into his chair; "I have chaffed them so much that they would +never have let me hear the end of it. I can afford to laugh, because I +know that I will be even with them in the long run." + +"What is it then?" I asked. + +"Oh, I don’t mind telling a story against myself. That creature had +gone a little way when she began to limp and show every sign of being +foot-sore. Presently she came to a halt, and hailed a four-wheeler which +was passing. I managed to be close to her so as to hear the address, but +I need not have been so anxious, for she sang it out loud enough to +be heard at the other side of the street, ‘Drive to 13, Duncan Street, +Houndsditch,’ she cried. This begins to look genuine, I thought, and +having seen her safely inside, I perched myself behind. That’s an art +which every detective should be an expert at. Well, away we rattled, and +never drew rein until we reached the street in question. I hopped off +before we came to the door, and strolled down the street in an easy, +lounging way. I saw the cab pull up. The driver jumped down, and I saw +him open the door and stand expectantly. Nothing came out though. When +I reached him he was groping about frantically in the empty cab, and +giving vent to the finest assorted collection of oaths that ever I +listened to. There was no sign or trace of his passenger, and I fear it +will be some time before he gets his fare. On inquiring at Number 13 +we found that the house belonged to a respectable paperhanger, named +Keswick, and that no one of the name either of Sawyer or Dennis had ever +been heard of there." + +"You don’t mean to say," I cried, in amazement, "that that tottering, +feeble old woman was able to get out of the cab while it was in motion, +without either you or the driver seeing her?" + +"Old woman be damned!" said Sherlock Holmes, sharply. "We were the old +women to be so taken in. It must have been a young man, and an +active one, too, besides being an incomparable actor. The get-up was +inimitable. He saw that he was followed, no doubt, and used this means +of giving me the slip. It shows that the man we are after is not as +lonely as I imagined he was, but has friends who are ready to risk +something for him. Now, Doctor, you are looking done-up. Take my advice +and turn in." + +I was certainly feeling very weary, so I obeyed his injunction. I +left Holmes seated in front of the smouldering fire, and long into the +watches of the night I heard the low, melancholy wailings of his violin, +and knew that he was still pondering over the strange problem which he +had set himself to unravel. + + + + +CHAPTER VI. TOBIAS GREGSON SHOWS WHAT HE CAN DO. + + +THE papers next day were full of the "Brixton Mystery," as they termed +it. Each had a long account of the affair, and some had leaders upon it +in addition. There was some information in them which was new to me. I +still retain in my scrap-book numerous clippings and extracts bearing +upon the case. Here is a condensation of a few of them:-- + +The _Daily Telegraph_ remarked that in the history of crime there had +seldom been a tragedy which presented stranger features. The German +name of the victim, the absence of all other motive, and the sinister +inscription on the wall, all pointed to its perpetration by political +refugees and revolutionists. The Socialists had many branches in +America, and the deceased had, no doubt, infringed their unwritten laws, +and been tracked down by them. After alluding airily to the Vehmgericht, +aqua tofana, Carbonari, the Marchioness de Brinvilliers, the Darwinian +theory, the principles of Malthus, and the Ratcliff Highway murders, the +article concluded by admonishing the Government and advocating a closer +watch over foreigners in England. + +The _Standard_ commented upon the fact that lawless outrages of the sort +usually occurred under a Liberal Administration. They arose from the +unsettling of the minds of the masses, and the consequent weakening +of all authority. The deceased was an American gentleman who had +been residing for some weeks in the Metropolis. He had stayed at the +boarding-house of Madame Charpentier, in Torquay Terrace, Camberwell. +He was accompanied in his travels by his private secretary, Mr. Joseph +Stangerson. The two bade adieu to their landlady upon Tuesday, the +4th inst., and departed to Euston Station with the avowed intention of +catching the Liverpool express. They were afterwards seen together upon +the platform. Nothing more is known of them until Mr. Drebber’s body +was, as recorded, discovered in an empty house in the Brixton Road, +many miles from Euston. How he came there, or how he met his fate, are +questions which are still involved in mystery. Nothing is known of the +whereabouts of Stangerson. We are glad to learn that Mr. Lestrade and +Mr. Gregson, of Scotland Yard, are both engaged upon the case, and it +is confidently anticipated that these well-known officers will speedily +throw light upon the matter. + +The _Daily News_ observed that there was no doubt as to the crime being +a political one. The despotism and hatred of Liberalism which animated +the Continental Governments had had the effect of driving to our shores +a number of men who might have made excellent citizens were they not +soured by the recollection of all that they had undergone. Among these +men there was a stringent code of honour, any infringement of which was +punished by death. Every effort should be made to find the secretary, +Stangerson, and to ascertain some particulars of the habits of the +deceased. A great step had been gained by the discovery of the address +of the house at which he had boarded--a result which was entirely due to +the acuteness and energy of Mr. Gregson of Scotland Yard. + +Sherlock Holmes and I read these notices over together at breakfast, and +they appeared to afford him considerable amusement. + +"I told you that, whatever happened, Lestrade and Gregson would be sure +to score." + +"That depends on how it turns out." + +"Oh, bless you, it doesn’t matter in the least. If the man is caught, it +will be _on account_ of their exertions; if he escapes, it will be _in +spite_ of their exertions. It’s heads I win and tails you lose. Whatever +they do, they will have followers. ‘Un sot trouve toujours un plus sot +qui l’admire.’" + +"What on earth is this?" I cried, for at this moment there came the +pattering of many steps in the hall and on the stairs, accompanied by +audible expressions of disgust upon the part of our landlady. + +"It’s the Baker Street division of the detective police force," said my +companion, gravely; and as he spoke there rushed into the room half a +dozen of the dirtiest and most ragged street Arabs that ever I clapped +eyes on. + +"‘Tention!" cried Holmes, in a sharp tone, and the six dirty little +scoundrels stood in a line like so many disreputable statuettes. "In +future you shall send up Wiggins alone to report, and the rest of you +must wait in the street. Have you found it, Wiggins?" + +"No, sir, we hain’t," said one of the youths. + +"I hardly expected you would. You must keep on until you do. Here are +your wages." [13] He handed each of them a shilling. + +"Now, off you go, and come back with a better report next time." + +He waved his hand, and they scampered away downstairs like so many rats, +and we heard their shrill voices next moment in the street. + +"There’s more work to be got out of one of those little beggars than +out of a dozen of the force," Holmes remarked. "The mere sight of an +official-looking person seals men’s lips. These youngsters, however, go +everywhere and hear everything. They are as sharp as needles, too; all +they want is organisation." + +"Is it on this Brixton case that you are employing them?" I asked. + +"Yes; there is a point which I wish to ascertain. It is merely a matter +of time. Hullo! we are going to hear some news now with a vengeance! +Here is Gregson coming down the road with beatitude written upon every +feature of his face. Bound for us, I know. Yes, he is stopping. There he +is!" + +There was a violent peal at the bell, and in a few seconds the +fair-haired detective came up the stairs, three steps at a time, and +burst into our sitting-room. + +"My dear fellow," he cried, wringing Holmes’ unresponsive hand, +"congratulate me! I have made the whole thing as clear as day." + +A shade of anxiety seemed to me to cross my companion’s expressive face. + +"Do you mean that you are on the right track?" he asked. + +"The right track! Why, sir, we have the man under lock and key." + +"And his name is?" + +"Arthur Charpentier, sub-lieutenant in Her Majesty’s navy," cried +Gregson, pompously, rubbing his fat hands and inflating his chest. + +Sherlock Holmes gave a sigh of relief, and relaxed into a smile. + +"Take a seat, and try one of these cigars," he said. "We are anxious to +know how you managed it. Will you have some whiskey and water?" + +"I don’t mind if I do," the detective answered. "The tremendous +exertions which I have gone through during the last day or two have worn +me out. Not so much bodily exertion, you understand, as the strain upon +the mind. You will appreciate that, Mr. Sherlock Holmes, for we are both +brain-workers." + +"You do me too much honour," said Holmes, gravely. "Let us hear how you +arrived at this most gratifying result." + +The detective seated himself in the arm-chair, and puffed complacently +at his cigar. Then suddenly he slapped his thigh in a paroxysm of +amusement. + +"The fun of it is," he cried, "that that fool Lestrade, who thinks +himself so smart, has gone off upon the wrong track altogether. He is +after the secretary Stangerson, who had no more to do with the crime +than the babe unborn. I have no doubt that he has caught him by this +time." + +The idea tickled Gregson so much that he laughed until he choked. + +"And how did you get your clue?" + +"Ah, I’ll tell you all about it. Of course, Doctor Watson, this is +strictly between ourselves. The first difficulty which we had to contend +with was the finding of this American’s antecedents. Some people would +have waited until their advertisements were answered, or until parties +came forward and volunteered information. That is not Tobias Gregson’s +way of going to work. You remember the hat beside the dead man?" + +"Yes," said Holmes; "by John Underwood and Sons, 129, Camberwell Road." + +Gregson looked quite crest-fallen. + +"I had no idea that you noticed that," he said. "Have you been there?" + +"No." + +"Ha!" cried Gregson, in a relieved voice; "you should never neglect a +chance, however small it may seem." + +"To a great mind, nothing is little," remarked Holmes, sententiously. + +"Well, I went to Underwood, and asked him if he had sold a hat of that +size and description. He looked over his books, and came on it at once. +He had sent the hat to a Mr. Drebber, residing at Charpentier’s Boarding +Establishment, Torquay Terrace. Thus I got at his address." + +"Smart--very smart!" murmured Sherlock Holmes. + +"I next called upon Madame Charpentier," continued the detective. +"I found her very pale and distressed. Her daughter was in the room, +too--an uncommonly fine girl she is, too; she was looking red about +the eyes and her lips trembled as I spoke to her. That didn’t escape +my notice. I began to smell a rat. You know the feeling, Mr. Sherlock +Holmes, when you come upon the right scent--a kind of thrill in your +nerves. ‘Have you heard of the mysterious death of your late boarder Mr. +Enoch J. Drebber, of Cleveland?’ I asked. + +"The mother nodded. She didn’t seem able to get out a word. The daughter +burst into tears. I felt more than ever that these people knew something +of the matter. + +"‘At what o’clock did Mr. Drebber leave your house for the train?’ I +asked. + +"‘At eight o’clock,’ she said, gulping in her throat to keep down her +agitation. ‘His secretary, Mr. Stangerson, said that there were two +trains--one at 9.15 and one at 11. He was to catch the first. [14] + +"‘And was that the last which you saw of him?’ + +"A terrible change came over the woman’s face as I asked the question. +Her features turned perfectly livid. It was some seconds before she +could get out the single word ‘Yes’--and when it did come it was in a +husky unnatural tone. + +"There was silence for a moment, and then the daughter spoke in a calm +clear voice. + +"‘No good can ever come of falsehood, mother,’ she said. ‘Let us be +frank with this gentleman. We _did_ see Mr. Drebber again.’ + +"‘God forgive you!’ cried Madame Charpentier, throwing up her hands and +sinking back in her chair. ‘You have murdered your brother.’ + +"‘Arthur would rather that we spoke the truth,’ the girl answered +firmly. + +"‘You had best tell me all about it now,’ I said. ‘Half-confidences are +worse than none. Besides, you do not know how much we know of it.’ + +"‘On your head be it, Alice!’ cried her mother; and then, turning to me, +‘I will tell you all, sir. Do not imagine that my agitation on behalf +of my son arises from any fear lest he should have had a hand in this +terrible affair. He is utterly innocent of it. My dread is, however, +that in your eyes and in the eyes of others he may appear to be +compromised. That however is surely impossible. His high character, his +profession, his antecedents would all forbid it.’ + +"‘Your best way is to make a clean breast of the facts,’ I answered. +‘Depend upon it, if your son is innocent he will be none the worse.’ + +"‘Perhaps, Alice, you had better leave us together,’ she said, and her +daughter withdrew. ‘Now, sir,’ she continued, ‘I had no intention of +telling you all this, but since my poor daughter has disclosed it I +have no alternative. Having once decided to speak, I will tell you all +without omitting any particular.’ + +"‘It is your wisest course,’ said I. + +"‘Mr. Drebber has been with us nearly three weeks. He and his secretary, +Mr. Stangerson, had been travelling on the Continent. I noticed a +"Copenhagen" label upon each of their trunks, showing that that had been +their last stopping place. Stangerson was a quiet reserved man, but his +employer, I am sorry to say, was far otherwise. He was coarse in his +habits and brutish in his ways. The very night of his arrival he became +very much the worse for drink, and, indeed, after twelve o’clock in the +day he could hardly ever be said to be sober. His manners towards the +maid-servants were disgustingly free and familiar. Worst of all, he +speedily assumed the same attitude towards my daughter, Alice, and spoke +to her more than once in a way which, fortunately, she is too innocent +to understand. On one occasion he actually seized her in his arms and +embraced her--an outrage which caused his own secretary to reproach him +for his unmanly conduct.’ + +"‘But why did you stand all this,’ I asked. ‘I suppose that you can get +rid of your boarders when you wish.’ + +"Mrs. Charpentier blushed at my pertinent question. ‘Would to God that +I had given him notice on the very day that he came,’ she said. ‘But +it was a sore temptation. They were paying a pound a day each--fourteen +pounds a week, and this is the slack season. I am a widow, and my boy in +the Navy has cost me much. I grudged to lose the money. I acted for the +best. This last was too much, however, and I gave him notice to leave on +account of it. That was the reason of his going.’ + +"‘Well?’ + +"‘My heart grew light when I saw him drive away. My son is on leave +just now, but I did not tell him anything of all this, for his temper +is violent, and he is passionately fond of his sister. When I closed the +door behind them a load seemed to be lifted from my mind. Alas, in +less than an hour there was a ring at the bell, and I learned that Mr. +Drebber had returned. He was much excited, and evidently the worse for +drink. He forced his way into the room, where I was sitting with my +daughter, and made some incoherent remark about having missed his train. +He then turned to Alice, and before my very face, proposed to her that +she should fly with him. "You are of age," he said, "and there is no law +to stop you. I have money enough and to spare. Never mind the old girl +here, but come along with me now straight away. You shall live like a +princess." Poor Alice was so frightened that she shrunk away from him, +but he caught her by the wrist and endeavoured to draw her towards the +door. I screamed, and at that moment my son Arthur came into the room. +What happened then I do not know. I heard oaths and the confused sounds +of a scuffle. I was too terrified to raise my head. When I did look up +I saw Arthur standing in the doorway laughing, with a stick in his hand. +"I don’t think that fine fellow will trouble us again," he said. "I will +just go after him and see what he does with himself." With those words +he took his hat and started off down the street. The next morning we +heard of Mr. Drebber’s mysterious death.’ + +"This statement came from Mrs. Charpentier’s lips with many gasps and +pauses. At times she spoke so low that I could hardly catch the words. I +made shorthand notes of all that she said, however, so that there should +be no possibility of a mistake." + +"It’s quite exciting," said Sherlock Holmes, with a yawn. "What happened +next?" + +"When Mrs. Charpentier paused," the detective continued, "I saw that the +whole case hung upon one point. Fixing her with my eye in a way which +I always found effective with women, I asked her at what hour her son +returned. + +"‘I do not know,’ she answered. + +"‘Not know?’ + +"‘No; he has a latch-key, and he let himself in.’ + +"‘After you went to bed?’ + +"‘Yes.’ + +"‘When did you go to bed?’ + +"‘About eleven.’ + +"‘So your son was gone at least two hours?’ + +"‘Yes.’ + +"‘Possibly four or five?’ + +"‘Yes.’ + +"‘What was he doing during that time?’ + +"‘I do not know,’ she answered, turning white to her very lips. + +"Of course after that there was nothing more to be done. I found +out where Lieutenant Charpentier was, took two officers with me, and +arrested him. When I touched him on the shoulder and warned him to come +quietly with us, he answered us as bold as brass, ‘I suppose you +are arresting me for being concerned in the death of that scoundrel +Drebber,’ he said. We had said nothing to him about it, so that his +alluding to it had a most suspicious aspect." + +"Very," said Holmes. + +"He still carried the heavy stick which the mother described him as +having with him when he followed Drebber. It was a stout oak cudgel." + +"What is your theory, then?" + +"Well, my theory is that he followed Drebber as far as the Brixton Road. +When there, a fresh altercation arose between them, in the course of +which Drebber received a blow from the stick, in the pit of the stomach, +perhaps, which killed him without leaving any mark. The night was so +wet that no one was about, so Charpentier dragged the body of his victim +into the empty house. As to the candle, and the blood, and the writing +on the wall, and the ring, they may all be so many tricks to throw the +police on to the wrong scent." + +"Well done!" said Holmes in an encouraging voice. "Really, Gregson, you +are getting along. We shall make something of you yet." + +"I flatter myself that I have managed it rather neatly," the detective +answered proudly. "The young man volunteered a statement, in which he +said that after following Drebber some time, the latter perceived him, +and took a cab in order to get away from him. On his way home he met an +old shipmate, and took a long walk with him. On being asked where this +old shipmate lived, he was unable to give any satisfactory reply. I +think the whole case fits together uncommonly well. What amuses me is to +think of Lestrade, who had started off upon the wrong scent. I am afraid +he won’t make much of [15] Why, by Jove, here’s the very man himself!" + +It was indeed Lestrade, who had ascended the stairs while we were +talking, and who now entered the room. The assurance and jauntiness +which generally marked his demeanour and dress were, however, wanting. +His face was disturbed and troubled, while his clothes were disarranged +and untidy. He had evidently come with the intention of consulting +with Sherlock Holmes, for on perceiving his colleague he appeared to be +embarrassed and put out. He stood in the centre of the room, fumbling +nervously with his hat and uncertain what to do. "This is a most +extraordinary case," he said at last--"a most incomprehensible affair." + +"Ah, you find it so, Mr. Lestrade!" cried Gregson, triumphantly. "I +thought you would come to that conclusion. Have you managed to find the +Secretary, Mr. Joseph Stangerson?" + +"The Secretary, Mr. Joseph Stangerson," said Lestrade gravely, "was +murdered at Halliday’s Private Hotel about six o’clock this morning." + + + + +CHAPTER VII. LIGHT IN THE DARKNESS. + + +THE intelligence with which Lestrade greeted us was so momentous and so +unexpected, that we were all three fairly dumfoundered. Gregson sprang +out of his chair and upset the remainder of his whiskey and water. I +stared in silence at Sherlock Holmes, whose lips were compressed and his +brows drawn down over his eyes. + +"Stangerson too!" he muttered. "The plot thickens." + +"It was quite thick enough before," grumbled Lestrade, taking a chair. +"I seem to have dropped into a sort of council of war." + +"Are you--are you sure of this piece of intelligence?" stammered +Gregson. + +"I have just come from his room," said Lestrade. "I was the first to +discover what had occurred." + +"We have been hearing Gregson’s view of the matter," Holmes observed. +"Would you mind letting us know what you have seen and done?" + +"I have no objection," Lestrade answered, seating himself. "I freely +confess that I was of the opinion that Stangerson was concerned in +the death of Drebber. This fresh development has shown me that I was +completely mistaken. Full of the one idea, I set myself to find out +what had become of the Secretary. They had been seen together at Euston +Station about half-past eight on the evening of the third. At two in the +morning Drebber had been found in the Brixton Road. The question which +confronted me was to find out how Stangerson had been employed between +8.30 and the time of the crime, and what had become of him afterwards. +I telegraphed to Liverpool, giving a description of the man, and warning +them to keep a watch upon the American boats. I then set to work calling +upon all the hotels and lodging-houses in the vicinity of Euston. You +see, I argued that if Drebber and his companion had become separated, +the natural course for the latter would be to put up somewhere in the +vicinity for the night, and then to hang about the station again next +morning." + +"They would be likely to agree on some meeting-place beforehand," + remarked Holmes. + +"So it proved. I spent the whole of yesterday evening in making +enquiries entirely without avail. This morning I began very early, and +at eight o’clock I reached Halliday’s Private Hotel, in Little George +Street. On my enquiry as to whether a Mr. Stangerson was living there, +they at once answered me in the affirmative. + +"‘No doubt you are the gentleman whom he was expecting,’ they said. ‘He +has been waiting for a gentleman for two days.’ + +"‘Where is he now?’ I asked. + +"‘He is upstairs in bed. He wished to be called at nine.’ + +"‘I will go up and see him at once,’ I said. + +"It seemed to me that my sudden appearance might shake his nerves and +lead him to say something unguarded. The Boots volunteered to show me +the room: it was on the second floor, and there was a small corridor +leading up to it. The Boots pointed out the door to me, and was about to +go downstairs again when I saw something that made me feel sickish, in +spite of my twenty years’ experience. From under the door there curled +a little red ribbon of blood, which had meandered across the passage and +formed a little pool along the skirting at the other side. I gave a cry, +which brought the Boots back. He nearly fainted when he saw it. The door +was locked on the inside, but we put our shoulders to it, and knocked it +in. The window of the room was open, and beside the window, all huddled +up, lay the body of a man in his nightdress. He was quite dead, and had +been for some time, for his limbs were rigid and cold. When we turned +him over, the Boots recognized him at once as being the same gentleman +who had engaged the room under the name of Joseph Stangerson. The cause +of death was a deep stab in the left side, which must have penetrated +the heart. And now comes the strangest part of the affair. What do you +suppose was above the murdered man?" + +I felt a creeping of the flesh, and a presentiment of coming horror, +even before Sherlock Holmes answered. + +"The word RACHE, written in letters of blood," he said. + +"That was it," said Lestrade, in an awe-struck voice; and we were all +silent for a while. + +There was something so methodical and so incomprehensible about the +deeds of this unknown assassin, that it imparted a fresh ghastliness to +his crimes. My nerves, which were steady enough on the field of battle +tingled as I thought of it. + +"The man was seen," continued Lestrade. "A milk boy, passing on his way +to the dairy, happened to walk down the lane which leads from the mews +at the back of the hotel. He noticed that a ladder, which usually lay +there, was raised against one of the windows of the second floor, which +was wide open. After passing, he looked back and saw a man descend the +ladder. He came down so quietly and openly that the boy imagined him to +be some carpenter or joiner at work in the hotel. He took no particular +notice of him, beyond thinking in his own mind that it was early for him +to be at work. He has an impression that the man was tall, had a reddish +face, and was dressed in a long, brownish coat. He must have stayed in +the room some little time after the murder, for we found blood-stained +water in the basin, where he had washed his hands, and marks on the +sheets where he had deliberately wiped his knife." + +I glanced at Holmes on hearing the description of the murderer, which +tallied so exactly with his own. There was, however, no trace of +exultation or satisfaction upon his face. + +"Did you find nothing in the room which could furnish a clue to the +murderer?" he asked. + +"Nothing. Stangerson had Drebber’s purse in his pocket, but it seems +that this was usual, as he did all the paying. There was eighty odd +pounds in it, but nothing had been taken. Whatever the motives of these +extraordinary crimes, robbery is certainly not one of them. There were +no papers or memoranda in the murdered man’s pocket, except a single +telegram, dated from Cleveland about a month ago, and containing +the words, ‘J. H. is in Europe.’ There was no name appended to this +message." + +"And there was nothing else?" Holmes asked. + +"Nothing of any importance. The man’s novel, with which he had read +himself to sleep was lying upon the bed, and his pipe was on a chair +beside him. There was a glass of water on the table, and on the +window-sill a small chip ointment box containing a couple of pills." + +Sherlock Holmes sprang from his chair with an exclamation of delight. + +"The last link," he cried, exultantly. "My case is complete." + +The two detectives stared at him in amazement. + +"I have now in my hands," my companion said, confidently, "all the +threads which have formed such a tangle. There are, of course, details +to be filled in, but I am as certain of all the main facts, from the +time that Drebber parted from Stangerson at the station, up to the +discovery of the body of the latter, as if I had seen them with my own +eyes. I will give you a proof of my knowledge. Could you lay your hand +upon those pills?" + +"I have them," said Lestrade, producing a small white box; "I took them +and the purse and the telegram, intending to have them put in a place of +safety at the Police Station. It was the merest chance my taking these +pills, for I am bound to say that I do not attach any importance to +them." + +"Give them here," said Holmes. "Now, Doctor," turning to me, "are those +ordinary pills?" + +They certainly were not. They were of a pearly grey colour, small, +round, and almost transparent against the light. "From their lightness +and transparency, I should imagine that they are soluble in water," I +remarked. + +"Precisely so," answered Holmes. "Now would you mind going down and +fetching that poor little devil of a terrier which has been bad so long, +and which the landlady wanted you to put out of its pain yesterday." + +I went downstairs and carried the dog upstair in my arms. It’s laboured +breathing and glazing eye showed that it was not far from its end. +Indeed, its snow-white muzzle proclaimed that it had already exceeded +the usual term of canine existence. I placed it upon a cushion on the +rug. + +"I will now cut one of these pills in two," said Holmes, and drawing his +penknife he suited the action to the word. "One half we return into the +box for future purposes. The other half I will place in this wine glass, +in which is a teaspoonful of water. You perceive that our friend, the +Doctor, is right, and that it readily dissolves." + +"This may be very interesting," said Lestrade, in the injured tone of +one who suspects that he is being laughed at, "I cannot see, however, +what it has to do with the death of Mr. Joseph Stangerson." + +"Patience, my friend, patience! You will find in time that it has +everything to do with it. I shall now add a little milk to make the +mixture palatable, and on presenting it to the dog we find that he laps +it up readily enough." + +As he spoke he turned the contents of the wine glass into a saucer and +placed it in front of the terrier, who speedily licked it dry. Sherlock +Holmes’ earnest demeanour had so far convinced us that we all sat in +silence, watching the animal intently, and expecting some startling +effect. None such appeared, however. The dog continued to lie stretched +upon tho [16] cushion, breathing in a laboured way, but apparently +neither the better nor the worse for its draught. + +Holmes had taken out his watch, and as minute followed minute without +result, an expression of the utmost chagrin and disappointment appeared +upon his features. He gnawed his lip, drummed his fingers upon the +table, and showed every other symptom of acute impatience. So great +was his emotion, that I felt sincerely sorry for him, while the two +detectives smiled derisively, by no means displeased at this check which +he had met. + +"It can’t be a coincidence," he cried, at last springing from his chair +and pacing wildly up and down the room; "it is impossible that it should +be a mere coincidence. The very pills which I suspected in the case of +Drebber are actually found after the death of Stangerson. And yet they +are inert. What can it mean? Surely my whole chain of reasoning cannot +have been false. It is impossible! And yet this wretched dog is none the +worse. Ah, I have it! I have it!" With a perfect shriek of delight he +rushed to the box, cut the other pill in two, dissolved it, added milk, +and presented it to the terrier. The unfortunate creature’s tongue +seemed hardly to have been moistened in it before it gave a convulsive +shiver in every limb, and lay as rigid and lifeless as if it had been +struck by lightning. + +Sherlock Holmes drew a long breath, and wiped the perspiration from his +forehead. "I should have more faith," he said; "I ought to know by +this time that when a fact appears to be opposed to a long train of +deductions, it invariably proves to be capable of bearing some other +interpretation. Of the two pills in that box one was of the most deadly +poison, and the other was entirely harmless. I ought to have known that +before ever I saw the box at all." + +This last statement appeared to me to be so startling, that I could +hardly believe that he was in his sober senses. There was the dead dog, +however, to prove that his conjecture had been correct. It seemed to me +that the mists in my own mind were gradually clearing away, and I began +to have a dim, vague perception of the truth. + +"All this seems strange to you," continued Holmes, "because you failed +at the beginning of the inquiry to grasp the importance of the single +real clue which was presented to you. I had the good fortune to seize +upon that, and everything which has occurred since then has served to +confirm my original supposition, and, indeed, was the logical sequence +of it. Hence things which have perplexed you and made the case more +obscure, have served to enlighten me and to strengthen my conclusions. +It is a mistake to confound strangeness with mystery. The most +commonplace crime is often the most mysterious because it presents no +new or special features from which deductions may be drawn. This murder +would have been infinitely more difficult to unravel had the body of +the victim been simply found lying in the roadway without any of +those _outré_ and sensational accompaniments which have rendered +it remarkable. These strange details, far from making the case more +difficult, have really had the effect of making it less so." + +Mr. Gregson, who had listened to this address with considerable +impatience, could contain himself no longer. "Look here, Mr. Sherlock +Holmes," he said, "we are all ready to acknowledge that you are a smart +man, and that you have your own methods of working. We want something +more than mere theory and preaching now, though. It is a case of taking +the man. I have made my case out, and it seems I was wrong. Young +Charpentier could not have been engaged in this second affair. Lestrade +went after his man, Stangerson, and it appears that he was wrong too. +You have thrown out hints here, and hints there, and seem to know more +than we do, but the time has come when we feel that we have a right to +ask you straight how much you do know of the business. Can you name the +man who did it?" + +"I cannot help feeling that Gregson is right, sir," remarked Lestrade. +"We have both tried, and we have both failed. You have remarked more +than once since I have been in the room that you had all the evidence +which you require. Surely you will not withhold it any longer." + +"Any delay in arresting the assassin," I observed, "might give him time +to perpetrate some fresh atrocity." + +Thus pressed by us all, Holmes showed signs of irresolution. He +continued to walk up and down the room with his head sunk on his chest +and his brows drawn down, as was his habit when lost in thought. + +"There will be no more murders," he said at last, stopping abruptly and +facing us. "You can put that consideration out of the question. You have +asked me if I know the name of the assassin. I do. The mere knowing of +his name is a small thing, however, compared with the power of laying +our hands upon him. This I expect very shortly to do. I have good hopes +of managing it through my own arrangements; but it is a thing which +needs delicate handling, for we have a shrewd and desperate man to deal +with, who is supported, as I have had occasion to prove, by another who +is as clever as himself. As long as this man has no idea that anyone +can have a clue there is some chance of securing him; but if he had the +slightest suspicion, he would change his name, and vanish in an instant +among the four million inhabitants of this great city. Without meaning +to hurt either of your feelings, I am bound to say that I consider these +men to be more than a match for the official force, and that is why I +have not asked your assistance. If I fail I shall, of course, incur all +the blame due to this omission; but that I am prepared for. At present +I am ready to promise that the instant that I can communicate with you +without endangering my own combinations, I shall do so." + +Gregson and Lestrade seemed to be far from satisfied by this assurance, +or by the depreciating allusion to the detective police. The former had +flushed up to the roots of his flaxen hair, while the other’s beady eyes +glistened with curiosity and resentment. Neither of them had time to +speak, however, before there was a tap at the door, and the spokesman +of the street Arabs, young Wiggins, introduced his insignificant and +unsavoury person. + +"Please, sir," he said, touching his forelock, "I have the cab +downstairs." + +"Good boy," said Holmes, blandly. "Why don’t you introduce this pattern +at Scotland Yard?" he continued, taking a pair of steel handcuffs from +a drawer. "See how beautifully the spring works. They fasten in an +instant." + +"The old pattern is good enough," remarked Lestrade, "if we can only +find the man to put them on." + +"Very good, very good," said Holmes, smiling. "The cabman may as well +help me with my boxes. Just ask him to step up, Wiggins." + +I was surprised to find my companion speaking as though he were about +to set out on a journey, since he had not said anything to me about it. +There was a small portmanteau in the room, and this he pulled out and +began to strap. He was busily engaged at it when the cabman entered the +room. + +"Just give me a help with this buckle, cabman," he said, kneeling over +his task, and never turning his head. + +The fellow came forward with a somewhat sullen, defiant air, and put +down his hands to assist. At that instant there was a sharp click, the +jangling of metal, and Sherlock Holmes sprang to his feet again. + +"Gentlemen," he cried, with flashing eyes, "let me introduce you to Mr. +Jefferson Hope, the murderer of Enoch Drebber and of Joseph Stangerson." + +The whole thing occurred in a moment--so quickly that I had no time +to realize it. I have a vivid recollection of that instant, of Holmes’ +triumphant expression and the ring of his voice, of the cabman’s +dazed, savage face, as he glared at the glittering handcuffs, which had +appeared as if by magic upon his wrists. For a second or two we might +have been a group of statues. Then, with an inarticulate roar of fury, +the prisoner wrenched himself free from Holmes’s grasp, and hurled +himself through the window. Woodwork and glass gave way before him; but +before he got quite through, Gregson, Lestrade, and Holmes sprang upon +him like so many staghounds. He was dragged back into the room, and then +commenced a terrific conflict. So powerful and so fierce was he, that +the four of us were shaken off again and again. He appeared to have the +convulsive strength of a man in an epileptic fit. His face and hands +were terribly mangled by his passage through the glass, but loss of +blood had no effect in diminishing his resistance. It was not until +Lestrade succeeded in getting his hand inside his neckcloth and +half-strangling him that we made him realize that his struggles were of +no avail; and even then we felt no security until we had pinioned his +feet as well as his hands. That done, we rose to our feet breathless and +panting. + +"We have his cab," said Sherlock Holmes. "It will serve to take him to +Scotland Yard. And now, gentlemen," he continued, with a pleasant smile, +"we have reached the end of our little mystery. You are very welcome to +put any questions that you like to me now, and there is no danger that I +will refuse to answer them." + + + + + +PART II. _The Country of the Saints._ + + + + +CHAPTER I. ON THE GREAT ALKALI PLAIN. + + +IN the central portion of the great North American Continent there lies +an arid and repulsive desert, which for many a long year served as a +barrier against the advance of civilisation. From the Sierra Nevada to +Nebraska, and from the Yellowstone River in the north to the Colorado +upon the south, is a region of desolation and silence. Nor is Nature +always in one mood throughout this grim district. It comprises +snow-capped and lofty mountains, and dark and gloomy valleys. There are +swift-flowing rivers which dash through jagged cañons; and there are +enormous plains, which in winter are white with snow, and in summer are +grey with the saline alkali dust. They all preserve, however, the common +characteristics of barrenness, inhospitality, and misery. + +There are no inhabitants of this land of despair. A band of Pawnees +or of Blackfeet may occasionally traverse it in order to reach other +hunting-grounds, but the hardiest of the braves are glad to lose sight +of those awesome plains, and to find themselves once more upon their +prairies. The coyote skulks among the scrub, the buzzard flaps heavily +through the air, and the clumsy grizzly bear lumbers through the dark +ravines, and picks up such sustenance as it can amongst the rocks. These +are the sole dwellers in the wilderness. + +In the whole world there can be no more dreary view than that from +the northern slope of the Sierra Blanco. As far as the eye can reach +stretches the great flat plain-land, all dusted over with patches of +alkali, and intersected by clumps of the dwarfish chaparral bushes. On +the extreme verge of the horizon lie a long chain of mountain peaks, +with their rugged summits flecked with snow. In this great stretch of +country there is no sign of life, nor of anything appertaining to life. +There is no bird in the steel-blue heaven, no movement upon the dull, +grey earth--above all, there is absolute silence. Listen as one may, +there is no shadow of a sound in all that mighty wilderness; nothing but +silence--complete and heart-subduing silence. + +It has been said there is nothing appertaining to life upon the broad +plain. That is hardly true. Looking down from the Sierra Blanco, one +sees a pathway traced out across the desert, which winds away and is +lost in the extreme distance. It is rutted with wheels and trodden down +by the feet of many adventurers. Here and there there are scattered +white objects which glisten in the sun, and stand out against the dull +deposit of alkali. Approach, and examine them! They are bones: some +large and coarse, others smaller and more delicate. The former have +belonged to oxen, and the latter to men. For fifteen hundred miles one +may trace this ghastly caravan route by these scattered remains of those +who had fallen by the wayside. + +Looking down on this very scene, there stood upon the fourth of May, +eighteen hundred and forty-seven, a solitary traveller. His appearance +was such that he might have been the very genius or demon of the region. +An observer would have found it difficult to say whether he was nearer +to forty or to sixty. His face was lean and haggard, and the brown +parchment-like skin was drawn tightly over the projecting bones; his +long, brown hair and beard were all flecked and dashed with white; his +eyes were sunken in his head, and burned with an unnatural lustre; while +the hand which grasped his rifle was hardly more fleshy than that of a +skeleton. As he stood, he leaned upon his weapon for support, and yet +his tall figure and the massive framework of his bones suggested a wiry +and vigorous constitution. His gaunt face, however, and his clothes, +which hung so baggily over his shrivelled limbs, proclaimed what it +was that gave him that senile and decrepit appearance. The man was +dying--dying from hunger and from thirst. + +He had toiled painfully down the ravine, and on to this little +elevation, in the vain hope of seeing some signs of water. Now the great +salt plain stretched before his eyes, and the distant belt of savage +mountains, without a sign anywhere of plant or tree, which might +indicate the presence of moisture. In all that broad landscape there +was no gleam of hope. North, and east, and west he looked with wild +questioning eyes, and then he realised that his wanderings had come to +an end, and that there, on that barren crag, he was about to die. "Why +not here, as well as in a feather bed, twenty years hence," he muttered, +as he seated himself in the shelter of a boulder. + +Before sitting down, he had deposited upon the ground his useless rifle, +and also a large bundle tied up in a grey shawl, which he had carried +slung over his right shoulder. It appeared to be somewhat too heavy for +his strength, for in lowering it, it came down on the ground with some +little violence. Instantly there broke from the grey parcel a little +moaning cry, and from it there protruded a small, scared face, with very +bright brown eyes, and two little speckled, dimpled fists. + +"You’ve hurt me!" said a childish voice reproachfully. + +"Have I though," the man answered penitently, "I didn’t go for to do +it." As he spoke he unwrapped the grey shawl and extricated a pretty +little girl of about five years of age, whose dainty shoes and smart +pink frock with its little linen apron all bespoke a mother’s care. The +child was pale and wan, but her healthy arms and legs showed that she +had suffered less than her companion. + +"How is it now?" he answered anxiously, for she was still rubbing the +towsy golden curls which covered the back of her head. + +"Kiss it and make it well," she said, with perfect gravity, shoving +[19] the injured part up to him. "That’s what mother used to do. Where’s +mother?" + +"Mother’s gone. I guess you’ll see her before long." + +"Gone, eh!" said the little girl. "Funny, she didn’t say good-bye; she +‘most always did if she was just goin’ over to Auntie’s for tea, and now +she’s been away three days. Say, it’s awful dry, ain’t it? Ain’t there +no water, nor nothing to eat?" + +"No, there ain’t nothing, dearie. You’ll just need to be patient awhile, +and then you’ll be all right. Put your head up agin me like that, and +then you’ll feel bullier. It ain’t easy to talk when your lips is like +leather, but I guess I’d best let you know how the cards lie. What’s +that you’ve got?" + +"Pretty things! fine things!" cried the little girl enthusiastically, +holding up two glittering fragments of mica. "When we goes back to home +I’ll give them to brother Bob." + +"You’ll see prettier things than them soon," said the man confidently. +"You just wait a bit. I was going to tell you though--you remember when +we left the river?" + +"Oh, yes." + +"Well, we reckoned we’d strike another river soon, d’ye see. But there +was somethin’ wrong; compasses, or map, or somethin’, and it didn’t +turn up. Water ran out. Just except a little drop for the likes of you +and--and----" + +"And you couldn’t wash yourself," interrupted his companion gravely, +staring up at his grimy visage. + +"No, nor drink. And Mr. Bender, he was the fust to go, and then Indian +Pete, and then Mrs. McGregor, and then Johnny Hones, and then, dearie, +your mother." + +"Then mother’s a deader too," cried the little girl dropping her face in +her pinafore and sobbing bitterly. + +"Yes, they all went except you and me. Then I thought there was some +chance of water in this direction, so I heaved you over my shoulder and +we tramped it together. It don’t seem as though we’ve improved matters. +There’s an almighty small chance for us now!" + +"Do you mean that we are going to die too?" asked the child, checking +her sobs, and raising her tear-stained face. + +"I guess that’s about the size of it." + +"Why didn’t you say so before?" she said, laughing gleefully. "You gave +me such a fright. Why, of course, now as long as we die we’ll be with +mother again." + +"Yes, you will, dearie." + +"And you too. I’ll tell her how awful good you’ve been. I’ll bet she +meets us at the door of Heaven with a big pitcher of water, and a lot +of buckwheat cakes, hot, and toasted on both sides, like Bob and me was +fond of. How long will it be first?" + +"I don’t know--not very long." The man’s eyes were fixed upon the +northern horizon. In the blue vault of the heaven there had appeared +three little specks which increased in size every moment, so rapidly did +they approach. They speedily resolved themselves into three large brown +birds, which circled over the heads of the two wanderers, and then +settled upon some rocks which overlooked them. They were buzzards, the +vultures of the west, whose coming is the forerunner of death. + +"Cocks and hens," cried the little girl gleefully, pointing at their +ill-omened forms, and clapping her hands to make them rise. "Say, did +God make this country?" + +"In course He did," said her companion, rather startled by this +unexpected question. + +"He made the country down in Illinois, and He made the Missouri," the +little girl continued. "I guess somebody else made the country in these +parts. It’s not nearly so well done. They forgot the water and the +trees." + +"What would ye think of offering up prayer?" the man asked diffidently. + +"It ain’t night yet," she answered. + +"It don’t matter. It ain’t quite regular, but He won’t mind that, you +bet. You say over them ones that you used to say every night in the +waggon when we was on the Plains." + +"Why don’t you say some yourself?" the child asked, with wondering eyes. + +"I disremember them," he answered. "I hain’t said none since I was half +the height o’ that gun. I guess it’s never too late. You say them out, +and I’ll stand by and come in on the choruses." + +"Then you’ll need to kneel down, and me too," she said, laying the shawl +out for that purpose. "You’ve got to put your hands up like this. It +makes you feel kind o’ good." + +It was a strange sight had there been anything but the buzzards to see +it. Side by side on the narrow shawl knelt the two wanderers, the little +prattling child and the reckless, hardened adventurer. Her chubby face, +and his haggard, angular visage were both turned up to the cloudless +heaven in heartfelt entreaty to that dread being with whom they were +face to face, while the two voices--the one thin and clear, the other +deep and harsh--united in the entreaty for mercy and forgiveness. The +prayer finished, they resumed their seat in the shadow of the boulder +until the child fell asleep, nestling upon the broad breast of her +protector. He watched over her slumber for some time, but Nature proved +to be too strong for him. For three days and three nights he had allowed +himself neither rest nor repose. Slowly the eyelids drooped over the +tired eyes, and the head sunk lower and lower upon the breast, until the +man’s grizzled beard was mixed with the gold tresses of his companion, +and both slept the same deep and dreamless slumber. + +Had the wanderer remained awake for another half hour a strange sight +would have met his eyes. Far away on the extreme verge of the alkali +plain there rose up a little spray of dust, very slight at first, and +hardly to be distinguished from the mists of the distance, but gradually +growing higher and broader until it formed a solid, well-defined cloud. +This cloud continued to increase in size until it became evident that it +could only be raised by a great multitude of moving creatures. In more +fertile spots the observer would have come to the conclusion that one +of those great herds of bisons which graze upon the prairie land was +approaching him. This was obviously impossible in these arid wilds. As +the whirl of dust drew nearer to the solitary bluff upon which the two +castaways were reposing, the canvas-covered tilts of waggons and the +figures of armed horsemen began to show up through the haze, and the +apparition revealed itself as being a great caravan upon its journey for +the West. But what a caravan! When the head of it had reached the base +of the mountains, the rear was not yet visible on the horizon. Right +across the enormous plain stretched the straggling array, waggons +and carts, men on horseback, and men on foot. Innumerable women who +staggered along under burdens, and children who toddled beside the +waggons or peeped out from under the white coverings. This was evidently +no ordinary party of immigrants, but rather some nomad people who had +been compelled from stress of circumstances to seek themselves a new +country. There rose through the clear air a confused clattering and +rumbling from this great mass of humanity, with the creaking of wheels +and the neighing of horses. Loud as it was, it was not sufficient to +rouse the two tired wayfarers above them. + +At the head of the column there rode a score or more of grave ironfaced +men, clad in sombre homespun garments and armed with rifles. On reaching +the base of the bluff they halted, and held a short council among +themselves. + +"The wells are to the right, my brothers," said one, a hard-lipped, +clean-shaven man with grizzly hair. + +"To the right of the Sierra Blanco--so we shall reach the Rio Grande," + said another. + +"Fear not for water," cried a third. "He who could draw it from the +rocks will not now abandon His own chosen people." + +"Amen! Amen!" responded the whole party. + +They were about to resume their journey when one of the youngest and +keenest-eyed uttered an exclamation and pointed up at the rugged crag +above them. From its summit there fluttered a little wisp of pink, +showing up hard and bright against the grey rocks behind. At the sight +there was a general reining up of horses and unslinging of guns, while +fresh horsemen came galloping up to reinforce the vanguard. The word +‘Redskins’ was on every lip. + +"There can’t be any number of Injuns here," said the elderly man who +appeared to be in command. "We have passed the Pawnees, and there are no +other tribes until we cross the great mountains." + +"Shall I go forward and see, Brother Stangerson," asked one of the band. + +"And I," "and I," cried a dozen voices. + +"Leave your horses below and we will await you here," the Elder +answered. In a moment the young fellows had dismounted, fastened their +horses, and were ascending the precipitous slope which led up to the +object which had excited their curiosity. They advanced rapidly and +noiselessly, with the confidence and dexterity of practised scouts. +The watchers from the plain below could see them flit from rock to rock +until their figures stood out against the skyline. The young man who had +first given the alarm was leading them. Suddenly his followers saw him +throw up his hands, as though overcome with astonishment, and on joining +him they were affected in the same way by the sight which met their +eyes. + +On the little plateau which crowned the barren hill there stood a +single giant boulder, and against this boulder there lay a tall man, +long-bearded and hard-featured, but of an excessive thinness. His placid +face and regular breathing showed that he was fast asleep. Beside him +lay a little child, with her round white arms encircling his brown +sinewy neck, and her golden haired head resting upon the breast of his +velveteen tunic. Her rosy lips were parted, showing the regular line of +snow-white teeth within, and a playful smile played over her infantile +features. Her plump little white legs terminating in white socks and +neat shoes with shining buckles, offered a strange contrast to the long +shrivelled members of her companion. On the ledge of rock above this +strange couple there stood three solemn buzzards, who, at the sight of +the new comers uttered raucous screams of disappointment and flapped +sullenly away. + +The cries of the foul birds awoke the two sleepers who stared about [20] +them in bewilderment. The man staggered to his feet and looked down upon +the plain which had been so desolate when sleep had overtaken him, and +which was now traversed by this enormous body of men and of beasts. His +face assumed an expression of incredulity as he gazed, and he passed his +boney hand over his eyes. "This is what they call delirium, I guess," + he muttered. The child stood beside him, holding on to the skirt of +his coat, and said nothing but looked all round her with the wondering +questioning gaze of childhood. + +The rescuing party were speedily able to convince the two castaways that +their appearance was no delusion. One of them seized the little girl, +and hoisted her upon his shoulder, while two others supported her gaunt +companion, and assisted him towards the waggons. + +"My name is John Ferrier," the wanderer explained; "me and that little +un are all that’s left o’ twenty-one people. The rest is all dead o’ +thirst and hunger away down in the south." + +"Is she your child?" asked someone. + +"I guess she is now," the other cried, defiantly; "she’s mine ‘cause I +saved her. No man will take her from me. She’s Lucy Ferrier from this +day on. Who are you, though?" he continued, glancing with curiosity at +his stalwart, sunburned rescuers; "there seems to be a powerful lot of +ye." + +"Nigh upon ten thousand," said one of the young men; "we are the +persecuted children of God--the chosen of the Angel Merona." + +"I never heard tell on him," said the wanderer. "He appears to have +chosen a fair crowd of ye." + +"Do not jest at that which is sacred," said the other sternly. "We are +of those who believe in those sacred writings, drawn in Egyptian letters +on plates of beaten gold, which were handed unto the holy Joseph Smith +at Palmyra. We have come from Nauvoo, in the State of Illinois, where we +had founded our temple. We have come to seek a refuge from the violent +man and from the godless, even though it be the heart of the desert." + +The name of Nauvoo evidently recalled recollections to John Ferrier. "I +see," he said, "you are the Mormons." + +"We are the Mormons," answered his companions with one voice. + +"And where are you going?" + +"We do not know. The hand of God is leading us under the person of our +Prophet. You must come before him. He shall say what is to be done with +you." + +They had reached the base of the hill by this time, and were surrounded +by crowds of the pilgrims--pale-faced meek-looking women, strong +laughing children, and anxious earnest-eyed men. Many were the cries +of astonishment and of commiseration which arose from them when they +perceived the youth of one of the strangers and the destitution of the +other. Their escort did not halt, however, but pushed on, followed by +a great crowd of Mormons, until they reached a waggon, which was +conspicuous for its great size and for the gaudiness and smartness of +its appearance. Six horses were yoked to it, whereas the others were +furnished with two, or, at most, four a-piece. Beside the driver there +sat a man who could not have been more than thirty years of age, but +whose massive head and resolute expression marked him as a leader. He +was reading a brown-backed volume, but as the crowd approached he laid +it aside, and listened attentively to an account of the episode. Then he +turned to the two castaways. + +"If we take you with us," he said, in solemn words, "it can only be as +believers in our own creed. We shall have no wolves in our fold. Better +far that your bones should bleach in this wilderness than that you +should prove to be that little speck of decay which in time corrupts the +whole fruit. Will you come with us on these terms?" + +"Guess I’ll come with you on any terms," said Ferrier, with such +emphasis that the grave Elders could not restrain a smile. The leader +alone retained his stern, impressive expression. + +"Take him, Brother Stangerson," he said, "give him food and drink, +and the child likewise. Let it be your task also to teach him our holy +creed. We have delayed long enough. Forward! On, on to Zion!" + +"On, on to Zion!" cried the crowd of Mormons, and the words rippled down +the long caravan, passing from mouth to mouth until they died away in a +dull murmur in the far distance. With a cracking of whips and a creaking +of wheels the great waggons got into motion, and soon the whole caravan +was winding along once more. The Elder to whose care the two waifs +had been committed, led them to his waggon, where a meal was already +awaiting them. + +"You shall remain here," he said. "In a few days you will have recovered +from your fatigues. In the meantime, remember that now and for ever you +are of our religion. Brigham Young has said it, and he has spoken with +the voice of Joseph Smith, which is the voice of God." + + + + +CHAPTER II. THE FLOWER OF UTAH. + + +THIS is not the place to commemorate the trials and privations endured +by the immigrant Mormons before they came to their final haven. From the +shores of the Mississippi to the western slopes of the Rocky Mountains +they had struggled on with a constancy almost unparalleled in history. +The savage man, and the savage beast, hunger, thirst, fatigue, and +disease--every impediment which Nature could place in the way, had all +been overcome with Anglo-Saxon tenacity. Yet the long journey and the +accumulated terrors had shaken the hearts of the stoutest among them. +There was not one who did not sink upon his knees in heartfelt prayer +when they saw the broad valley of Utah bathed in the sunlight beneath +them, and learned from the lips of their leader that this was the +promised land, and that these virgin acres were to be theirs for +evermore. + +Young speedily proved himself to be a skilful administrator as well as a +resolute chief. Maps were drawn and charts prepared, in which the future +city was sketched out. All around farms were apportioned and allotted in +proportion to the standing of each individual. The tradesman was put +to his trade and the artisan to his calling. In the town streets and +squares sprang up, as if by magic. In the country there was draining +and hedging, planting and clearing, until the next summer saw the whole +country golden with the wheat crop. Everything prospered in the strange +settlement. Above all, the great temple which they had erected in the +centre of the city grew ever taller and larger. From the first blush of +dawn until the closing of the twilight, the clatter of the hammer +and the rasp of the saw was never absent from the monument which the +immigrants erected to Him who had led them safe through many dangers. + +The two castaways, John Ferrier and the little girl who had shared his +fortunes and had been adopted as his daughter, accompanied the Mormons +to the end of their great pilgrimage. Little Lucy Ferrier was borne +along pleasantly enough in Elder Stangerson’s waggon, a retreat which +she shared with the Mormon’s three wives and with his son, a headstrong +forward boy of twelve. Having rallied, with the elasticity of childhood, +from the shock caused by her mother’s death, she soon became a pet +with the women, and reconciled herself to this new life in her moving +canvas-covered home. In the meantime Ferrier having recovered from his +privations, distinguished himself as a useful guide and an indefatigable +hunter. So rapidly did he gain the esteem of his new companions, that +when they reached the end of their wanderings, it was unanimously agreed +that he should be provided with as large and as fertile a tract of land +as any of the settlers, with the exception of Young himself, and of +Stangerson, Kemball, Johnston, and Drebber, who were the four principal +Elders. + +On the farm thus acquired John Ferrier built himself a substantial +log-house, which received so many additions in succeeding years that it +grew into a roomy villa. He was a man of a practical turn of mind, +keen in his dealings and skilful with his hands. His iron constitution +enabled him to work morning and evening at improving and tilling his +lands. Hence it came about that his farm and all that belonged to +him prospered exceedingly. In three years he was better off than his +neighbours, in six he was well-to-do, in nine he was rich, and in twelve +there were not half a dozen men in the whole of Salt Lake City who could +compare with him. From the great inland sea to the distant Wahsatch +Mountains there was no name better known than that of John Ferrier. + +There was one way and only one in which he offended the susceptibilities +of his co-religionists. No argument or persuasion could ever induce him +to set up a female establishment after the manner of his companions. He +never gave reasons for this persistent refusal, but contented himself by +resolutely and inflexibly adhering to his determination. There were some +who accused him of lukewarmness in his adopted religion, and others who +put it down to greed of wealth and reluctance to incur expense. Others, +again, spoke of some early love affair, and of a fair-haired girl who +had pined away on the shores of the Atlantic. Whatever the reason, +Ferrier remained strictly celibate. In every other respect he conformed +to the religion of the young settlement, and gained the name of being an +orthodox and straight-walking man. + +Lucy Ferrier grew up within the log-house, and assisted her adopted +father in all his undertakings. The keen air of the mountains and the +balsamic odour of the pine trees took the place of nurse and mother to +the young girl. As year succeeded to year she grew taller and stronger, +her cheek more rudy, and her step more elastic. Many a wayfarer upon +the high road which ran by Ferrier’s farm felt long-forgotten thoughts +revive in their mind as they watched her lithe girlish figure tripping +through the wheatfields, or met her mounted upon her father’s mustang, +and managing it with all the ease and grace of a true child of the West. +So the bud blossomed into a flower, and the year which saw her father +the richest of the farmers left her as fair a specimen of American +girlhood as could be found in the whole Pacific slope. + +It was not the father, however, who first discovered that the child had +developed into the woman. It seldom is in such cases. That mysterious +change is too subtle and too gradual to be measured by dates. Least of +all does the maiden herself know it until the tone of a voice or the +touch of a hand sets her heart thrilling within her, and she learns, +with a mixture of pride and of fear, that a new and a larger nature has +awoken within her. There are few who cannot recall that day and remember +the one little incident which heralded the dawn of a new life. In the +case of Lucy Ferrier the occasion was serious enough in itself, apart +from its future influence on her destiny and that of many besides. + +It was a warm June morning, and the Latter Day Saints were as busy as +the bees whose hive they have chosen for their emblem. In the fields and +in the streets rose the same hum of human industry. Down the dusty high +roads defiled long streams of heavily-laden mules, all heading to the +west, for the gold fever had broken out in California, and the Overland +Route lay through the City of the Elect. There, too, were droves of +sheep and bullocks coming in from the outlying pasture lands, and trains +of tired immigrants, men and horses equally weary of their interminable +journey. Through all this motley assemblage, threading her way with the +skill of an accomplished rider, there galloped Lucy Ferrier, her fair +face flushed with the exercise and her long chestnut hair floating out +behind her. She had a commission from her father in the City, and was +dashing in as she had done many a time before, with all the fearlessness +of youth, thinking only of her task and how it was to be performed. The +travel-stained adventurers gazed after her in astonishment, and even +the unemotional Indians, journeying in with their pelties, relaxed their +accustomed stoicism as they marvelled at the beauty of the pale-faced +maiden. + +She had reached the outskirts of the city when she found the road +blocked by a great drove of cattle, driven by a half-dozen wild-looking +herdsmen from the plains. In her impatience she endeavoured to pass this +obstacle by pushing her horse into what appeared to be a gap. Scarcely +had she got fairly into it, however, before the beasts closed in behind +her, and she found herself completely imbedded in the moving stream of +fierce-eyed, long-horned bullocks. Accustomed as she was to deal with +cattle, she was not alarmed at her situation, but took advantage of +every opportunity to urge her horse on in the hopes of pushing her way +through the cavalcade. Unfortunately the horns of one of the creatures, +either by accident or design, came in violent contact with the flank of +the mustang, and excited it to madness. In an instant it reared up upon +its hind legs with a snort of rage, and pranced and tossed in a way that +would have unseated any but a most skilful rider. The situation was full +of peril. Every plunge of the excited horse brought it against the horns +again, and goaded it to fresh madness. It was all that the girl could +do to keep herself in the saddle, yet a slip would mean a terrible death +under the hoofs of the unwieldy and terrified animals. Unaccustomed to +sudden emergencies, her head began to swim, and her grip upon the bridle +to relax. Choked by the rising cloud of dust and by the steam from the +struggling creatures, she might have abandoned her efforts in despair, +but for a kindly voice at her elbow which assured her of assistance. At +the same moment a sinewy brown hand caught the frightened horse by +the curb, and forcing a way through the drove, soon brought her to the +outskirts. + +"You’re not hurt, I hope, miss," said her preserver, respectfully. + +She looked up at his dark, fierce face, and laughed saucily. "I’m awful +frightened," she said, naively; "whoever would have thought that Poncho +would have been so scared by a lot of cows?" + +"Thank God you kept your seat," the other said earnestly. He was a tall, +savage-looking young fellow, mounted on a powerful roan horse, and +clad in the rough dress of a hunter, with a long rifle slung over his +shoulders. "I guess you are the daughter of John Ferrier," he remarked, +"I saw you ride down from his house. When you see him, ask him if he +remembers the Jefferson Hopes of St. Louis. If he’s the same Ferrier, my +father and he were pretty thick." + +"Hadn’t you better come and ask yourself?" she asked, demurely. + +The young fellow seemed pleased at the suggestion, and his dark eyes +sparkled with pleasure. "I’ll do so," he said, "we’ve been in the +mountains for two months, and are not over and above in visiting +condition. He must take us as he finds us." + +"He has a good deal to thank you for, and so have I," she answered, +"he’s awful fond of me. If those cows had jumped on me he’d have never +got over it." + +"Neither would I," said her companion. + +"You! Well, I don’t see that it would make much matter to you, anyhow. +You ain’t even a friend of ours." + +The young hunter’s dark face grew so gloomy over this remark that Lucy +Ferrier laughed aloud. + +"There, I didn’t mean that," she said; "of course, you are a friend now. +You must come and see us. Now I must push along, or father won’t trust +me with his business any more. Good-bye!" + +"Good-bye," he answered, raising his broad sombrero, and bending over +her little hand. She wheeled her mustang round, gave it a cut with her +riding-whip, and darted away down the broad road in a rolling cloud of +dust. + +Young Jefferson Hope rode on with his companions, gloomy and taciturn. +He and they had been among the Nevada Mountains prospecting for silver, +and were returning to Salt Lake City in the hope of raising capital +enough to work some lodes which they had discovered. He had been as keen +as any of them upon the business until this sudden incident had drawn +his thoughts into another channel. The sight of the fair young girl, +as frank and wholesome as the Sierra breezes, had stirred his volcanic, +untamed heart to its very depths. When she had vanished from his sight, +he realized that a crisis had come in his life, and that neither silver +speculations nor any other questions could ever be of such importance to +him as this new and all-absorbing one. The love which had sprung up in +his heart was not the sudden, changeable fancy of a boy, but rather the +wild, fierce passion of a man of strong will and imperious temper. He +had been accustomed to succeed in all that he undertook. He swore in +his heart that he would not fail in this if human effort and human +perseverance could render him successful. + +He called on John Ferrier that night, and many times again, until +his face was a familiar one at the farm-house. John, cooped up in the +valley, and absorbed in his work, had had little chance of learning +the news of the outside world during the last twelve years. All this +Jefferson Hope was able to tell him, and in a style which interested +Lucy as well as her father. He had been a pioneer in California, and +could narrate many a strange tale of fortunes made and fortunes lost +in those wild, halcyon days. He had been a scout too, and a trapper, a +silver explorer, and a ranchman. Wherever stirring adventures were to be +had, Jefferson Hope had been there in search of them. He soon became a +favourite with the old farmer, who spoke eloquently of his virtues. On +such occasions, Lucy was silent, but her blushing cheek and her bright, +happy eyes, showed only too clearly that her young heart was no longer +her own. Her honest father may not have observed these symptoms, +but they were assuredly not thrown away upon the man who had won her +affections. + +It was a summer evening when he came galloping down the road and pulled +up at the gate. She was at the doorway, and came down to meet him. He +threw the bridle over the fence and strode up the pathway. + +"I am off, Lucy," he said, taking her two hands in his, and gazing +tenderly down into her face; "I won’t ask you to come with me now, but +will you be ready to come when I am here again?" + +"And when will that be?" she asked, blushing and laughing. + +"A couple of months at the outside. I will come and claim you then, my +darling. There’s no one who can stand between us." + +"And how about father?" she asked. + +"He has given his consent, provided we get these mines working all +right. I have no fear on that head." + +"Oh, well; of course, if you and father have arranged it all, there’s +no more to be said," she whispered, with her cheek against his broad +breast. + +"Thank God!" he said, hoarsely, stooping and kissing her. "It is +settled, then. The longer I stay, the harder it will be to go. They are +waiting for me at the cañon. Good-bye, my own darling--good-bye. In two +months you shall see me." + +He tore himself from her as he spoke, and, flinging himself upon his +horse, galloped furiously away, never even looking round, as though +afraid that his resolution might fail him if he took one glance at +what he was leaving. She stood at the gate, gazing after him until +he vanished from her sight. Then she walked back into the house, the +happiest girl in all Utah. + + + + +CHAPTER III. JOHN FERRIER TALKS WITH THE PROPHET. + + +THREE weeks had passed since Jefferson Hope and his comrades had +departed from Salt Lake City. John Ferrier’s heart was sore within him +when he thought of the young man’s return, and of the impending loss of +his adopted child. Yet her bright and happy face reconciled him to +the arrangement more than any argument could have done. He had always +determined, deep down in his resolute heart, that nothing would ever +induce him to allow his daughter to wed a Mormon. Such a marriage he +regarded as no marriage at all, but as a shame and a disgrace. Whatever +he might think of the Mormon doctrines, upon that one point he was +inflexible. He had to seal his mouth on the subject, however, for to +express an unorthodox opinion was a dangerous matter in those days in +the Land of the Saints. + +Yes, a dangerous matter--so dangerous that even the most saintly dared +only whisper their religious opinions with bated breath, lest something +which fell from their lips might be misconstrued, and bring down a +swift retribution upon them. The victims of persecution had now turned +persecutors on their own account, and persecutors of the most +terrible description. Not the Inquisition of Seville, nor the German +Vehm-gericht, nor the Secret Societies of Italy, were ever able to put +a more formidable machinery in motion than that which cast a cloud over +the State of Utah. + +Its invisibility, and the mystery which was attached to it, made +this organization doubly terrible. It appeared to be omniscient and +omnipotent, and yet was neither seen nor heard. The man who held out +against the Church vanished away, and none knew whither he had gone or +what had befallen him. His wife and his children awaited him at home, +but no father ever returned to tell them how he had fared at the +hands of his secret judges. A rash word or a hasty act was followed +by annihilation, and yet none knew what the nature might be of this +terrible power which was suspended over them. No wonder that men +went about in fear and trembling, and that even in the heart of the +wilderness they dared not whisper the doubts which oppressed them. + +At first this vague and terrible power was exercised only upon the +recalcitrants who, having embraced the Mormon faith, wished afterwards +to pervert or to abandon it. Soon, however, it took a wider range. The +supply of adult women was running short, and polygamy without a female +population on which to draw was a barren doctrine indeed. Strange +rumours began to be bandied about--rumours of murdered immigrants and +rifled camps in regions where Indians had never been seen. Fresh women +appeared in the harems of the Elders--women who pined and wept, and +bore upon their faces the traces of an unextinguishable horror. Belated +wanderers upon the mountains spoke of gangs of armed men, masked, +stealthy, and noiseless, who flitted by them in the darkness. These +tales and rumours took substance and shape, and were corroborated and +re-corroborated, until they resolved themselves into a definite name. +To this day, in the lonely ranches of the West, the name of the Danite +Band, or the Avenging Angels, is a sinister and an ill-omened one. + +Fuller knowledge of the organization which produced such terrible +results served to increase rather than to lessen the horror which it +inspired in the minds of men. None knew who belonged to this ruthless +society. The names of the participators in the deeds of blood and +violence done under the name of religion were kept profoundly secret. +The very friend to whom you communicated your misgivings as to the +Prophet and his mission, might be one of those who would come forth at +night with fire and sword to exact a terrible reparation. Hence every +man feared his neighbour, and none spoke of the things which were +nearest his heart. + +One fine morning, John Ferrier was about to set out to his wheatfields, +when he heard the click of the latch, and, looking through the window, +saw a stout, sandy-haired, middle-aged man coming up the pathway. His +heart leapt to his mouth, for this was none other than the great Brigham +Young himself. Full of trepidation--for he knew that such a visit boded +him little good--Ferrier ran to the door to greet the Mormon chief. The +latter, however, received his salutations coldly, and followed him with +a stern face into the sitting-room. + +"Brother Ferrier," he said, taking a seat, and eyeing the farmer keenly +from under his light-coloured eyelashes, "the true believers have been +good friends to you. We picked you up when you were starving in the +desert, we shared our food with you, led you safe to the Chosen Valley, +gave you a goodly share of land, and allowed you to wax rich under our +protection. Is not this so?" + +"It is so," answered John Ferrier. + +"In return for all this we asked but one condition: that was, that you +should embrace the true faith, and conform in every way to its usages. +This you promised to do, and this, if common report says truly, you have +neglected." + +"And how have I neglected it?" asked Ferrier, throwing out his hands in +expostulation. "Have I not given to the common fund? Have I not attended +at the Temple? Have I not----?" + +"Where are your wives?" asked Young, looking round him. "Call them in, +that I may greet them." + +"It is true that I have not married," Ferrier answered. "But women +were few, and there were many who had better claims than I. I was not a +lonely man: I had my daughter to attend to my wants." + +"It is of that daughter that I would speak to you," said the leader +of the Mormons. "She has grown to be the flower of Utah, and has found +favour in the eyes of many who are high in the land." + +John Ferrier groaned internally. + +"There are stories of her which I would fain disbelieve--stories that +she is sealed to some Gentile. This must be the gossip of idle tongues. +What is the thirteenth rule in the code of the sainted Joseph Smith? +‘Let every maiden of the true faith marry one of the elect; for if +she wed a Gentile, she commits a grievous sin.’ This being so, it is +impossible that you, who profess the holy creed, should suffer your +daughter to violate it." + +John Ferrier made no answer, but he played nervously with his +riding-whip. + +"Upon this one point your whole faith shall be tested--so it has been +decided in the Sacred Council of Four. The girl is young, and we would +not have her wed grey hairs, neither would we deprive her of all +choice. We Elders have many heifers, [29] but our children must also +be provided. Stangerson has a son, and Drebber has a son, and either of +them would gladly welcome your daughter to their house. Let her choose +between them. They are young and rich, and of the true faith. What say +you to that?" + +Ferrier remained silent for some little time with his brows knitted. + +"You will give us time," he said at last. "My daughter is very +young--she is scarce of an age to marry." + +"She shall have a month to choose," said Young, rising from his seat. +"At the end of that time she shall give her answer." + +He was passing through the door, when he turned, with flushed face and +flashing eyes. "It were better for you, John Ferrier," he thundered, +"that you and she were now lying blanched skeletons upon the Sierra +Blanco, than that you should put your weak wills against the orders of +the Holy Four!" + +With a threatening gesture of his hand, he turned from the door, and +Ferrier heard his heavy step scrunching along the shingly path. + +He was still sitting with his elbows upon his knees, considering how he +should broach the matter to his daughter when a soft hand was laid upon +his, and looking up, he saw her standing beside him. One glance at her +pale, frightened face showed him that she had heard what had passed. + +"I could not help it," she said, in answer to his look. "His voice rang +through the house. Oh, father, father, what shall we do?" + +"Don’t you scare yourself," he answered, drawing her to him, and passing +his broad, rough hand caressingly over her chestnut hair. "We’ll fix it +up somehow or another. You don’t find your fancy kind o’ lessening for +this chap, do you?" + +A sob and a squeeze of his hand was her only answer. + +"No; of course not. I shouldn’t care to hear you say you did. He’s a +likely lad, and he’s a Christian, which is more than these folk here, in +spite o’ all their praying and preaching. There’s a party starting for +Nevada to-morrow, and I’ll manage to send him a message letting him know +the hole we are in. If I know anything o’ that young man, he’ll be back +here with a speed that would whip electro-telegraphs." + +Lucy laughed through her tears at her father’s description. + +"When he comes, he will advise us for the best. But it is for you that +I am frightened, dear. One hears--one hears such dreadful stories about +those who oppose the Prophet: something terrible always happens to +them." + +"But we haven’t opposed him yet," her father answered. "It will be time +to look out for squalls when we do. We have a clear month before us; at +the end of that, I guess we had best shin out of Utah." + +"Leave Utah!" + +"That’s about the size of it." + +"But the farm?" + +"We will raise as much as we can in money, and let the rest go. To tell +the truth, Lucy, it isn’t the first time I have thought of doing it. I +don’t care about knuckling under to any man, as these folk do to their +darned prophet. I’m a free-born American, and it’s all new to me. Guess +I’m too old to learn. If he comes browsing about this farm, he might +chance to run up against a charge of buckshot travelling in the opposite +direction." + +"But they won’t let us leave," his daughter objected. + +"Wait till Jefferson comes, and we’ll soon manage that. In the meantime, +don’t you fret yourself, my dearie, and don’t get your eyes swelled up, +else he’ll be walking into me when he sees you. There’s nothing to be +afeared about, and there’s no danger at all." + +John Ferrier uttered these consoling remarks in a very confident tone, +but she could not help observing that he paid unusual care to the +fastening of the doors that night, and that he carefully cleaned and +loaded the rusty old shotgun which hung upon the wall of his bedroom. + + + + +CHAPTER IV. A FLIGHT FOR LIFE. + + +ON the morning which followed his interview with the Mormon Prophet, +John Ferrier went in to Salt Lake City, and having found his +acquaintance, who was bound for the Nevada Mountains, he entrusted him +with his message to Jefferson Hope. In it he told the young man of the +imminent danger which threatened them, and how necessary it was that he +should return. Having done thus he felt easier in his mind, and returned +home with a lighter heart. + +As he approached his farm, he was surprised to see a horse hitched to +each of the posts of the gate. Still more surprised was he on entering +to find two young men in possession of his sitting-room. One, with a +long pale face, was leaning back in the rocking-chair, with his feet +cocked up upon the stove. The other, a bull-necked youth with coarse +bloated features, was standing in front of the window with his hands in +his pocket, whistling a popular hymn. Both of them nodded to Ferrier as +he entered, and the one in the rocking-chair commenced the conversation. + +"Maybe you don’t know us," he said. "This here is the son of Elder +Drebber, and I’m Joseph Stangerson, who travelled with you in the desert +when the Lord stretched out His hand and gathered you into the true +fold." + +"As He will all the nations in His own good time," said the other in a +nasal voice; "He grindeth slowly but exceeding small." + +John Ferrier bowed coldly. He had guessed who his visitors were. + +"We have come," continued Stangerson, "at the advice of our fathers to +solicit the hand of your daughter for whichever of us may seem good to +you and to her. As I have but four wives and Brother Drebber here has +seven, it appears to me that my claim is the stronger one." + +"Nay, nay, Brother Stangerson," cried the other; "the question is not +how many wives we have, but how many we can keep. My father has now +given over his mills to me, and I am the richer man." + +"But my prospects are better," said the other, warmly. "When the +Lord removes my father, I shall have his tanning yard and his leather +factory. Then I am your elder, and am higher in the Church." + +"It will be for the maiden to decide," rejoined young Drebber, smirking +at his own reflection in the glass. "We will leave it all to her +decision." + +During this dialogue, John Ferrier had stood fuming in the doorway, +hardly able to keep his riding-whip from the backs of his two visitors. + +"Look here," he said at last, striding up to them, "when my daughter +summons you, you can come, but until then I don’t want to see your faces +again." + +The two young Mormons stared at him in amazement. In their eyes this +competition between them for the maiden’s hand was the highest of +honours both to her and her father. + +"There are two ways out of the room," cried Ferrier; "there is the door, +and there is the window. Which do you care to use?" + +His brown face looked so savage, and his gaunt hands so threatening, +that his visitors sprang to their feet and beat a hurried retreat. The +old farmer followed them to the door. + +"Let me know when you have settled which it is to be," he said, +sardonically. + +"You shall smart for this!" Stangerson cried, white with rage. "You have +defied the Prophet and the Council of Four. You shall rue it to the end +of your days." + +"The hand of the Lord shall be heavy upon you," cried young Drebber; "He +will arise and smite you!" + +"Then I’ll start the smiting," exclaimed Ferrier furiously, and would +have rushed upstairs for his gun had not Lucy seized him by the arm and +restrained him. Before he could escape from her, the clatter of horses’ +hoofs told him that they were beyond his reach. + +"The young canting rascals!" he exclaimed, wiping the perspiration from +his forehead; "I would sooner see you in your grave, my girl, than the +wife of either of them." + +"And so should I, father," she answered, with spirit; "but Jefferson +will soon be here." + +"Yes. It will not be long before he comes. The sooner the better, for we +do not know what their next move may be." + +It was, indeed, high time that someone capable of giving advice and +help should come to the aid of the sturdy old farmer and his adopted +daughter. In the whole history of the settlement there had never been +such a case of rank disobedience to the authority of the Elders. If +minor errors were punished so sternly, what would be the fate of this +arch rebel. Ferrier knew that his wealth and position would be of no +avail to him. Others as well known and as rich as himself had been +spirited away before now, and their goods given over to the Church. He +was a brave man, but he trembled at the vague, shadowy terrors which +hung over him. Any known danger he could face with a firm lip, but +this suspense was unnerving. He concealed his fears from his daughter, +however, and affected to make light of the whole matter, though she, +with the keen eye of love, saw plainly that he was ill at ease. + +He expected that he would receive some message or remonstrance from +Young as to his conduct, and he was not mistaken, though it came in an +unlooked-for manner. Upon rising next morning he found, to his surprise, +a small square of paper pinned on to the coverlet of his bed just over +his chest. On it was printed, in bold straggling letters:-- + +"Twenty-nine days are given you for amendment, and then----" + +The dash was more fear-inspiring than any threat could have been. How +this warning came into his room puzzled John Ferrier sorely, for his +servants slept in an outhouse, and the doors and windows had all been +secured. He crumpled the paper up and said nothing to his daughter, but +the incident struck a chill into his heart. The twenty-nine days were +evidently the balance of the month which Young had promised. What +strength or courage could avail against an enemy armed with such +mysterious powers? The hand which fastened that pin might have struck +him to the heart, and he could never have known who had slain him. + +Still more shaken was he next morning. They had sat down to their +breakfast when Lucy with a cry of surprise pointed upwards. In the +centre of the ceiling was scrawled, with a burned stick apparently, +the number 28. To his daughter it was unintelligible, and he did not +enlighten her. That night he sat up with his gun and kept watch and +ward. He saw and he heard nothing, and yet in the morning a great 27 had +been painted upon the outside of his door. + +Thus day followed day; and as sure as morning came he found that his +unseen enemies had kept their register, and had marked up in some +conspicuous position how many days were still left to him out of the +month of grace. Sometimes the fatal numbers appeared upon the walls, +sometimes upon the floors, occasionally they were on small placards +stuck upon the garden gate or the railings. With all his vigilance John +Ferrier could not discover whence these daily warnings proceeded. A +horror which was almost superstitious came upon him at the sight of +them. He became haggard and restless, and his eyes had the troubled look +of some hunted creature. He had but one hope in life now, and that was +for the arrival of the young hunter from Nevada. + +Twenty had changed to fifteen and fifteen to ten, but there was no news +of the absentee. One by one the numbers dwindled down, and still there +came no sign of him. Whenever a horseman clattered down the road, or a +driver shouted at his team, the old farmer hurried to the gate thinking +that help had arrived at last. At last, when he saw five give way to +four and that again to three, he lost heart, and abandoned all hope of +escape. Single-handed, and with his limited knowledge of the mountains +which surrounded the settlement, he knew that he was powerless. The +more-frequented roads were strictly watched and guarded, and none could +pass along them without an order from the Council. Turn which way he +would, there appeared to be no avoiding the blow which hung over him. +Yet the old man never wavered in his resolution to part with life itself +before he consented to what he regarded as his daughter’s dishonour. + +He was sitting alone one evening pondering deeply over his troubles, and +searching vainly for some way out of them. That morning had shown the +figure 2 upon the wall of his house, and the next day would be the last +of the allotted time. What was to happen then? All manner of vague and +terrible fancies filled his imagination. And his daughter--what was to +become of her after he was gone? Was there no escape from the invisible +network which was drawn all round them. He sank his head upon the table +and sobbed at the thought of his own impotence. + +What was that? In the silence he heard a gentle scratching sound--low, +but very distinct in the quiet of the night. It came from the door of +the house. Ferrier crept into the hall and listened intently. There +was a pause for a few moments, and then the low insidious sound was +repeated. Someone was evidently tapping very gently upon one of the +panels of the door. Was it some midnight assassin who had come to carry +out the murderous orders of the secret tribunal? Or was it some agent +who was marking up that the last day of grace had arrived. John Ferrier +felt that instant death would be better than the suspense which shook +his nerves and chilled his heart. Springing forward he drew the bolt and +threw the door open. + +Outside all was calm and quiet. The night was fine, and the stars were +twinkling brightly overhead. The little front garden lay before the +farmer’s eyes bounded by the fence and gate, but neither there nor on +the road was any human being to be seen. With a sigh of relief, Ferrier +looked to right and to left, until happening to glance straight down at +his own feet he saw to his astonishment a man lying flat upon his face +upon the ground, with arms and legs all asprawl. + +So unnerved was he at the sight that he leaned up against the wall with +his hand to his throat to stifle his inclination to call out. His first +thought was that the prostrate figure was that of some wounded or dying +man, but as he watched it he saw it writhe along the ground and into the +hall with the rapidity and noiselessness of a serpent. Once within the +house the man sprang to his feet, closed the door, and revealed to the +astonished farmer the fierce face and resolute expression of Jefferson +Hope. + +"Good God!" gasped John Ferrier. "How you scared me! Whatever made you +come in like that." + +"Give me food," the other said, hoarsely. "I have had no time for bite +or sup for eight-and-forty hours." He flung himself upon the [21] cold +meat and bread which were still lying upon the table from his host’s +supper, and devoured it voraciously. "Does Lucy bear up well?" he asked, +when he had satisfied his hunger. + +"Yes. She does not know the danger," her father answered. + +"That is well. The house is watched on every side. That is why I crawled +my way up to it. They may be darned sharp, but they’re not quite sharp +enough to catch a Washoe hunter." + +John Ferrier felt a different man now that he realized that he had +a devoted ally. He seized the young man’s leathery hand and wrung it +cordially. "You’re a man to be proud of," he said. "There are not many +who would come to share our danger and our troubles." + +"You’ve hit it there, pard," the young hunter answered. "I have a +respect for you, but if you were alone in this business I’d think twice +before I put my head into such a hornet’s nest. It’s Lucy that brings me +here, and before harm comes on her I guess there will be one less o’ the +Hope family in Utah." + +"What are we to do?" + +"To-morrow is your last day, and unless you act to-night you are lost. +I have a mule and two horses waiting in the Eagle Ravine. How much money +have you?" + +"Two thousand dollars in gold, and five in notes." + +"That will do. I have as much more to add to it. We must push for Carson +City through the mountains. You had best wake Lucy. It is as well that +the servants do not sleep in the house." + +While Ferrier was absent, preparing his daughter for the approaching +journey, Jefferson Hope packed all the eatables that he could find into +a small parcel, and filled a stoneware jar with water, for he knew by +experience that the mountain wells were few and far between. He had +hardly completed his arrangements before the farmer returned with his +daughter all dressed and ready for a start. The greeting between the +lovers was warm, but brief, for minutes were precious, and there was +much to be done. + +"We must make our start at once," said Jefferson Hope, speaking in a low +but resolute voice, like one who realizes the greatness of the peril, +but has steeled his heart to meet it. "The front and back entrances are +watched, but with caution we may get away through the side window and +across the fields. Once on the road we are only two miles from the +Ravine where the horses are waiting. By daybreak we should be half-way +through the mountains." + +"What if we are stopped," asked Ferrier. + +Hope slapped the revolver butt which protruded from the front of his +tunic. "If they are too many for us we shall take two or three of them +with us," he said with a sinister smile. + +The lights inside the house had all been extinguished, and from the +darkened window Ferrier peered over the fields which had been his own, +and which he was now about to abandon for ever. He had long nerved +himself to the sacrifice, however, and the thought of the honour and +happiness of his daughter outweighed any regret at his ruined fortunes. +All looked so peaceful and happy, the rustling trees and the broad +silent stretch of grain-land, that it was difficult to realize that +the spirit of murder lurked through it all. Yet the white face and set +expression of the young hunter showed that in his approach to the house +he had seen enough to satisfy him upon that head. + +Ferrier carried the bag of gold and notes, Jefferson Hope had the scanty +provisions and water, while Lucy had a small bundle containing a few +of her more valued possessions. Opening the window very slowly and +carefully, they waited until a dark cloud had somewhat obscured the +night, and then one by one passed through into the little garden. With +bated breath and crouching figures they stumbled across it, and gained +the shelter of the hedge, which they skirted until they came to the gap +which opened into the cornfields. They had just reached this point when +the young man seized his two companions and dragged them down into the +shadow, where they lay silent and trembling. + +It was as well that his prairie training had given Jefferson Hope the +ears of a lynx. He and his friends had hardly crouched down before the +melancholy hooting of a mountain owl was heard within a few yards +of them, which was immediately answered by another hoot at a small +distance. At the same moment a vague shadowy figure emerged from the +gap for which they had been making, and uttered the plaintive signal cry +again, on which a second man appeared out of the obscurity. + +"To-morrow at midnight," said the first who appeared to be in authority. +"When the Whip-poor-Will calls three times." + +"It is well," returned the other. "Shall I tell Brother Drebber?" + +"Pass it on to him, and from him to the others. Nine to seven!" + +"Seven to five!" repeated the other, and the two figures flitted away +in different directions. Their concluding words had evidently been some +form of sign and countersign. The instant that their footsteps had died +away in the distance, Jefferson Hope sprang to his feet, and helping his +companions through the gap, led the way across the fields at the top +of his speed, supporting and half-carrying the girl when her strength +appeared to fail her. + +"Hurry on! hurry on!" he gasped from time to time. "We are through the +line of sentinels. Everything depends on speed. Hurry on!" + +Once on the high road they made rapid progress. Only once did they +meet anyone, and then they managed to slip into a field, and so avoid +recognition. Before reaching the town the hunter branched away into a +rugged and narrow footpath which led to the mountains. Two dark jagged +peaks loomed above them through the darkness, and the defile which led +between them was the Eagle Cañon in which the horses were awaiting them. +With unerring instinct Jefferson Hope picked his way among the great +boulders and along the bed of a dried-up watercourse, until he came to +the retired corner, screened with rocks, where the faithful animals had +been picketed. The girl was placed upon the mule, and old Ferrier upon +one of the horses, with his money-bag, while Jefferson Hope led the +other along the precipitous and dangerous path. + +It was a bewildering route for anyone who was not accustomed to face +Nature in her wildest moods. On the one side a great crag towered up a +thousand feet or more, black, stern, and menacing, with long basaltic +columns upon its rugged surface like the ribs of some petrified monster. +On the other hand a wild chaos of boulders and debris made all advance +impossible. Between the two ran the irregular track, so narrow in places +that they had to travel in Indian file, and so rough that only practised +riders could have traversed it at all. Yet in spite of all dangers and +difficulties, the hearts of the fugitives were light within them, +for every step increased the distance between them and the terrible +despotism from which they were flying. + +They soon had a proof, however, that they were still within the +jurisdiction of the Saints. They had reached the very wildest and most +desolate portion of the pass when the girl gave a startled cry, and +pointed upwards. On a rock which overlooked the track, showing out dark +and plain against the sky, there stood a solitary sentinel. He saw them +as soon as they perceived him, and his military challenge of "Who goes +there?" rang through the silent ravine. + +"Travellers for Nevada," said Jefferson Hope, with his hand upon the +rifle which hung by his saddle. + +They could see the lonely watcher fingering his gun, and peering down at +them as if dissatisfied at their reply. + +"By whose permission?" he asked. + +"The Holy Four," answered Ferrier. His Mormon experiences had taught him +that that was the highest authority to which he could refer. + +"Nine from seven," cried the sentinel. + +"Seven from five," returned Jefferson Hope promptly, remembering the +countersign which he had heard in the garden. + +"Pass, and the Lord go with you," said the voice from above. Beyond his +post the path broadened out, and the horses were able to break into a +trot. Looking back, they could see the solitary watcher leaning upon +his gun, and knew that they had passed the outlying post of the chosen +people, and that freedom lay before them. + + + + +CHAPTER V. THE AVENGING ANGELS. + + +ALL night their course lay through intricate defiles and over irregular +and rock-strewn paths. More than once they lost their way, but Hope’s +intimate knowledge of the mountains enabled them to regain the track +once more. When morning broke, a scene of marvellous though savage +beauty lay before them. In every direction the great snow-capped peaks +hemmed them in, peeping over each other’s shoulders to the far horizon. +So steep were the rocky banks on either side of them, that the larch +and the pine seemed to be suspended over their heads, and to need only a +gust of wind to come hurtling down upon them. Nor was the fear entirely +an illusion, for the barren valley was thickly strewn with trees and +boulders which had fallen in a similar manner. Even as they passed, +a great rock came thundering down with a hoarse rattle which woke +the echoes in the silent gorges, and startled the weary horses into a +gallop. + +As the sun rose slowly above the eastern horizon, the caps of the great +mountains lit up one after the other, like lamps at a festival, until +they were all ruddy and glowing. The magnificent spectacle cheered the +hearts of the three fugitives and gave them fresh energy. At a wild +torrent which swept out of a ravine they called a halt and watered their +horses, while they partook of a hasty breakfast. Lucy and her father +would fain have rested longer, but Jefferson Hope was inexorable. "They +will be upon our track by this time," he said. "Everything depends upon +our speed. Once safe in Carson we may rest for the remainder of our +lives." + +During the whole of that day they struggled on through the defiles, and +by evening they calculated that they were more than thirty miles from +their enemies. At night-time they chose the base of a beetling crag, +where the rocks offered some protection from the chill wind, and there +huddled together for warmth, they enjoyed a few hours’ sleep. Before +daybreak, however, they were up and on their way once more. They had +seen no signs of any pursuers, and Jefferson Hope began to think that +they were fairly out of the reach of the terrible organization whose +enmity they had incurred. He little knew how far that iron grasp could +reach, or how soon it was to close upon them and crush them. + +About the middle of the second day of their flight their scanty store +of provisions began to run out. This gave the hunter little uneasiness, +however, for there was game to be had among the mountains, and he had +frequently before had to depend upon his rifle for the needs of life. +Choosing a sheltered nook, he piled together a few dried branches and +made a blazing fire, at which his companions might warm themselves, for +they were now nearly five thousand feet above the sea level, and the air +was bitter and keen. Having tethered the horses, and bade Lucy adieu, +he threw his gun over his shoulder, and set out in search of whatever +chance might throw in his way. Looking back he saw the old man and the +young girl crouching over the blazing fire, while the three animals +stood motionless in the back-ground. Then the intervening rocks hid them +from his view. + +He walked for a couple of miles through one ravine after another without +success, though from the marks upon the bark of the trees, and other +indications, he judged that there were numerous bears in the vicinity. +At last, after two or three hours’ fruitless search, he was thinking of +turning back in despair, when casting his eyes upwards he saw a sight +which sent a thrill of pleasure through his heart. On the edge of a +jutting pinnacle, three or four hundred feet above him, there stood a +creature somewhat resembling a sheep in appearance, but armed with a +pair of gigantic horns. The big-horn--for so it is called--was acting, +probably, as a guardian over a flock which were invisible to the hunter; +but fortunately it was heading in the opposite direction, and had not +perceived him. Lying on his face, he rested his rifle upon a rock, and +took a long and steady aim before drawing the trigger. The animal sprang +into the air, tottered for a moment upon the edge of the precipice, and +then came crashing down into the valley beneath. + +The creature was too unwieldy to lift, so the hunter contented himself +with cutting away one haunch and part of the flank. With this trophy +over his shoulder, he hastened to retrace his steps, for the evening was +already drawing in. He had hardly started, however, before he realized +the difficulty which faced him. In his eagerness he had wandered far +past the ravines which were known to him, and it was no easy matter +to pick out the path which he had taken. The valley in which he found +himself divided and sub-divided into many gorges, which were so like +each other that it was impossible to distinguish one from the other. +He followed one for a mile or more until he came to a mountain torrent +which he was sure that he had never seen before. Convinced that he had +taken the wrong turn, he tried another, but with the same result. Night +was coming on rapidly, and it was almost dark before he at last found +himself in a defile which was familiar to him. Even then it was no easy +matter to keep to the right track, for the moon had not yet risen, and +the high cliffs on either side made the obscurity more profound. Weighed +down with his burden, and weary from his exertions, he stumbled along, +keeping up his heart by the reflection that every step brought him +nearer to Lucy, and that he carried with him enough to ensure them food +for the remainder of their journey. + +He had now come to the mouth of the very defile in which he had left +them. Even in the darkness he could recognize the outline of the cliffs +which bounded it. They must, he reflected, be awaiting him anxiously, +for he had been absent nearly five hours. In the gladness of his heart +he put his hands to his mouth and made the glen re-echo to a loud halloo +as a signal that he was coming. He paused and listened for an answer. +None came save his own cry, which clattered up the dreary silent +ravines, and was borne back to his ears in countless repetitions. Again +he shouted, even louder than before, and again no whisper came back from +the friends whom he had left such a short time ago. A vague, nameless +dread came over him, and he hurried onwards frantically, dropping the +precious food in his agitation. + +When he turned the corner, he came full in sight of the spot where the +fire had been lit. There was still a glowing pile of wood ashes there, +but it had evidently not been tended since his departure. The same +dead silence still reigned all round. With his fears all changed to +convictions, he hurried on. There was no living creature near the +remains of the fire: animals, man, maiden, all were gone. It was only +too clear that some sudden and terrible disaster had occurred during +his absence--a disaster which had embraced them all, and yet had left no +traces behind it. + +Bewildered and stunned by this blow, Jefferson Hope felt his head spin +round, and had to lean upon his rifle to save himself from falling. He +was essentially a man of action, however, and speedily recovered from +his temporary impotence. Seizing a half-consumed piece of wood from the +smouldering fire, he blew it into a flame, and proceeded with its help +to examine the little camp. The ground was all stamped down by the feet +of horses, showing that a large party of mounted men had overtaken +the fugitives, and the direction of their tracks proved that they had +afterwards turned back to Salt Lake City. Had they carried back both of +his companions with them? Jefferson Hope had almost persuaded himself +that they must have done so, when his eye fell upon an object which made +every nerve of his body tingle within him. A little way on one side of +the camp was a low-lying heap of reddish soil, which had assuredly +not been there before. There was no mistaking it for anything but a +newly-dug grave. As the young hunter approached it, he perceived that a +stick had been planted on it, with a sheet of paper stuck in the cleft +fork of it. The inscription upon the paper was brief, but to the point: + + JOHN FERRIER, + FORMERLY OF SALT LAKE CITY, [22] + Died August 4th, 1860. + +The sturdy old man, whom he had left so short a time before, was gone, +then, and this was all his epitaph. Jefferson Hope looked wildly round +to see if there was a second grave, but there was no sign of one. Lucy +had been carried back by their terrible pursuers to fulfil her original +destiny, by becoming one of the harem of the Elder’s son. As the young +fellow realized the certainty of her fate, and his own powerlessness to +prevent it, he wished that he, too, was lying with the old farmer in his +last silent resting-place. + +Again, however, his active spirit shook off the lethargy which springs +from despair. If there was nothing else left to him, he could at least +devote his life to revenge. With indomitable patience and perseverance, +Jefferson Hope possessed also a power of sustained vindictiveness, which +he may have learned from the Indians amongst whom he had lived. As he +stood by the desolate fire, he felt that the only one thing which could +assuage his grief would be thorough and complete retribution, brought +by his own hand upon his enemies. His strong will and untiring energy +should, he determined, be devoted to that one end. With a grim, white +face, he retraced his steps to where he had dropped the food, and having +stirred up the smouldering fire, he cooked enough to last him for a +few days. This he made up into a bundle, and, tired as he was, he +set himself to walk back through the mountains upon the track of the +avenging angels. + +For five days he toiled footsore and weary through the defiles which he +had already traversed on horseback. At night he flung himself down among +the rocks, and snatched a few hours of sleep; but before daybreak he was +always well on his way. On the sixth day, he reached the Eagle Cañon, +from which they had commenced their ill-fated flight. Thence he could +look down upon the home of the saints. Worn and exhausted, he leaned +upon his rifle and shook his gaunt hand fiercely at the silent +widespread city beneath him. As he looked at it, he observed that +there were flags in some of the principal streets, and other signs of +festivity. He was still speculating as to what this might mean when he +heard the clatter of horse’s hoofs, and saw a mounted man riding towards +him. As he approached, he recognized him as a Mormon named Cowper, to +whom he had rendered services at different times. He therefore accosted +him when he got up to him, with the object of finding out what Lucy +Ferrier’s fate had been. + +"I am Jefferson Hope," he said. "You remember me." + +The Mormon looked at him with undisguised astonishment--indeed, it was +difficult to recognize in this tattered, unkempt wanderer, with ghastly +white face and fierce, wild eyes, the spruce young hunter of former +days. Having, however, at last, satisfied himself as to his identity, +the man’s surprise changed to consternation. + +"You are mad to come here," he cried. "It is as much as my own life is +worth to be seen talking with you. There is a warrant against you from +the Holy Four for assisting the Ferriers away." + +"I don’t fear them, or their warrant," Hope said, earnestly. "You must +know something of this matter, Cowper. I conjure you by everything you +hold dear to answer a few questions. We have always been friends. For +God’s sake, don’t refuse to answer me." + +"What is it?" the Mormon asked uneasily. "Be quick. The very rocks have +ears and the trees eyes." + +"What has become of Lucy Ferrier?" + +"She was married yesterday to young Drebber. Hold up, man, hold up, you +have no life left in you." + +"Don’t mind me," said Hope faintly. He was white to the very lips, and +had sunk down on the stone against which he had been leaning. "Married, +you say?" + +"Married yesterday--that’s what those flags are for on the Endowment +House. There was some words between young Drebber and young Stangerson +as to which was to have her. They’d both been in the party that followed +them, and Stangerson had shot her father, which seemed to give him the +best claim; but when they argued it out in council, Drebber’s party was +the stronger, so the Prophet gave her over to him. No one won’t have +her very long though, for I saw death in her face yesterday. She is more +like a ghost than a woman. Are you off, then?" + +"Yes, I am off," said Jefferson Hope, who had risen from his seat. His +face might have been chiselled out of marble, so hard and set was its +expression, while its eyes glowed with a baleful light. + +"Where are you going?" + +"Never mind," he answered; and, slinging his weapon over his shoulder, +strode off down the gorge and so away into the heart of the mountains to +the haunts of the wild beasts. Amongst them all there was none so fierce +and so dangerous as himself. + +The prediction of the Mormon was only too well fulfilled. Whether it was +the terrible death of her father or the effects of the hateful marriage +into which she had been forced, poor Lucy never held up her head again, +but pined away and died within a month. Her sottish husband, who had +married her principally for the sake of John Ferrier’s property, did not +affect any great grief at his bereavement; but his other wives mourned +over her, and sat up with her the night before the burial, as is the +Mormon custom. They were grouped round the bier in the early hours of +the morning, when, to their inexpressible fear and astonishment, +the door was flung open, and a savage-looking, weather-beaten man in +tattered garments strode into the room. Without a glance or a word to +the cowering women, he walked up to the white silent figure which had +once contained the pure soul of Lucy Ferrier. Stooping over her, he +pressed his lips reverently to her cold forehead, and then, snatching +up her hand, he took the wedding-ring from her finger. "She shall not be +buried in that," he cried with a fierce snarl, and before an alarm could +be raised sprang down the stairs and was gone. So strange and so brief +was the episode, that the watchers might have found it hard to believe +it themselves or persuade other people of it, had it not been for the +undeniable fact that the circlet of gold which marked her as having been +a bride had disappeared. + +For some months Jefferson Hope lingered among the mountains, leading +a strange wild life, and nursing in his heart the fierce desire for +vengeance which possessed him. Tales were told in the City of the weird +figure which was seen prowling about the suburbs, and which haunted +the lonely mountain gorges. Once a bullet whistled through Stangerson’s +window and flattened itself upon the wall within a foot of him. On +another occasion, as Drebber passed under a cliff a great boulder +crashed down on him, and he only escaped a terrible death by throwing +himself upon his face. The two young Mormons were not long in +discovering the reason of these attempts upon their lives, and led +repeated expeditions into the mountains in the hope of capturing or +killing their enemy, but always without success. Then they adopted the +precaution of never going out alone or after nightfall, and of having +their houses guarded. After a time they were able to relax these +measures, for nothing was either heard or seen of their opponent, and +they hoped that time had cooled his vindictiveness. + +Far from doing so, it had, if anything, augmented it. The hunter’s mind +was of a hard, unyielding nature, and the predominant idea of revenge +had taken such complete possession of it that there was no room for +any other emotion. He was, however, above all things practical. He soon +realized that even his iron constitution could not stand the incessant +strain which he was putting upon it. Exposure and want of wholesome food +were wearing him out. If he died like a dog among the mountains, what +was to become of his revenge then? And yet such a death was sure to +overtake him if he persisted. He felt that that was to play his enemy’s +game, so he reluctantly returned to the old Nevada mines, there to +recruit his health and to amass money enough to allow him to pursue his +object without privation. + +His intention had been to be absent a year at the most, but a +combination of unforeseen circumstances prevented his leaving the mines +for nearly five. At the end of that time, however, his memory of +his wrongs and his craving for revenge were quite as keen as on that +memorable night when he had stood by John Ferrier’s grave. Disguised, +and under an assumed name, he returned to Salt Lake City, careless +what became of his own life, as long as he obtained what he knew to +be justice. There he found evil tidings awaiting him. There had been a +schism among the Chosen People a few months before, some of the younger +members of the Church having rebelled against the authority of the +Elders, and the result had been the secession of a certain number of the +malcontents, who had left Utah and become Gentiles. Among these had been +Drebber and Stangerson; and no one knew whither they had gone. Rumour +reported that Drebber had managed to convert a large part of his +property into money, and that he had departed a wealthy man, while his +companion, Stangerson, was comparatively poor. There was no clue at all, +however, as to their whereabouts. + +Many a man, however vindictive, would have abandoned all thought of +revenge in the face of such a difficulty, but Jefferson Hope never +faltered for a moment. With the small competence he possessed, eked out +by such employment as he could pick up, he travelled from town to town +through the United States in quest of his enemies. Year passed into +year, his black hair turned grizzled, but still he wandered on, a human +bloodhound, with his mind wholly set upon the one object upon which he +had devoted his life. At last his perseverance was rewarded. It was +but a glance of a face in a window, but that one glance told him that +Cleveland in Ohio possessed the men whom he was in pursuit of. He +returned to his miserable lodgings with his plan of vengeance all +arranged. It chanced, however, that Drebber, looking from his window, +had recognized the vagrant in the street, and had read murder in +his eyes. He hurried before a justice of the peace, accompanied by +Stangerson, who had become his private secretary, and represented to him +that they were in danger of their lives from the jealousy and hatred of +an old rival. That evening Jefferson Hope was taken into custody, and +not being able to find sureties, was detained for some weeks. When at +last he was liberated, it was only to find that Drebber’s house was +deserted, and that he and his secretary had departed for Europe. + +Again the avenger had been foiled, and again his concentrated hatred +urged him to continue the pursuit. Funds were wanting, however, and +for some time he had to return to work, saving every dollar for his +approaching journey. At last, having collected enough to keep life in +him, he departed for Europe, and tracked his enemies from city to +city, working his way in any menial capacity, but never overtaking the +fugitives. When he reached St. Petersburg they had departed for Paris; +and when he followed them there he learned that they had just set off +for Copenhagen. At the Danish capital he was again a few days late, for +they had journeyed on to London, where he at last succeeded in running +them to earth. As to what occurred there, we cannot do better than quote +the old hunter’s own account, as duly recorded in Dr. Watson’s Journal, +to which we are already under such obligations. + + + + +CHAPTER VI. A CONTINUATION OF THE REMINISCENCES OF JOHN WATSON, M.D. + + +OUR prisoner’s furious resistance did not apparently indicate any +ferocity in his disposition towards ourselves, for on finding himself +powerless, he smiled in an affable manner, and expressed his hopes that +he had not hurt any of us in the scuffle. "I guess you’re going to take +me to the police-station," he remarked to Sherlock Holmes. "My cab’s at +the door. If you’ll loose my legs I’ll walk down to it. I’m not so light +to lift as I used to be." + +Gregson and Lestrade exchanged glances as if they thought this +proposition rather a bold one; but Holmes at once took the prisoner at +his word, and loosened the towel which we had bound round his ancles. +[23] He rose and stretched his legs, as though to assure himself that +they were free once more. I remember that I thought to myself, as I eyed +him, that I had seldom seen a more powerfully built man; and his dark +sunburned face bore an expression of determination and energy which was +as formidable as his personal strength. + +"If there’s a vacant place for a chief of the police, I reckon you +are the man for it," he said, gazing with undisguised admiration at my +fellow-lodger. "The way you kept on my trail was a caution." + +"You had better come with me," said Holmes to the two detectives. + +"I can drive you," said Lestrade. + +"Good! and Gregson can come inside with me. You too, Doctor, you have +taken an interest in the case and may as well stick to us." + +I assented gladly, and we all descended together. Our prisoner made no +attempt at escape, but stepped calmly into the cab which had been his, +and we followed him. Lestrade mounted the box, whipped up the horse, and +brought us in a very short time to our destination. We were ushered into +a small chamber where a police Inspector noted down our prisoner’s name +and the names of the men with whose murder he had been charged. The +official was a white-faced unemotional man, who went through his +duties in a dull mechanical way. "The prisoner will be put before the +magistrates in the course of the week," he said; "in the mean time, Mr. +Jefferson Hope, have you anything that you wish to say? I must warn you +that your words will be taken down, and may be used against you." + +"I’ve got a good deal to say," our prisoner said slowly. "I want to tell +you gentlemen all about it." + +"Hadn’t you better reserve that for your trial?" asked the Inspector. + +"I may never be tried," he answered. "You needn’t look startled. It +isn’t suicide I am thinking of. Are you a Doctor?" He turned his fierce +dark eyes upon me as he asked this last question. + +"Yes; I am," I answered. + +"Then put your hand here," he said, with a smile, motioning with his +manacled wrists towards his chest. + +I did so; and became at once conscious of an extraordinary throbbing and +commotion which was going on inside. The walls of his chest seemed to +thrill and quiver as a frail building would do inside when some powerful +engine was at work. In the silence of the room I could hear a dull +humming and buzzing noise which proceeded from the same source. + +"Why," I cried, "you have an aortic aneurism!" + +"That’s what they call it," he said, placidly. "I went to a Doctor last +week about it, and he told me that it is bound to burst before many days +passed. It has been getting worse for years. I got it from over-exposure +and under-feeding among the Salt Lake Mountains. I’ve done my work now, +and I don’t care how soon I go, but I should like to leave some account +of the business behind me. I don’t want to be remembered as a common +cut-throat." + +The Inspector and the two detectives had a hurried discussion as to the +advisability of allowing him to tell his story. + +"Do you consider, Doctor, that there is immediate danger?" the former +asked, [24] + +"Most certainly there is," I answered. + +"In that case it is clearly our duty, in the interests of justice, to +take his statement," said the Inspector. "You are at liberty, sir, to +give your account, which I again warn you will be taken down." + +"I’ll sit down, with your leave," the prisoner said, suiting the action +to the word. "This aneurism of mine makes me easily tired, and the +tussle we had half an hour ago has not mended matters. I’m on the brink +of the grave, and I am not likely to lie to you. Every word I say is the +absolute truth, and how you use it is a matter of no consequence to me." + +With these words, Jefferson Hope leaned back in his chair and began +the following remarkable statement. He spoke in a calm and methodical +manner, as though the events which he narrated were commonplace enough. +I can vouch for the accuracy of the subjoined account, for I have had +access to Lestrade’s note-book, in which the prisoner’s words were taken +down exactly as they were uttered. + +"It don’t much matter to you why I hated these men," he said; "it’s +enough that they were guilty of the death of two human beings--a father +and a daughter--and that they had, therefore, forfeited their own +lives. After the lapse of time that has passed since their crime, it was +impossible for me to secure a conviction against them in any court. I +knew of their guilt though, and I determined that I should be judge, +jury, and executioner all rolled into one. You’d have done the same, if +you have any manhood in you, if you had been in my place. + +"That girl that I spoke of was to have married me twenty years ago. She +was forced into marrying that same Drebber, and broke her heart over +it. I took the marriage ring from her dead finger, and I vowed that his +dying eyes should rest upon that very ring, and that his last thoughts +should be of the crime for which he was punished. I have carried +it about with me, and have followed him and his accomplice over two +continents until I caught them. They thought to tire me out, but they +could not do it. If I die to-morrow, as is likely enough, I die knowing +that my work in this world is done, and well done. They have perished, +and by my hand. There is nothing left for me to hope for, or to desire. + +"They were rich and I was poor, so that it was no easy matter for me to +follow them. When I got to London my pocket was about empty, and I found +that I must turn my hand to something for my living. Driving and riding +are as natural to me as walking, so I applied at a cabowner’s office, +and soon got employment. I was to bring a certain sum a week to the +owner, and whatever was over that I might keep for myself. There was +seldom much over, but I managed to scrape along somehow. The hardest job +was to learn my way about, for I reckon that of all the mazes that ever +were contrived, this city is the most confusing. I had a map beside me +though, and when once I had spotted the principal hotels and stations, I +got on pretty well. + +"It was some time before I found out where my two gentlemen were living; +but I inquired and inquired until at last I dropped across them. They +were at a boarding-house at Camberwell, over on the other side of the +river. When once I found them out I knew that I had them at my mercy. I +had grown my beard, and there was no chance of their recognizing me. +I would dog them and follow them until I saw my opportunity. I was +determined that they should not escape me again. + +"They were very near doing it for all that. Go where they would about +London, I was always at their heels. Sometimes I followed them on my +cab, and sometimes on foot, but the former was the best, for then they +could not get away from me. It was only early in the morning or late +at night that I could earn anything, so that I began to get behind hand +with my employer. I did not mind that, however, as long as I could lay +my hand upon the men I wanted. + +"They were very cunning, though. They must have thought that there was +some chance of their being followed, for they would never go out alone, +and never after nightfall. During two weeks I drove behind them every +day, and never once saw them separate. Drebber himself was drunk half +the time, but Stangerson was not to be caught napping. I watched them +late and early, but never saw the ghost of a chance; but I was not +discouraged, for something told me that the hour had almost come. My +only fear was that this thing in my chest might burst a little too soon +and leave my work undone. + +"At last, one evening I was driving up and down Torquay Terrace, as the +street was called in which they boarded, when I saw a cab drive up to +their door. Presently some luggage was brought out, and after a time +Drebber and Stangerson followed it, and drove off. I whipped up my horse +and kept within sight of them, feeling very ill at ease, for I feared +that they were going to shift their quarters. At Euston Station they +got out, and I left a boy to hold my horse, and followed them on to the +platform. I heard them ask for the Liverpool train, and the guard answer +that one had just gone and there would not be another for some hours. +Stangerson seemed to be put out at that, but Drebber was rather pleased +than otherwise. I got so close to them in the bustle that I could hear +every word that passed between them. Drebber said that he had a little +business of his own to do, and that if the other would wait for him he +would soon rejoin him. His companion remonstrated with him, and reminded +him that they had resolved to stick together. Drebber answered that the +matter was a delicate one, and that he must go alone. I could not catch +what Stangerson said to that, but the other burst out swearing, and +reminded him that he was nothing more than his paid servant, and that he +must not presume to dictate to him. On that the Secretary gave it up +as a bad job, and simply bargained with him that if he missed the last +train he should rejoin him at Halliday’s Private Hotel; to which Drebber +answered that he would be back on the platform before eleven, and made +his way out of the station. + +"The moment for which I had waited so long had at last come. I had my +enemies within my power. Together they could protect each other, +but singly they were at my mercy. I did not act, however, with undue +precipitation. My plans were already formed. There is no satisfaction in +vengeance unless the offender has time to realize who it is that strikes +him, and why retribution has come upon him. I had my plans arranged by +which I should have the opportunity of making the man who had wronged me +understand that his old sin had found him out. It chanced that some days +before a gentleman who had been engaged in looking over some houses in +the Brixton Road had dropped the key of one of them in my carriage. It +was claimed that same evening, and returned; but in the interval I had +taken a moulding of it, and had a duplicate constructed. By means of +this I had access to at least one spot in this great city where I could +rely upon being free from interruption. How to get Drebber to that house +was the difficult problem which I had now to solve. + +"He walked down the road and went into one or two liquor shops, staying +for nearly half-an-hour in the last of them. When he came out he +staggered in his walk, and was evidently pretty well on. There was a +hansom just in front of me, and he hailed it. I followed it so close +that the nose of my horse was within a yard of his driver the whole way. +We rattled across Waterloo Bridge and through miles of streets, until, +to my astonishment, we found ourselves back in the Terrace in which he +had boarded. I could not imagine what his intention was in returning +there; but I went on and pulled up my cab a hundred yards or so from +the house. He entered it, and his hansom drove away. Give me a glass of +water, if you please. My mouth gets dry with the talking." + +I handed him the glass, and he drank it down. + +"That’s better," he said. "Well, I waited for a quarter of an hour, or +more, when suddenly there came a noise like people struggling inside the +house. Next moment the door was flung open and two men appeared, one of +whom was Drebber, and the other was a young chap whom I had never seen +before. This fellow had Drebber by the collar, and when they came to +the head of the steps he gave him a shove and a kick which sent him half +across the road. ‘You hound,’ he cried, shaking his stick at him; ‘I’ll +teach you to insult an honest girl!’ He was so hot that I think he would +have thrashed Drebber with his cudgel, only that the cur staggered away +down the road as fast as his legs would carry him. He ran as far as the +corner, and then, seeing my cab, he hailed me and jumped in. ‘Drive me +to Halliday’s Private Hotel,’ said he. + +"When I had him fairly inside my cab, my heart jumped so with joy that +I feared lest at this last moment my aneurism might go wrong. I drove +along slowly, weighing in my own mind what it was best to do. I might +take him right out into the country, and there in some deserted lane +have my last interview with him. I had almost decided upon this, when he +solved the problem for me. The craze for drink had seized him again, and +he ordered me to pull up outside a gin palace. He went in, leaving word +that I should wait for him. There he remained until closing time, and +when he came out he was so far gone that I knew the game was in my own +hands. + +"Don’t imagine that I intended to kill him in cold blood. It would only +have been rigid justice if I had done so, but I could not bring myself +to do it. I had long determined that he should have a show for his life +if he chose to take advantage of it. Among the many billets which I +have filled in America during my wandering life, I was once janitor and +sweeper out of the laboratory at York College. One day the professor was +lecturing on poisions, [25] and he showed his students some alkaloid, +as he called it, which he had extracted from some South American arrow +poison, and which was so powerful that the least grain meant instant +death. I spotted the bottle in which this preparation was kept, and when +they were all gone, I helped myself to a little of it. I was a fairly +good dispenser, so I worked this alkaloid into small, soluble pills, and +each pill I put in a box with a similar pill made without the poison. +I determined at the time that when I had my chance, my gentlemen should +each have a draw out of one of these boxes, while I ate the pill that +remained. It would be quite as deadly, and a good deal less noisy than +firing across a handkerchief. From that day I had always my pill boxes +about with me, and the time had now come when I was to use them. + +"It was nearer one than twelve, and a wild, bleak night, blowing hard +and raining in torrents. Dismal as it was outside, I was glad within--so +glad that I could have shouted out from pure exultation. If any of you +gentlemen have ever pined for a thing, and longed for it during twenty +long years, and then suddenly found it within your reach, you would +understand my feelings. I lit a cigar, and puffed at it to steady my +nerves, but my hands were trembling, and my temples throbbing with +excitement. As I drove, I could see old John Ferrier and sweet Lucy +looking at me out of the darkness and smiling at me, just as plain as I +see you all in this room. All the way they were ahead of me, one on each +side of the horse until I pulled up at the house in the Brixton Road. + +"There was not a soul to be seen, nor a sound to be heard, except the +dripping of the rain. When I looked in at the window, I found Drebber +all huddled together in a drunken sleep. I shook him by the arm, ‘It’s +time to get out,’ I said. + +"‘All right, cabby,’ said he. + +"I suppose he thought we had come to the hotel that he had mentioned, +for he got out without another word, and followed me down the garden. +I had to walk beside him to keep him steady, for he was still a little +top-heavy. When we came to the door, I opened it, and led him into the +front room. I give you my word that all the way, the father and the +daughter were walking in front of us. + +"‘It’s infernally dark,’ said he, stamping about. + +"‘We’ll soon have a light,’ I said, striking a match and putting it to +a wax candle which I had brought with me. ‘Now, Enoch Drebber,’ I +continued, turning to him, and holding the light to my own face, ‘who am +I?’ + +"He gazed at me with bleared, drunken eyes for a moment, and then I +saw a horror spring up in them, and convulse his whole features, which +showed me that he knew me. He staggered back with a livid face, and I +saw the perspiration break out upon his brow, while his teeth chattered +in his head. At the sight, I leaned my back against the door and laughed +loud and long. I had always known that vengeance would be sweet, but I +had never hoped for the contentment of soul which now possessed me. + +"‘You dog!’ I said; ‘I have hunted you from Salt Lake City to St. +Petersburg, and you have always escaped me. Now, at last your wanderings +have come to an end, for either you or I shall never see to-morrow’s sun +rise.’ He shrunk still further away as I spoke, and I could see on his +face that he thought I was mad. So I was for the time. The pulses in my +temples beat like sledge-hammers, and I believe I would have had a fit +of some sort if the blood had not gushed from my nose and relieved me. + +"‘What do you think of Lucy Ferrier now?’ I cried, locking the door, and +shaking the key in his face. ‘Punishment has been slow in coming, but it +has overtaken you at last.’ I saw his coward lips tremble as I spoke. He +would have begged for his life, but he knew well that it was useless. + +"‘Would you murder me?’ he stammered. + +"‘There is no murder,’ I answered. ‘Who talks of murdering a mad dog? +What mercy had you upon my poor darling, when you dragged her from her +slaughtered father, and bore her away to your accursed and shameless +harem.’ + +"‘It was not I who killed her father,’ he cried. + +"‘But it was you who broke her innocent heart,’ I shrieked, thrusting +the box before him. ‘Let the high God judge between us. Choose and +eat. There is death in one and life in the other. I shall take what you +leave. Let us see if there is justice upon the earth, or if we are ruled +by chance.’ + +"He cowered away with wild cries and prayers for mercy, but I drew my +knife and held it to his throat until he had obeyed me. Then I swallowed +the other, and we stood facing one another in silence for a minute or +more, waiting to see which was to live and which was to die. Shall I +ever forget the look which came over his face when the first warning +pangs told him that the poison was in his system? I laughed as I saw +it, and held Lucy’s marriage ring in front of his eyes. It was but for +a moment, for the action of the alkaloid is rapid. A spasm of pain +contorted his features; he threw his hands out in front of him, +staggered, and then, with a hoarse cry, fell heavily upon the floor. I +turned him over with my foot, and placed my hand upon his heart. There +was no movement. He was dead! + +"The blood had been streaming from my nose, but I had taken no notice of +it. I don’t know what it was that put it into my head to write upon the +wall with it. Perhaps it was some mischievous idea of setting the police +upon a wrong track, for I felt light-hearted and cheerful. I remembered +a German being found in New York with RACHE written up above him, and it +was argued at the time in the newspapers that the secret societies must +have done it. I guessed that what puzzled the New Yorkers would puzzle +the Londoners, so I dipped my finger in my own blood and printed it on +a convenient place on the wall. Then I walked down to my cab and found +that there was nobody about, and that the night was still very wild. I +had driven some distance when I put my hand into the pocket in which +I usually kept Lucy’s ring, and found that it was not there. I was +thunderstruck at this, for it was the only memento that I had of her. +Thinking that I might have dropped it when I stooped over Drebber’s +body, I drove back, and leaving my cab in a side street, I went boldly +up to the house--for I was ready to dare anything rather than lose +the ring. When I arrived there, I walked right into the arms of a +police-officer who was coming out, and only managed to disarm his +suspicions by pretending to be hopelessly drunk. + +"That was how Enoch Drebber came to his end. All I had to do then was +to do as much for Stangerson, and so pay off John Ferrier’s debt. I knew +that he was staying at Halliday’s Private Hotel, and I hung about all +day, but he never came out. [26] fancy that he suspected something when +Drebber failed to put in an appearance. He was cunning, was Stangerson, +and always on his guard. If he thought he could keep me off by staying +indoors he was very much mistaken. I soon found out which was the window +of his bedroom, and early next morning I took advantage of some ladders +which were lying in the lane behind the hotel, and so made my way into +his room in the grey of the dawn. I woke him up and told him that the +hour had come when he was to answer for the life he had taken so long +before. I described Drebber’s death to him, and I gave him the same +choice of the poisoned pills. Instead of grasping at the chance of +safety which that offered him, he sprang from his bed and flew at my +throat. In self-defence I stabbed him to the heart. It would have been +the same in any case, for Providence would never have allowed his guilty +hand to pick out anything but the poison. + +"I have little more to say, and it’s as well, for I am about done up. +I went on cabbing it for a day or so, intending to keep at it until I +could save enough to take me back to America. I was standing in the +yard when a ragged youngster asked if there was a cabby there called +Jefferson Hope, and said that his cab was wanted by a gentleman at 221B, +Baker Street. I went round, suspecting no harm, and the next thing I +knew, this young man here had the bracelets on my wrists, and as neatly +snackled [27] as ever I saw in my life. That’s the whole of my story, +gentlemen. You may consider me to be a murderer; but I hold that I am +just as much an officer of justice as you are." + +So thrilling had the man’s narrative been, and his manner was so +impressive that we had sat silent and absorbed. Even the professional +detectives, _blasé_ as they were in every detail of crime, appeared to +be keenly interested in the man’s story. When he finished we sat for +some minutes in a stillness which was only broken by the scratching +of Lestrade’s pencil as he gave the finishing touches to his shorthand +account. + +"There is only one point on which I should like a little more +information," Sherlock Holmes said at last. "Who was your accomplice who +came for the ring which I advertised?" + +The prisoner winked at my friend jocosely. "I can tell my own secrets," + he said, "but I don’t get other people into trouble. I saw your +advertisement, and I thought it might be a plant, or it might be the +ring which I wanted. My friend volunteered to go and see. I think you’ll +own he did it smartly." + +"Not a doubt of that," said Holmes heartily. + +"Now, gentlemen," the Inspector remarked gravely, "the forms of the law +must be complied with. On Thursday the prisoner will be brought before +the magistrates, and your attendance will be required. Until then I will +be responsible for him." He rang the bell as he spoke, and Jefferson +Hope was led off by a couple of warders, while my friend and I made our +way out of the Station and took a cab back to Baker Street. + + + + +CHAPTER VII. THE CONCLUSION. + + +WE had all been warned to appear before the magistrates upon the +Thursday; but when the Thursday came there was no occasion for our +testimony. A higher Judge had taken the matter in hand, and Jefferson +Hope had been summoned before a tribunal where strict justice would +be meted out to him. On the very night after his capture the aneurism +burst, and he was found in the morning stretched upon the floor of the +cell, with a placid smile upon his face, as though he had been able +in his dying moments to look back upon a useful life, and on work well +done. + +"Gregson and Lestrade will be wild about his death," Holmes remarked, as +we chatted it over next evening. "Where will their grand advertisement +be now?" + +"I don’t see that they had very much to do with his capture," I +answered. + +"What you do in this world is a matter of no consequence," returned my +companion, bitterly. "The question is, what can you make people believe +that you have done. Never mind," he continued, more brightly, after a +pause. "I would not have missed the investigation for anything. There +has been no better case within my recollection. Simple as it was, there +were several most instructive points about it." + +"Simple!" I ejaculated. + +"Well, really, it can hardly be described as otherwise," said Sherlock +Holmes, smiling at my surprise. "The proof of its intrinsic simplicity +is, that without any help save a few very ordinary deductions I was able +to lay my hand upon the criminal within three days." + +"That is true," said I. + +"I have already explained to you that what is out of the common is +usually a guide rather than a hindrance. In solving a problem of this +sort, the grand thing is to be able to reason backwards. That is a very +useful accomplishment, and a very easy one, but people do not practise +it much. In the every-day affairs of life it is more useful to reason +forwards, and so the other comes to be neglected. There are fifty who +can reason synthetically for one who can reason analytically." + +"I confess," said I, "that I do not quite follow you." + +"I hardly expected that you would. Let me see if I can make it clearer. +Most people, if you describe a train of events to them, will tell you +what the result would be. They can put those events together in their +minds, and argue from them that something will come to pass. There are +few people, however, who, if you told them a result, would be able to +evolve from their own inner consciousness what the steps were which led +up to that result. This power is what I mean when I talk of reasoning +backwards, or analytically." + +"I understand," said I. + +"Now this was a case in which you were given the result and had to +find everything else for yourself. Now let me endeavour to show you the +different steps in my reasoning. To begin at the beginning. I approached +the house, as you know, on foot, and with my mind entirely free from all +impressions. I naturally began by examining the roadway, and there, as I +have already explained to you, I saw clearly the marks of a cab, which, +I ascertained by inquiry, must have been there during the night. I +satisfied myself that it was a cab and not a private carriage by the +narrow gauge of the wheels. The ordinary London growler is considerably +less wide than a gentleman’s brougham. + +"This was the first point gained. I then walked slowly down the garden +path, which happened to be composed of a clay soil, peculiarly suitable +for taking impressions. No doubt it appeared to you to be a mere +trampled line of slush, but to my trained eyes every mark upon its +surface had a meaning. There is no branch of detective science which +is so important and so much neglected as the art of tracing footsteps. +Happily, I have always laid great stress upon it, and much practice +has made it second nature to me. I saw the heavy footmarks of the +constables, but I saw also the track of the two men who had first passed +through the garden. It was easy to tell that they had been before the +others, because in places their marks had been entirely obliterated by +the others coming upon the top of them. In this way my second link was +formed, which told me that the nocturnal visitors were two in number, +one remarkable for his height (as I calculated from the length of his +stride), and the other fashionably dressed, to judge from the small and +elegant impression left by his boots. + +"On entering the house this last inference was confirmed. My well-booted +man lay before me. The tall one, then, had done the murder, if murder +there was. There was no wound upon the dead man’s person, but the +agitated expression upon his face assured me that he had foreseen his +fate before it came upon him. Men who die from heart disease, or any +sudden natural cause, never by any chance exhibit agitation upon their +features. Having sniffed the dead man’s lips I detected a slightly sour +smell, and I came to the conclusion that he had had poison forced upon +him. Again, I argued that it had been forced upon him from the hatred +and fear expressed upon his face. By the method of exclusion, I had +arrived at this result, for no other hypothesis would meet the facts. +Do not imagine that it was a very unheard of idea. The forcible +administration of poison is by no means a new thing in criminal annals. +The cases of Dolsky in Odessa, and of Leturier in Montpellier, will +occur at once to any toxicologist. + +"And now came the great question as to the reason why. Robbery had not +been the object of the murder, for nothing was taken. Was it politics, +then, or was it a woman? That was the question which confronted me. +I was inclined from the first to the latter supposition. Political +assassins are only too glad to do their work and to fly. This murder +had, on the contrary, been done most deliberately, and the perpetrator +had left his tracks all over the room, showing that he had been there +all the time. It must have been a private wrong, and not a political +one, which called for such a methodical revenge. When the inscription +was discovered upon the wall I was more inclined than ever to my +opinion. The thing was too evidently a blind. When the ring was found, +however, it settled the question. Clearly the murderer had used it to +remind his victim of some dead or absent woman. It was at this point +that I asked Gregson whether he had enquired in his telegram to +Cleveland as to any particular point in Mr. Drebber’s former career. He +answered, you remember, in the negative. + +"I then proceeded to make a careful examination of the room, which +confirmed me in my opinion as to the murderer’s height, and furnished me +with the additional details as to the Trichinopoly cigar and the length +of his nails. I had already come to the conclusion, since there were no +signs of a struggle, that the blood which covered the floor had burst +from the murderer’s nose in his excitement. I could perceive that the +track of blood coincided with the track of his feet. It is seldom that +any man, unless he is very full-blooded, breaks out in this way through +emotion, so I hazarded the opinion that the criminal was probably a +robust and ruddy-faced man. Events proved that I had judged correctly. + +"Having left the house, I proceeded to do what Gregson had neglected. I +telegraphed to the head of the police at Cleveland, limiting my enquiry +to the circumstances connected with the marriage of Enoch Drebber. The +answer was conclusive. It told me that Drebber had already applied for +the protection of the law against an old rival in love, named Jefferson +Hope, and that this same Hope was at present in Europe. I knew now that +I held the clue to the mystery in my hand, and all that remained was to +secure the murderer. + +"I had already determined in my own mind that the man who had walked +into the house with Drebber, was none other than the man who had driven +the cab. The marks in the road showed me that the horse had wandered +on in a way which would have been impossible had there been anyone in +charge of it. Where, then, could the driver be, unless he were inside +the house? Again, it is absurd to suppose that any sane man would carry +out a deliberate crime under the very eyes, as it were, of a third +person, who was sure to betray him. Lastly, supposing one man wished +to dog another through London, what better means could he adopt than +to turn cabdriver. All these considerations led me to the irresistible +conclusion that Jefferson Hope was to be found among the jarveys of the +Metropolis. + +"If he had been one there was no reason to believe that he had ceased to +be. On the contrary, from his point of view, any sudden change would be +likely to draw attention to himself. He would, probably, for a time at +least, continue to perform his duties. There was no reason to suppose +that he was going under an assumed name. Why should he change his name +in a country where no one knew his original one? I therefore organized +my Street Arab detective corps, and sent them systematically to every +cab proprietor in London until they ferreted out the man that I wanted. +How well they succeeded, and how quickly I took advantage of it, are +still fresh in your recollection. The murder of Stangerson was an +incident which was entirely unexpected, but which could hardly in +any case have been prevented. Through it, as you know, I came into +possession of the pills, the existence of which I had already surmised. +You see the whole thing is a chain of logical sequences without a break +or flaw." + +"It is wonderful!" I cried. "Your merits should be publicly recognized. +You should publish an account of the case. If you won’t, I will for +you." + +"You may do what you like, Doctor," he answered. "See here!" he +continued, handing a paper over to me, "look at this!" + +It was the _Echo_ for the day, and the paragraph to which he pointed was +devoted to the case in question. + +"The public," it said, "have lost a sensational treat through the sudden +death of the man Hope, who was suspected of the murder of Mr. Enoch +Drebber and of Mr. Joseph Stangerson. The details of the case will +probably be never known now, though we are informed upon good authority +that the crime was the result of an old standing and romantic feud, in +which love and Mormonism bore a part. It seems that both the victims +belonged, in their younger days, to the Latter Day Saints, and Hope, the +deceased prisoner, hails also from Salt Lake City. If the case has had +no other effect, it, at least, brings out in the most striking manner +the efficiency of our detective police force, and will serve as a lesson +to all foreigners that they will do wisely to settle their feuds at +home, and not to carry them on to British soil. It is an open secret +that the credit of this smart capture belongs entirely to the well-known +Scotland Yard officials, Messrs. Lestrade and Gregson. The man was +apprehended, it appears, in the rooms of a certain Mr. Sherlock Holmes, +who has himself, as an amateur, shown some talent in the detective +line, and who, with such instructors, may hope in time to attain to some +degree of their skill. It is expected that a testimonial of some sort +will be presented to the two officers as a fitting recognition of their +services." + +"Didn’t I tell you so when we started?" cried Sherlock Holmes with a +laugh. "That’s the result of all our Study in Scarlet: to get them a +testimonial!" + +"Never mind," I answered, "I have all the facts in my journal, and the +public shall know them. In the meantime you must make yourself contented +by the consciousness of success, like the Roman miser-- + + "‘Populus me sibilat, at mihi plaudo + Ipse domi simul ac nummos contemplor in arca.’" + + + + + +ORIGINAL TRANSCRIBER’S NOTES: + + +[Footnote 1: Frontispiece, with the caption: "He examined with his glass +the word upon the wall, going over every letter of it with the most +minute exactness." (_Page_ 23.)] + +[Footnote 2: "JOHN H. WATSON, M.D.": the initial letters in the name are +capitalized, the other letters in small caps. All chapter titles are in +small caps. The initial words of chapters are in small caps with first +letter capitalized.] + +[Footnote 3: "lodgings.": the period should be a comma, as in later +editions.] + +[Footnote 4: "hoemoglobin": should be haemoglobin. The o&e are +concatenated.] + +[Footnote 5: "221B": the B is in small caps] + +[Footnote 6: "THE LAURISTON GARDEN MYSTERY": the table-of-contents +lists this chapter as "...GARDENS MYSTERY"--plural, and probably more +correct.] + +[Footnote 7: "brought."": the text has an extra double-quote mark] + +[Footnote 8: "individual--": illustration this page, with the +caption: "As he spoke, his nimble fingers were flying here, there, and +everywhere."] + +[Footnote 9: "manoeuvres": the o&e are concatenated.] + +[Footnote 10: "Patent leathers": the hyphen is missing.] + +[Footnote 11: "condonment": should be condonement.] + +[Footnote 13: "wages.": ending quote is missing.] + +[Footnote 14: "the first.": ending quote is missing.] + +[Footnote 15: "make much of...": Other editions complete this sentence +with an "it." But there is a gap in the text at this point, and, given +the context, it may have actually been an interjection, a dash. The gap +is just the right size for the characters "it." and the start of a new +sentence, or for a "----"] + +[Footnote 16: "tho cushion": "tho" should be "the"] + +[Footnote 19: "shoving": later editions have "showing". The original is +clearly superior.] + +[Footnote 20: "stared about...": illustration, with the caption: "One of +them seized the little girl, and hoisted her upon his shoulder."] + +[Footnote 21: "upon the": illustration, with the caption: "As he watched +it he saw it writhe along the ground."] + +[Footnote 22: "FORMERLY...": F,S,L,C in caps, other letters in this line +in small caps.] + +[Footnote 23: "ancles": ankles.] + +[Footnote 24: "asked,": should be "asked."] + +[Footnote 25: "poisions": should be "poisons"] + +[Footnote 26: "...fancy": should be "I fancy". There is a gap in the +text.] + +[Footnote 27: "snackled": "shackled" in later texts.] + +[Footnote 29: Heber C. Kemball, in one of his sermons, alludes to his +hundred wives under this endearing epithet.] + + + + + +End of Project Gutenberg’s A Study In Scarlet, by Arthur Conan Doyle + +*** END OF THIS PROJECT GUTENBERG EBOOK A STUDY IN SCARLET *** + +***** This file should be named 244-0.txt or 244-0.zip ***** +This and all associated files of various formats will be found in: + http://www.gutenberg.org/2/4/244/ + +Produced by Roger Squires + +Updated editions will replace the previous one--the old editions +will be renamed. + +Creating the works from public domain print editions means that no +one owns a United States copyright in these works, so the Foundation +(and you!) can copy and distribute it in the United States without +permission and without paying copyright royalties. Special rules, +set forth in the General Terms of Use part of this license, apply to +copying and distributing Project Gutenberg-tm electronic works to +protect the PROJECT GUTENBERG-tm concept and trademark. Project +Gutenberg is a registered trademark, and may not be used if you +charge for the eBooks, unless you receive specific permission. If you +do not charge anything for copies of this eBook, complying with the +rules is very easy. You may use this eBook for nearly any purpose +such as creation of derivative works, reports, performances and +research. They may be modified and printed and given away--you may do +practically ANYTHING with public domain eBooks. Redistribution is +subject to the trademark license, especially commercial +redistribution. + + + +*** START: FULL LICENSE *** + +THE FULL PROJECT GUTENBERG LICENSE +PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK + +To protect the Project Gutenberg-tm mission of promoting the free +distribution of electronic works, by using or distributing this work +(or any other work associated in any way with the phrase "Project +Gutenberg"), you agree to comply with all the terms of the Full Project +Gutenberg-tm License (available with this file or online at +http://gutenberg.org/license). + + +Section 1. General Terms of Use and Redistributing Project Gutenberg-tm +electronic works + +1.A. By reading or using any part of this Project Gutenberg-tm +electronic work, you indicate that you have read, understand, agree to +and accept all the terms of this license and intellectual property +(trademark/copyright) agreement. If you do not agree to abide by all +the terms of this agreement, you must cease using and return or destroy +all copies of Project Gutenberg-tm electronic works in your possession. +If you paid a fee for obtaining a copy of or access to a Project +Gutenberg-tm electronic work and you do not agree to be bound by the +terms of this agreement, you may obtain a refund from the person or +entity to whom you paid the fee as set forth in paragraph 1.E.8. + +1.B. "Project Gutenberg" is a registered trademark. It may only be +used on or associated in any way with an electronic work by people who +agree to be bound by the terms of this agreement. There are a few +things that you can do with most Project Gutenberg-tm electronic works +even without complying with the full terms of this agreement. See +paragraph 1.C below. There are a lot of things you can do with Project +Gutenberg-tm electronic works if you follow the terms of this agreement +and help preserve free future access to Project Gutenberg-tm electronic +works. See paragraph 1.E below. + +1.C. The Project Gutenberg Literary Archive Foundation ("the Foundation" + or PGLAF), owns a compilation copyright in the collection of Project +Gutenberg-tm electronic works. Nearly all the individual works in the +collection are in the public domain in the United States. If an +individual work is in the public domain in the United States and you are +located in the United States, we do not claim a right to prevent you from +copying, distributing, performing, displaying or creating derivative +works based on the work as long as all references to Project Gutenberg +are removed. Of course, we hope that you will support the Project +Gutenberg-tm mission of promoting free access to electronic works by +freely sharing Project Gutenberg-tm works in compliance with the terms of +this agreement for keeping the Project Gutenberg-tm name associated with +the work. You can easily comply with the terms of this agreement by +keeping this work in the same format with its attached full Project +Gutenberg-tm License when you share it without charge with others. + +1.D. The copyright laws of the place where you are located also govern +what you can do with this work. Copyright laws in most countries are in +a constant state of change. If you are outside the United States, check +the laws of your country in addition to the terms of this agreement +before downloading, copying, displaying, performing, distributing or +creating derivative works based on this work or any other Project +Gutenberg-tm work. The Foundation makes no representations concerning +the copyright status of any work in any country outside the United +States. + +1.E. Unless you have removed all references to Project Gutenberg: + +1.E.1. The following sentence, with active links to, or other immediate +access to, the full Project Gutenberg-tm License must appear prominently +whenever any copy of a Project Gutenberg-tm work (any work on which the +phrase "Project Gutenberg" appears, or with which the phrase "Project +Gutenberg" is associated) is accessed, displayed, performed, viewed, +copied or distributed: + +This eBook is for the use of anyone anywhere at no cost and with +almost no restrictions whatsoever. You may copy it, give it away or +re-use it under the terms of the Project Gutenberg License included +with this eBook or online at www.gutenberg.org + +1.E.2. If an individual Project Gutenberg-tm electronic work is derived +from the public domain (does not contain a notice indicating that it is +posted with permission of the copyright holder), the work can be copied +and distributed to anyone in the United States without paying any fees +or charges. If you are redistributing or providing access to a work +with the phrase "Project Gutenberg" associated with or appearing on the +work, you must comply either with the requirements of paragraphs 1.E.1 +through 1.E.7 or obtain permission for the use of the work and the +Project Gutenberg-tm trademark as set forth in paragraphs 1.E.8 or +1.E.9. + +1.E.3. If an individual Project Gutenberg-tm electronic work is posted +with the permission of the copyright holder, your use and distribution +must comply with both paragraphs 1.E.1 through 1.E.7 and any additional +terms imposed by the copyright holder. Additional terms will be linked +to the Project Gutenberg-tm License for all works posted with the +permission of the copyright holder found at the beginning of this work. + +1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm +License terms from this work, or any files containing a part of this +work or any other work associated with Project Gutenberg-tm. + +1.E.5. Do not copy, display, perform, distribute or redistribute this +electronic work, or any part of this electronic work, without +prominently displaying the sentence set forth in paragraph 1.E.1 with +active links or immediate access to the full terms of the Project +Gutenberg-tm License. + +1.E.6. You may convert to and distribute this work in any binary, +compressed, marked up, nonproprietary or proprietary form, including any +word processing or hypertext form. However, if you provide access to or +distribute copies of a Project Gutenberg-tm work in a format other than +"Plain Vanilla ASCII" or other format used in the official version +posted on the official Project Gutenberg-tm web site (www.gutenberg.org), +you must, at no additional cost, fee or expense to the user, provide a +copy, a means of exporting a copy, or a means of obtaining a copy upon +request, of the work in its original "Plain Vanilla ASCII" or other +form. Any alternate format must include the full Project Gutenberg-tm +License as specified in paragraph 1.E.1. + +1.E.7. Do not charge a fee for access to, viewing, displaying, +performing, copying or distributing any Project Gutenberg-tm works +unless you comply with paragraph 1.E.8 or 1.E.9. + +1.E.8. You may charge a reasonable fee for copies of or providing +access to or distributing Project Gutenberg-tm electronic works provided +that + +- You pay a royalty fee of 20% of the gross profits you derive from + the use of Project Gutenberg-tm works calculated using the method + you already use to calculate your applicable taxes. The fee is + owed to the owner of the Project Gutenberg-tm trademark, but he + has agreed to donate royalties under this paragraph to the + Project Gutenberg Literary Archive Foundation. Royalty payments + must be paid within 60 days following each date on which you + prepare (or are legally required to prepare) your periodic tax + returns. Royalty payments should be clearly marked as such and + sent to the Project Gutenberg Literary Archive Foundation at the + address specified in Section 4, "Information about donations to + the Project Gutenberg Literary Archive Foundation." + +- You provide a full refund of any money paid by a user who notifies + you in writing (or by e-mail) within 30 days of receipt that s/he + does not agree to the terms of the full Project Gutenberg-tm + License. You must require such a user to return or + destroy all copies of the works possessed in a physical medium + and discontinue all use of and all access to other copies of + Project Gutenberg-tm works. + +- You provide, in accordance with paragraph 1.F.3, a full refund of any + money paid for a work or a replacement copy, if a defect in the + electronic work is discovered and reported to you within 90 days + of receipt of the work. + +- You comply with all other terms of this agreement for free + distribution of Project Gutenberg-tm works. + +1.E.9. If you wish to charge a fee or distribute a Project Gutenberg-tm +electronic work or group of works on different terms than are set +forth in this agreement, you must obtain permission in writing from +both the Project Gutenberg Literary Archive Foundation and Michael +Hart, the owner of the Project Gutenberg-tm trademark. Contact the +Foundation as set forth in Section 3 below. + +1.F. + +1.F.1. Project Gutenberg volunteers and employees expend considerable +effort to identify, do copyright research on, transcribe and proofread +public domain works in creating the Project Gutenberg-tm +collection. Despite these efforts, Project Gutenberg-tm electronic +works, and the medium on which they may be stored, may contain +"Defects," such as, but not limited to, incomplete, inaccurate or +corrupt data, transcription errors, a copyright or other intellectual +property infringement, a defective or damaged disk or other medium, a +computer virus, or computer codes that damage or cannot be read by +your equipment. + +1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the "Right +of Replacement or Refund" described in paragraph 1.F.3, the Project +Gutenberg Literary Archive Foundation, the owner of the Project +Gutenberg-tm trademark, and any other party distributing a Project +Gutenberg-tm electronic work under this agreement, disclaim all +liability to you for damages, costs and expenses, including legal +fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT +LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE +PROVIDED IN PARAGRAPH F3. YOU AGREE THAT THE FOUNDATION, THE +TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE +LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR +INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH +DAMAGE. + +1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a +defect in this electronic work within 90 days of receiving it, you can +receive a refund of the money (if any) you paid for it by sending a +written explanation to the person you received the work from. If you +received the work on a physical medium, you must return the medium with +your written explanation. The person or entity that provided you with +the defective work may elect to provide a replacement copy in lieu of a +refund. If you received the work electronically, the person or entity +providing it to you may choose to give you a second opportunity to +receive the work electronically in lieu of a refund. If the second copy +is also defective, you may demand a refund in writing without further +opportunities to fix the problem. + +1.F.4. Except for the limited right of replacement or refund set forth +in paragraph 1.F.3, this work is provided to you ‘AS-IS’ WITH NO OTHER +WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR ANY PURPOSE. + +1.F.5. Some states do not allow disclaimers of certain implied +warranties or the exclusion or limitation of certain types of damages. +If any disclaimer or limitation set forth in this agreement violates the +law of the state applicable to this agreement, the agreement shall be +interpreted to make the maximum disclaimer or limitation permitted by +the applicable state law. The invalidity or unenforceability of any +provision of this agreement shall not void the remaining provisions. + +1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the +trademark owner, any agent or employee of the Foundation, anyone +providing copies of Project Gutenberg-tm electronic works in accordance +with this agreement, and any volunteers associated with the production, +promotion and distribution of Project Gutenberg-tm electronic works, +harmless from all liability, costs and expenses, including legal fees, +that arise directly or indirectly from any of the following which you do +or cause to occur: (a) distribution of this or any Project Gutenberg-tm +work, (b) alteration, modification, or additions or deletions to any +Project Gutenberg-tm work, and (c) any Defect you cause. + + +Section 2. Information about the Mission of Project Gutenberg-tm + +Project Gutenberg-tm is synonymous with the free distribution of +electronic works in formats readable by the widest variety of computers +including obsolete, old, middle-aged and new computers. It exists +because of the efforts of hundreds of volunteers and donations from +people in all walks of life. + +Volunteers and financial support to provide volunteers with the +assistance they need, is critical to reaching Project Gutenberg-tm’s +goals and ensuring that the Project Gutenberg-tm collection will +remain freely available for generations to come. In 2001, the Project +Gutenberg Literary Archive Foundation was created to provide a secure +and permanent future for Project Gutenberg-tm and future generations. +To learn more about the Project Gutenberg Literary Archive Foundation +and how your efforts and donations can help, see Sections 3 and 4 +and the Foundation web page at http://www.pglaf.org. + + +Section 3. Information about the Project Gutenberg Literary Archive +Foundation + +The Project Gutenberg Literary Archive Foundation is a non profit +501(c)(3) educational corporation organized under the laws of the +state of Mississippi and granted tax exempt status by the Internal +Revenue Service. The Foundation’s EIN or federal tax identification +number is 64-6221541. Its 501(c)(3) letter is posted at +http://pglaf.org/fundraising. Contributions to the Project Gutenberg +Literary Archive Foundation are tax deductible to the full extent +permitted by U.S. federal laws and your state’s laws. + +The Foundation’s principal office is located at 4557 Melan Dr. S. +Fairbanks, AK, 99712., but its volunteers and employees are scattered +throughout numerous locations. Its business office is located at +809 North 1500 West, Salt Lake City, UT 84116, (801) 596-1887, email +business@pglaf.org. Email contact links and up to date contact +information can be found at the Foundation’s web site and official +page at http://pglaf.org + +For additional contact information: + Dr. Gregory B. Newby + Chief Executive and Director + gbnewby@pglaf.org + + +Section 4. Information about Donations to the Project Gutenberg +Literary Archive Foundation + +Project Gutenberg-tm depends upon and cannot survive without wide +spread public support and donations to carry out its mission of +increasing the number of public domain and licensed works that can be +freely distributed in machine readable form accessible by the widest +array of equipment including outdated equipment. Many small donations +($1 to $5,000) are particularly important to maintaining tax exempt +status with the IRS. + +The Foundation is committed to complying with the laws regulating +charities and charitable donations in all 50 states of the United +States. Compliance requirements are not uniform and it takes a +considerable effort, much paperwork and many fees to meet and keep up +with these requirements. We do not solicit donations in locations +where we have not received written confirmation of compliance. To +SEND DONATIONS or determine the status of compliance for any +particular state visit http://pglaf.org + +While we cannot and do not solicit contributions from states where we +have not met the solicitation requirements, we know of no prohibition +against accepting unsolicited donations from donors in such states who +approach us with offers to donate. + +International donations are gratefully accepted, but we cannot make +any statements concerning tax treatment of donations received from +outside the United States. U.S. laws alone swamp our small staff. + +Please check the Project Gutenberg Web pages for current donation +methods and addresses. Donations are accepted in a number of other +ways including checks, online payments and credit card donations. +To donate, please visit: http://pglaf.org/donate + + +Section 5. General Information About Project Gutenberg-tm electronic +works. + +Professor Michael S. Hart is the originator of the Project Gutenberg-tm +concept of a library of electronic works that could be freely shared +with anyone. For thirty years, he produced and distributed Project +Gutenberg-tm eBooks with only a loose network of volunteer support. + + +Project Gutenberg-tm eBooks are often created from several printed +editions, all of which are confirmed as Public Domain in the U.S. +unless a copyright notice is included. Thus, we do not necessarily +keep eBooks in compliance with any particular paper edition. + + +Most people start at our Web site which has the main PG search facility: + + http://www.gutenberg.org + +This Web site includes information about Project Gutenberg-tm, +including how to make donations to the Project Gutenberg Literary +Archive Foundation, how to help produce our new eBooks, and how to +subscribe to our email newsletter to hear about new eBooks. diff --git a/scripts/sum_brute_force.py b/scripts/sum_brute_force.py new file mode 100644 index 0000000..457a997 --- /dev/null +++ b/scripts/sum_brute_force.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 8 10:23:48 2019 + + + calculate sum of 1 up to 100 + + do it the 'brute force' way + +@author: u0015831 +""" + + +sum100 = 0 + +sum100 = sum100 + 1 +sum100 = sum100 + 2 +sum100 = sum100 + 3 +sum100 = sum100 + 4 +sum100 = sum100 + 5 +sum100 = sum100 + 6 +sum100 = sum100 + 7 +sum100 = sum100 + 8 +sum100 = sum100 + 9 + +sum100 = sum100 + 10 +sum100 = sum100 + 11 +sum100 = sum100 + 12 +sum100 = sum100 + 13 +sum100 = sum100 + 14 +sum100 = sum100 + 15 +sum100 = sum100 + 16 +sum100 = sum100 + 17 +sum100 = sum100 + 18 +sum100 = sum100 + 19 + +sum100 = sum100 + 20 +sum100 = sum100 + 21 +sum100 = sum100 + 22 +sum100 = sum100 + 23 +sum100 = sum100 + 24 +sum100 = sum100 + 25 +sum100 = sum100 + 26 +sum100 = sum100 + 27 +sum100 = sum100 + 28 +sum100 = sum100 + 29 + +sum100 = sum100 + 30 +sum100 = sum100 + 31 +sum100 = sum100 + 32 +sum100 = sum100 + 33 +sum100 = sum100 + 34 +sum100 = sum100 + 35 +sum100 = sum100 + 36 +sum100 = sum100 + 37 +sum100 = sum100 + 38 +sum100 = sum100 + 39 + +sum100 = sum100 + 40 +sum100 = sum100 + 41 +sum100 = sum100 + 42 +sum100 = sum100 + 43 +sum100 = sum100 + 44 +sum100 = sum100 + 45 +sum100 = sum100 + 46 +sum100 = sum100 + 47 +sum100 = sum100 + 48 +sum100 = sum100 + 49 + +sum100 = sum100 + 50 +sum100 = sum100 + 51 +sum100 = sum100 + 52 +sum100 = sum100 + 53 +sum100 = sum100 + 54 +sum100 = sum100 + 55 +sum100 = sum100 + 56 +sum100 = sum100 + 57 +sum100 = sum100 + 58 +sum100 = sum100 + 59 + +sum100 = sum100 + 60 +sum100 = sum100 + 61 +sum100 = sum100 + 62 +sum100 = sum100 + 63 +sum100 = sum100 + 64 +sum100 = sum100 + 65 +sum100 = sum100 + 66 +sum100 = sum100 + 67 +sum100 = sum100 + 68 +sum100 = sum100 + 69 + +sum100 = sum100 + 70 +sum100 = sum100 + 71 +sum100 = sum100 + 72 +sum100 = sum100 + 73 +sum100 = sum100 + 74 +sum100 = sum100 + 75 +sum100 = sum100 + 76 +sum100 = sum100 + 77 +sum100 = sum100 + 78 +sum100 = sum100 + 79 + +sum100 = sum100 + 80 +sum100 = sum100 + 81 +sum100 = sum100 + 82 +sum100 = sum100 + 83 +sum100 = sum100 + 84 +sum100 = sum100 + 85 +sum100 = sum100 + 86 +sum100 = sum100 + 87 +sum100 = sum100 + 88 +sum100 = sum100 + 89 + +sum100 = sum100 + 90 +sum100 = sum100 + 91 +sum100 = sum100 + 92 +sum100 = sum100 + 93 +sum100 = sum100 + 94 +sum100 = sum100 + 95 +sum100 = sum100 + 96 +sum100 = sum100 + 97 +sum100 = sum100 + 98 +sum100 = sum100 + 99 + +sum100 = sum100 + 100 + +print('sum100 = ', sum100) diff --git a/scripts/sum_for_loop.py b/scripts/sum_for_loop.py new file mode 100644 index 0000000..b86590b --- /dev/null +++ b/scripts/sum_for_loop.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 8 12:02:55 2019 + + calculate sum of 1 up to 100 + + do it with a for loop + +@author: u0015831 +""" +sum100 = 0 + +for i in range(1,101): + sum100 = sum100 + i + +print('sum100 = ', sum100) \ No newline at end of file diff --git a/scripts/sum_while_loop.py b/scripts/sum_while_loop.py new file mode 100644 index 0000000..f7f55f6 --- /dev/null +++ b/scripts/sum_while_loop.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 8 12:12:03 2019 + + calculate sum of 1 up to 100 + + do it with a while loop + +@author: u0015831 +""" + +sum100 = 0 +i = 1 + +while i <= 100 : + sum100 = sum100 + i + i = i + 1 + +print('sum100 = ', sum100) \ No newline at end of file diff --git a/scripts/support_print.py b/scripts/support_print.py new file mode 100644 index 0000000..f421b8c --- /dev/null +++ b/scripts/support_print.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 29 12:11:46 2019 + +module containing different functions that can be used to print + +@author: u0015831 +""" + + +def print_func( name ): + print("Hello : ", name) + return + +def print_func_fancy( name ): + print("Hello My Dear: ", name) + return \ No newline at end of file diff --git a/scripts/support_print_use.py b/scripts/support_print_use.py new file mode 100644 index 0000000..a72eaec --- /dev/null +++ b/scripts/support_print_use.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 29 12:15:05 2019 + +demo 1: try to run without import + +demo 2: run the code in debug mode + +@author: u0015831 +""" + +import support_print + +support_print.print_func('Jules') + +support_print.print_func_fancy('Tom') \ No newline at end of file diff --git a/scripts/support_print_use_bis.py b/scripts/support_print_use_bis.py new file mode 100644 index 0000000..b3c7bf0 --- /dev/null +++ b/scripts/support_print_use_bis.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Nov 29 12:15:05 2019 + +demo 1: try to run without import + +demo 2: run the code in debug mode + +@author: u0015831 +""" + +from support_print import print_func +from support_print import print_func_fancy + +# no need to specify the module +print_func('Jules') + +print_func_fancy('Tom') \ No newline at end of file diff --git a/scripts/test_text.txt b/scripts/test_text.txt new file mode 100644 index 0000000..3249e31 --- /dev/null +++ b/scripts/test_text.txt @@ -0,0 +1,49 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc convallis quam nulla, in aliquam turpis venenatis vel. Praesent placerat nisl libero. Proin gravida massa quis tortor commodo rhoncus. Integer commodo dolor quis enim elementum malesuada eget eget eros. Integer tincidunt metus ac turpis tempus accumsan. Nulla facilisi. Etiam tempus imperdiet nunc, ac porta felis tempus vitae. Nulla tempus turpis arcu, ut fringilla lorem gravida eu. Mauris malesuada leo in ante mattis tristique eu non magna. Etiam quis nulla ut erat pulvinar pellentesque. Vestibulum in lorem fermentum, consectetur odio vestibulum, varius nisl. Vestibulum quis pretium arcu, id tincidunt tellus. Etiam maximus vehicula erat quis laoreet. Donec sit amet varius dolor, quis tempor mi. In in orci pretium, vestibulum ante eget, varius orci. Etiam a congue magna. + +Mauris venenatis augue ut elit mattis, non auctor arcu volutpat. Cras mollis vestibulum lorem, eu sodales metus euismod eget. Pellentesque facilisis mi nec lectus volutpat tempor at ac erat. In hac habitasse platea dictumst. Duis interdum convallis justo, eu sodales dui pharetra in. Donec vitae euismod mi. Sed sodales, sapien at posuere malesuada, purus odio dapibus elit, nec suscipit orci ante at mauris. In hac habitasse platea dictumst. + +Nunc dictum, sapien sed auctor vestibulum, leo purus laoreet purus, vel porttitor lacus arcu quis nisi. Aenean facilisis efficitur vestibulum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam congue tempus dui et consequat. Ut vestibulum, purus eget vulputate imperdiet, quam risus elementum nisi, id auctor magna ante sit amet purus. Integer ac ipsum nec diam congue finibus et nec dui. Cras mauris lacus, euismod eu condimentum eleifend, vehicula et augue. Sed nibh ipsum, fermentum ut vehicula pulvinar, iaculis at purus. In vitae metus eu diam consectetur condimentum. In mi nisi, imperdiet at accumsan iaculis, auctor in tellus. Aliquam interdum tortor a velit gravida, et elementum lectus condimentum. Nulla molestie dolor lacus, vitae luctus nunc laoreet quis. + +Aenean accumsan facilisis eros, quis molestie metus ultricies in. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate massa nec erat pulvinar, sit amet interdum ipsum lobortis. Duis diam lacus, venenatis eu mauris sollicitudin, commodo facilisis elit. Cras semper dolor vitae dui egestas, quis auctor felis vulputate. Nulla facilisi. In arcu neque, sagittis ut dui sed, gravida sodales nulla. Pellentesque mollis dui nibh, sit amet vulputate diam porta eget. Ut et tortor vel libero blandit euismod. Sed dignissim eros malesuada, convallis odio eget, consequat tellus. Etiam odio dolor, vehicula vel odio ullamcorper, rhoncus cursus dolor. In volutpat at tortor ut convallis. Sed orci nibh, gravida in neque non, laoreet ornare ante. Nulla molestie auctor finibus. Duis suscipit est aliquet blandit viverra. Pellentesque orci nisi, lobortis nec nulla et, ultrices dictum lorem. + +Curabitur commodo erat urna. Nulla suscipit lectus id libero tempor, id aliquam quam dignissim. Pellentesque non dapibus risus. Donec a augue sollicitudin, malesuada quam ut, sagittis libero. Aliquam imperdiet purus nisi, vitae scelerisque mauris aliquet auctor. Nulla orci leo, porttitor sit amet purus vel, rhoncus rutrum urna. Nullam egestas orci nibh, non malesuada dolor malesuada in. Praesent posuere, augue eget pharetra faucibus, ipsum sapien bibendum erat, sit amet scelerisque diam eros ut tortor. Sed et imperdiet lectus, eget euismod massa. Nullam vehicula velit id purus facilisis dapibus. Donec a arcu sed enim tincidunt tristique id id nunc. + +In faucibus nibh at urna sodales sodales. Suspendisse non tincidunt diam. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nunc pretium, velit et pellentesque vulputate, libero augue blandit metus, placerat varius lectus orci sed lectus. Nam ligula odio, mollis id viverra in, porttitor ac felis. Nam pellentesque, lectus id commodo lacinia, ligula elit pharetra ex, eu lacinia magna lorem id enim. Integer at arcu mi. Duis lobortis in turpis ac venenatis. Morbi facilisis auctor lacus, a vulputate magna hendrerit mollis. Duis risus mauris, interdum non orci ut, tincidunt facilisis orci. + +Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi consequat vulputate neque ullamcorper lacinia. Curabitur egestas porta tincidunt. Quisque sodales nisl velit, sit amet efficitur tellus sodales in. Phasellus a consectetur ante. Aenean in enim sapien. Vivamus et consectetur tellus. Pellentesque vitae dolor massa. Vivamus quis justo nunc. + +Curabitur interdum, erat sit amet placerat molestie, massa lectus convallis nulla, sed elementum justo justo id enim. Morbi eleifend sed massa vitae consectetur. Praesent tempus enim vitae ex efficitur, et cursus libero tristique. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis fermentum gravida odio quis tincidunt. Vivamus vitae sapien sed urna dapibus mollis. Cras tempus nibh nec tortor pulvinar condimentum. + +Aliquam vitae nisi laoreet, congue nisi vitae, consequat sem. Morbi nibh enim, tempor a varius nec, dapibus sed mauris. Proin imperdiet lectus odio, in ultricies justo aliquet in. In sollicitudin imperdiet risus, vel cursus nibh molestie eget. Mauris vitae tortor mi. Donec aliquam diam non odio suscipit dignissim. Ut fermentum et odio id ultrices. Aliquam varius sem eu eros malesuada tincidunt. Integer ullamcorper rhoncus suscipit. Praesent molestie erat molestie massa iaculis fermentum. Proin non nibh a velit scelerisque aliquam a eget dolor. Maecenas quis neque et augue suscipit finibus. Ut accumsan commodo odio, id elementum quam accumsan in. Donec nec hendrerit ante. Fusce lacus augue, viverra vitae quam et, venenatis scelerisque nisl. + +Phasellus posuere leo ante, ut sodales metus eleifend at. Suspendisse mollis justo id felis elementum interdum. Sed feugiat erat lacus, ut maximus felis euismod quis. Curabitur euismod orci sed ligula imperdiet auctor ac nec lorem. Proin magna nunc, luctus nec orci nec, facilisis elementum leo. Proin malesuada porttitor euismod. Aenean purus ligula, vehicula id accumsan in, placerat vel tellus. Praesent feugiat dapibus diam, sed eleifend mauris eleifend consectetur. Pellentesque vel sapien vel odio sodales scelerisque. Praesent vitae lacus neque. In tincidunt aliquam ultricies. Proin pellentesque molestie urna, vitae porta quam dignissim ut. Nulla blandit eu dui sit amet blandit. + +Sed malesuada euismod enim, vel dapibus enim ultrices ut. Maecenas sodales ligula dui, ac tempus velit porttitor efficitur. Integer ut condimentum sem, sit amet pharetra nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras laoreet porttitor lacus, at vulputate augue mollis sed. Ut est lacus, convallis ac blandit et, interdum nec est. Nulla elit ligula, vehicula sit amet efficitur eu, ullamcorper eu nulla. Nam condimentum porttitor magna nec facilisis. Nunc scelerisque auctor molestie. Aliquam egestas erat eget eros consectetur semper. Integer vulputate orci et posuere vestibulum. In dictum ipsum vitae justo porta sodales. Fusce non euismod odio. In hac habitasse platea dictumst. Nullam a lectus fringilla, convallis nisl nec, facilisis est. + +Nulla condimentum ipsum nisl, nec tincidunt metus sollicitudin eget. Etiam vel odio sapien. Pellentesque vitae aliquam lacus. Ut erat lorem, auctor sed quam id, porttitor aliquam orci. Ut felis odio, vulputate pretium est vel, tempus eleifend eros. Nullam in hendrerit dui. Quisque accumsan ullamcorper arcu imperdiet eleifend. Aliquam varius bibendum sapien sed placerat. Fusce lacinia vel massa et rutrum. Maecenas sed aliquam quam. Fusce eget sollicitudin turpis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis dapibus quam vitae pellentesque rutrum. Duis condimentum elit eu lectus consequat molestie. Mauris rhoncus elit ut ex rutrum eleifend. + +Cras et turpis tortor. Mauris ac condimentum quam. Integer consectetur nisi vestibulum, iaculis nibh a, auctor mauris. Maecenas molestie erat tellus, a tempus nibh commodo ac. Phasellus neque massa, ornare non dignissim sed, rhoncus egestas odio. Vestibulum venenatis pretium tortor eu mollis. In et euismod ante. Vivamus scelerisque nulla magna, vel fermentum odio accumsan in. Quisque eu laoreet nulla, sit amet lobortis odio. Morbi imperdiet, est quis convallis maximus, risus dolor viverra dui, nec congue dolor diam nec urna. Curabitur id mollis erat, in pellentesque urna. Fusce finibus eros in ipsum auctor, eget egestas leo iaculis. Etiam varius commodo eros in laoreet. + +Vestibulum vel dui justo. Pellentesque aliquam lectus non ante pulvinar, ut convallis sapien porta. Donec eget maximus magna. Integer leo orci, lacinia sit amet orci id, tempus imperdiet enim. Curabitur sit amet massa ultricies, finibus est sit amet, posuere nisi. Nulla tincidunt justo vitae fringilla mollis. Duis vel consequat sem. Nullam ac viverra quam, a egestas erat. Suspendisse nunc magna, lobortis eu blandit ac, eleifend sed magna. + +Suspendisse id arcu suscipit, suscipit sapien vel, hendrerit dui. Phasellus tincidunt nec arcu a consectetur. Duis nibh felis, condimentum ac lobortis nec, sodales non sem. Morbi condimentum ipsum sed nisi lobortis porttitor. Sed viverra, nisi ac feugiat aliquam, purus libero finibus dui, a dictum ex libero eu nibh. Donec in urna sodales, pulvinar arcu vulputate, pretium erat. Sed accumsan nunc ut auctor consectetur. Vestibulum lacus quam, faucibus sit amet augue et, porttitor aliquam dui. Sed molestie accumsan rhoncus. Nam semper vitae ipsum non dictum. + +Nulla sed odio consequat, venenatis tortor ac, mattis elit. Nam urna risus, mattis ut faucibus ut, elementum ac diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc vitae vehicula risus, vitae molestie nisi. Fusce gravida porttitor diam. Morbi ut ipsum et arcu iaculis ultricies. Curabitur dictum purus et orci tincidunt ultrices. Nullam nec fringilla dui. Curabitur non diam a nisl semper luctus non nec arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + +Donec tristique lacus eget massa malesuada, eget varius enim ultrices. Donec turpis tortor, ornare ac dolor id, fringilla accumsan dui. Nullam viverra euismod risus, a blandit orci dictum sit amet. In nulla odio, malesuada lacinia bibendum placerat, aliquam vel diam. Fusce malesuada orci id enim elementum, a blandit nisl feugiat. Curabitur dignissim rutrum ornare. Phasellus vehicula ligula eget enim pretium lobortis. Cras consequat libero eu vehicula molestie. Nullam tempor neque mauris, et imperdiet enim accumsan lacinia. Proin suscipit neque non massa rhoncus, eget imperdiet orci hendrerit. Suspendisse mollis viverra eros. Pellentesque ullamcorper orci sit amet viverra varius. + +Donec facilisis facilisis elit, non sagittis dolor suscipit vel. Ut velit eros, aliquam eget dictum quis, commodo vel nulla. Sed eget enim at erat suscipit aliquet a nec erat. Suspendisse interdum, nunc vel imperdiet gravida, metus lorem sollicitudin augue, ac hendrerit magna nibh sit amet ipsum. Donec rutrum massa lorem, ut sagittis urna iaculis ut. Fusce bibendum mauris ac diam molestie, ut scelerisque magna hendrerit. Maecenas mauris ex, lobortis a magna eget, tincidunt ullamcorper ex. Vestibulum ut malesuada dolor, non fermentum nisl. Integer eu massa convallis, bibendum nisl in, convallis est. Proin vulputate porttitor urna, consequat tincidunt dui. Nulla facilisi. In vel fringilla erat. Phasellus bibendum, orci id iaculis efficitur, lacus enim tempor nunc, ac scelerisque ante tortor eu leo. Vivamus gravida libero ac malesuada rutrum. Nulla facilisi. Morbi scelerisque finibus lorem fringilla fringilla. + +Pellentesque suscipit, leo eget volutpat ornare, odio libero dignissim turpis, et pulvinar risus justo non augue. Morbi scelerisque feugiat velit id cursus. Proin condimentum lorem vitae euismod facilisis. Praesent in luctus odio. Sed condimentum suscipit odio sed elementum. Cras pretium ultrices orci quis condimentum. Mauris tempus malesuada elementum. Sed lobortis ante ut sapien sagittis volutpat. + +Suspendisse orci sem, sodales eget laoreet at, ullamcorper in neque. Quisque ac sapien tincidunt, eleifend lorem quis, ultricies orci. Maecenas scelerisque lacus vitae neque molestie, nec semper neque malesuada. In et diam tellus. Pellentesque quis metus dolor. Fusce volutpat justo nisl, eu dignissim justo semper quis. Sed ut sagittis nibh. Vestibulum vel tempor magna, et laoreet urna. + +Nulla pretium pellentesque rhoncus. Maecenas eget ex nulla. Sed lacus nisl, lacinia in ex eget, porttitor tempor tortor. Duis et egestas orci, in maximus urna. Proin quis lorem scelerisque, vestibulum neque sit amet, porttitor erat. Mauris sit amet tristique lacus. Morbi arcu nisl, dignissim tempor lacus ut, aliquet molestie purus. Sed varius suscipit augue, ut dapibus felis posuere ac. Ut ullamcorper orci porttitor, malesuada mi a, rhoncus nisi. Suspendisse potenti. Sed sed leo eu metus tristique auctor. Ut sodales quis tellus a sollicitudin. Pellentesque ultricies luctus vulputate. Curabitur suscipit faucibus urna, sit amet commodo erat finibus sit amet. Sed aliquet nulla at erat lacinia, nec pretium felis malesuada. Pellentesque porttitor viverra viverra. + +Sed eu odio ut magna sodales sagittis. Pellentesque urna turpis, ultrices molestie libero eleifend, consectetur pretium velit. Duis malesuada magna a tortor mollis efficitur. Etiam leo nunc, mattis sed sagittis non, rhoncus sed arcu. Nulla euismod dapibus iaculis. Etiam tincidunt massa sit amet tortor varius mattis. Aliquam nisl nisi, suscipit sit amet fringilla vel, lacinia non nulla. Donec hendrerit erat sit amet dolor volutpat, id elementum tortor tempor. Nunc accumsan posuere lorem eget sollicitudin. Sed eu ligula eget libero eleifend aliquam eu vitae arcu. Suspendisse mattis diam nibh, sed molestie mi auctor faucibus. Pellentesque quis quam at justo sollicitudin volutpat. Nullam lacus nisi, luctus vitae ornare tincidunt, malesuada varius neque. Nullam a iaculis massa. Suspendisse sit amet tincidunt velit. + +Nam diam erat, vestibulum ac urna a, viverra tristique nunc. Cras mollis sollicitudin magna, ut porta nibh blandit non. Fusce vitae lacus lectus. Nunc condimentum dui ac purus pulvinar, eu maximus libero aliquam. Nulla commodo sit amet massa eu imperdiet. Donec eu laoreet velit, in ultricies metus. Nunc convallis molestie turpis, et congue dolor congue sed. Nullam auctor ullamcorper dui, ut finibus leo ullamcorper non. Sed odio turpis, egestas vitae sodales ultrices, pharetra in dui. Pellentesque quis diam sed mi consectetur consectetur. Mauris justo nulla, imperdiet at nunc in, sodales ornare tellus. Pellentesque non sollicitudin quam. Mauris nec mi suscipit, cursus sapien id, elementum est. Aenean laoreet aliquet pellentesque. Sed pellentesque augue ac dui ultrices posuere. + +Phasellus gravida ligula nec mi luctus tincidunt. Morbi tincidunt sem vitae sapien sodales congue. Cras a nisl sit amet sapien egestas tristique at sit amet erat. Sed fermentum dictum lectus, vitae fermentum dolor accumsan ut. Proin neque felis, ullamcorper id aliquam ac, malesuada vel orci. Mauris dapibus tristique velit, id commodo nulla interdum non. Sed feugiat, odio non placerat consequat, sem tellus elementum sapien, a pretium ipsum dolor sit amet ex. Sed purus nulla, rutrum vitae dui non, venenatis mattis lorem. Nullam blandit vehicula mi vitae vulputate. Mauris purus ante, elementum eu nunc scelerisque, vehicula pharetra eros. Ut dictum, magna vel consequat porta, eros ante mollis ante, quis pulvinar elit leo eget lectus. + +Maecenas ligula ante, vulputate sed nibh nec, vulputate malesuada tortor. Morbi nec varius sapien. Vivamus id mollis enim. Nunc vulputate in lorem ac viverra. Quisque viverra est sagittis vestibulum auctor. Nunc ut nisl in tellus aliquam pretium. Duis auctor, dui eget ullamcorper scelerisque, libero sapien auctor risus, ut efficitur tortor nunc nec quam. \ No newline at end of file diff --git a/scripts/testfile-write.txt b/scripts/testfile-write.txt new file mode 100644 index 0000000..ef3c5d0 --- /dev/null +++ b/scripts/testfile-write.txt @@ -0,0 +1,7 @@ +Hello WorldHello World +[0, 1, 2, 3] +0 +1 +2 +3 +0 1 2 3 01230/1/2/3/ diff --git a/scripts/testfile-writelines.txt b/scripts/testfile-writelines.txt new file mode 100644 index 0000000..7a67f52 --- /dev/null +++ b/scripts/testfile-writelines.txt @@ -0,0 +1,2 @@ +Hello WorldHello World +123 \ No newline at end of file diff --git a/scripts/testfile.txt b/scripts/testfile.txt new file mode 100644 index 0000000..d2e37e5 --- /dev/null +++ b/scripts/testfile.txt @@ -0,0 +1,37 @@ +Hello WorldHello World +[0, 1, 2, 3] +0 +1 +2 +3 +0 1 2 3 01230/1/2/3/ +10: 100 +11: 121 +12: 144 +13: 169 +14: 196 +15: 225 +16: 256 +17: 289 +18: 324 +19: 361 +10: 100 +11: 121 +12: 144 +13: 169 +14: 196 +15: 225 +16: 256 +17: 289 +18: 324 +19: 361 +10: 100 +11: 121 +12: 144 +13: 169 +14: 196 +15: 225 +16: 256 +17: 289 +18: 324 +19: 361 diff --git a/scripts/text_from_web.py b/scripts/text_from_web.py new file mode 100644 index 0000000..285d87b --- /dev/null +++ b/scripts/text_from_web.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jun 19 09:56:22 2018 + +source: https://www2.cs.duke.edu/courses/spring18/compsci101 + +read the King James Bible +count the number of characters +@author: u0015831 +""" + +import urllib.request +url = "https://www2.cs.duke.edu/csed/data/kjv10.txt" + +f = urllib.request.urlopen(url) +st = f.read().decode('utf-8') +st = st.lower() +total = len(st) +print ("total # chars = ",total) +print ("total # z’s = ",st.count("z")) +for ch in "abcdefghijklmnopqrstuvwxyz": print (ch,st.count(ch)) diff --git a/scripts/try_except_1.py b/scripts/try_except_1.py new file mode 100644 index 0000000..86ee32f --- /dev/null +++ b/scripts/try_except_1.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jul 4 10:43:53 2018 + +source: + Jake Van der Plas: A Whirlwind Tour of Python +@author: u0015831 +""" +# x = 1/0 + +try: + print("let's try something:") + x = 1 / 0 # ZeroDivisionError +except: + print("something bad happened!") \ No newline at end of file diff --git a/scripts/try_except_2.py b/scripts/try_except_2.py new file mode 100644 index 0000000..e230ce8 --- /dev/null +++ b/scripts/try_except_2.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 12 16:04:50 2023 + +source: https://www.w3schools.com/python/python_try_except.asp + + +@author: u0015831 +""" + +# You can define as many exception blocks as you want, e.g. if you want to execute a special block of code for a special kind of error +# some of the more commonly encountered ones. + +# NameError - You probably misspelled a variable or function name, or you otherwise referenced a name that was never defined. +# IOError - I/O operation failed. +# SystemError - Internal error in the Python interpreter. +# ZeroDivisionError - Second argument to a division or modulo operation was zero. + +x = 5 # put in comment to test + +try: + print(x/0) +except NameError: + print("Variable x is not defined") +except: + print("Something else went wrong") \ No newline at end of file diff --git a/scripts/tuple.ipynb b/scripts/tuple.ipynb new file mode 100644 index 0000000..c2a8a72 --- /dev/null +++ b/scripts/tuple.ipynb @@ -0,0 +1,173 @@ +{ + "metadata": { + "kernelspec": { + "name": "xpython", + "display_name": "Python 3.13 (XPython)", + "language": "python" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.13.1" + } + }, + "nbformat_minor": 4, + "nbformat": 4, + "cells": [ + { + "cell_type": "code", + "source": "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\nfrom traceback import print_exc", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "## Key concepts in programming\n\n- Variables (integers, strings, dates, etc.)\n- Flow control (if then, loop, etc.)\n- Functions (list of steps the code will follow)\n\n\n## data containers\n\nOrganize the data structure into four different families: \n- Ordered data structure: list and tuple\n- Unordered data structure: set and dictionary \n- Mutable: list, set and dictionary \n- Immutable: tuple \n\n\n| Type | Example | Description |\n|------|---------|---------|\n| list | `[1, 2, 3]` | Ordered collection|\n| tuple | `(1, 2, 3)` | Immutable ordered collection|\n| dict | `{'a':1, 'b':2, 'c':3}` | Unordered (key:value) pair mapping|\n| set | `{1, 2, 3}` | Unordered collection of unique values |\n\n\n## operations on any sequence\n\n| Operation | Operator | Description |\n|------|---------|---------|\n| indexing | `[]` | Access an element of a sequence |\n|concatenation | `+` | Combine sequences together|\n| repetition | `*` | Concatenate a repeated number of times|\n| membership | `in` | Ask whether an item is in a sequence |\n| length | `len` | Ask the number of items in the sequence|\n| slicing | `[:]` | Extract a part of a sequence |", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "# Tuples\nTuples are in many ways similar to lists, but they are defined with parentheses rather than square brackets:\n- ()\n- Tuples are defined by specifying items separated by commas\n- immutable objects, they are usually used when the list of values doesn't change\n- same slicing rules apply as for lists\n\nKey features:\n - **heterogeneous**: elements of a tuple don't have to be the same type. Each element of the tuple can be of any type.\n - **indexing**: elements can be referenced by an index. \n - **nesting**: tuples can be nested to arbitrary depth\n - **immutable**: tuples are unchangeable\n - **duplicates allowed**: tuples are indexed, items can have the same value\n\nTuples?\n- if data do not change, implementing it as tuple will guarantee that it remains write-protected.\n- tuples are immutable, iterating through tuple is faster than with list. So there is a slight performance boost.\n- tuples are frequently used to return multiple variables from functions.\n", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# tuple of strings\nmy_tuple1 = ('hi', 'hello', 'world')\nprint(my_tuple1)\n\n# tuple mixed data\nmy_tuple2 = (1, 'Hello', 3.14)\nprint(my_tuple2)\n\n# tuple of string and list\nmy_tuple3 = ('moving', [1, 2, 3, 4], ('v', 't', 'y'))\nprint(my_tuple3)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Watch out: mutable elements from a tuple can be changed", + "metadata": {} + }, + { + "cell_type": "code", + "source": "#mutable elements from a tuple can be changed\nmy_tuple3[1][0] = 100\nprint('my_tuple3', my_tuple3)\n\n# tuple with 1 element\nmy_tuple4 = (1,)\nprint(my_tuple4)\n\n# empty tuple\nmy_tuple5 = () # or tuple()\nprint(my_tuple5)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "select items from a tuple with []", + "metadata": {} + }, + { + "cell_type": "code", + "source": "#select elements out of the tuples\nprint(my_tuple1[1])\nprint(my_tuple1[1][1])\nprint(my_tuple2[1])\nprint(my_tuple3[2])\nprint(my_tuple3[2][2])\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### packing / unpacking\n\nTuples can be used to assign multiple variables in a single operation (packing)\n\nSyntax: < tuple of variables > = < tuple of values >", + "metadata": {} + }, + { + "cell_type": "code", + "source": "# The paranthesis on the left-hand-side is optional (recommended)\n(a, b, c) = (1, 2, 3)\na, b, c = (1, 2, 3)\nprint(a, b, c)\nprint(type(c))\n\n(a, b, *c) = (1, 2, 3, 4, 5)\nprint(a, b, c)\nprint(type(c))\n\n(a, *b, c) = (1, 2, 3, 4, 5)\nprint(a, b, c)\nprint(type(c))\n\n(a, b, c) = (1, 2, 3, 4, 5)\nprint(a, b, c)\nprint(type(c))\n", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "t1 = (1, 2, 'help', [1, 2, 3])\nprint(t1)\nprint(dir(t1))", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Methods\n\n- index() searches an element in a tuple and returns its index.\n- count() returns the number of items", + "metadata": {} + }, + { + "cell_type": "code", + "source": "t1 = (1, 2, 'help', [1, 2, 3])\nprint(t1)\nprint('count of 1: ', t1.count(1))\nprint('count of 3: ', t1.count(3))\n\nprint('index of 1: ', t1.index(1))\nprint('index of 3: ', t1.index(3))", + "metadata": { + "scrolled": true, + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Test membership with `in`", + "metadata": {} + }, + { + "cell_type": "code", + "source": "3 in t1", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "Delete Tuple Elements?\n\n- Removing individual tuple elements is not possible (immutability). \n- To explicitly remove an entire tuple, use the `del` statement.", + "metadata": {} + }, + { + "cell_type": "code", + "source": "t1 = (1, 2, 'help', [1, 2, 3])\n%who\ndel(t1)\n%who", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "#### advanced\n\nnamed tuple \n\n* Convenient access the tuple's fields by name, rather than by index. \n* Python's standard library defines named tuples in `collections.namedtuple` (but see also `typing.NamedTuple`).", + "metadata": {} + }, + { + "cell_type": "code", + "source": "from collections import namedtuple\n\nCar = namedtuple('Car', ['name', 'year', 'weight'])\n\nvolvo = Car('Volvo', 2026, 1.6e3)\nprint('Volvo tuple:', volvo)\nprint('Weight:', volvo.weight)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "from typing import NamedTuple\n\nclass Car(NamedTuple):\n name: str\n year: int\n weight: float\n \nvolvo = Car('Volvo', 2015, 1.6e3)\nprint('Class instance = ', volvo)\nprint('Car name = ', volvo.name)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": "lcars = [Car('Volvo', 2015, 1600), Car('VW', 2017, 1320), Car('Opel', 2011, 989)]\nprint('car 1:', lcars[0])\nprint('car 2:', lcars[1].name)", + "metadata": { + "trusted": true + }, + "outputs": [], + "execution_count": null + } + ] +} \ No newline at end of file diff --git a/scripts/ucfirst.py b/scripts/ucfirst.py new file mode 100644 index 0000000..394f9cd --- /dev/null +++ b/scripts/ucfirst.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 20:29:41 2019 +source: http://rwet.decontextualize.com/book/functions/ +example: + as standalone + python ucfirst.py >> from ucfirst import ucfirst +>>>print ucfirst("my favorite first names are Gertrude, Jehosephat and Gary") +""" + +def ucfirst(s): + return s[0].upper() + s[1:] + +if __name__ == '__main__': + import sys + for line in sys.stdin: + line = line.strip() + if len(line) > 0: + print(ucfirst(line)) + else: + print(line) \ No newline at end of file diff --git a/scripts/use_print_greet.py b/scripts/use_print_greet.py new file mode 100644 index 0000000..81c44c7 --- /dev/null +++ b/scripts/use_print_greet.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 20:56:06 2019 + +@author: u0015831 +""" + +from print_greet import print_greet + +name1 = 'Jan' +print_greet(name1) \ No newline at end of file diff --git a/scripts/use_print_greet_main.py b/scripts/use_print_greet_main.py new file mode 100644 index 0000000..4339394 --- /dev/null +++ b/scripts/use_print_greet_main.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Nov 18 20:56:06 2019 + +@author: u0015831 +""" + +from print_greet_main import print_greet + +name1 = 'Jan' +print_greet(name1) \ No newline at end of file diff --git a/scripts/variables.ipynb b/scripts/variables.ipynb new file mode 100644 index 0000000..caf7606 --- /dev/null +++ b/scripts/variables.ipynb @@ -0,0 +1,413 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Variables\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# In order to ensure that all cells in this notebook can be evaluated without errors, we will use try-except to catch exceptions. To show the actual errors, we need to print the backtrace, hence the following import.\n", + "from traceback import print_exc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Key concepts in programming\n", + "\n", + "- Variables (integers, strings, dates, etc.)\n", + "- Flow control (if then, loop, etc.)\n", + "- Functions (list of steps the code will follow)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Variables \n", + "* Variables are placeholders for locations in memory. \n", + " * Variables are names for values\n", + " * Created by use – no declaration necessary\n", + " * Python is dynamically typed, The Python interpreter infers the type based on the assigned value.\n", + "* Variables always have a type \n", + " * Variables only have data types after you use them\n", + " * Use the type function to determine variable type\n", + "* Variables have a name\n", + " * Python is case sensitive. \n", + " * myVar is different from Myvar\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Naming \n", + "Variable names in Python can contain alphanumeric characters (a-z, A-Z, 0-9) and underscores (_)\n", + "\n", + "Python is case-sensitive.\n", + "\n", + " * Avoid using names that differ only by case\n", + " * Choose meaningful names\n", + " * No leading numbers, no spaces\n", + " * Variables are generally lower case, functions are CapCase\n", + " * Don’t use Python keywords" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "password1 = 'secret'\n", + "n00b = 9.07\n", + "un_der_scores = 9\n", + "case_sensitive = 'c' \n", + "CASE_SENSITIVE = 'cc'\n", + "Case_Sensitive = 'ccc'\n", + "%whos\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# use keyword library to get the list of keywords\n", + "import keyword\n", + "keyword.kwlist" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "76trombones = 'big parade'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "more@ = 1000000" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for = 'Advanced Theoretical Physics'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Assignment\n", + "\n", + "Variables must be created (assigned a value) before they can be used\n", + "\n", + "A variable is created through assignment:\n", + "`x = 4`\n", + "\n", + "What happens?\n", + "* Python creates the object 4 \n", + "* Everything in Python is an object, this object is stored somewhere in memory. \n", + "* Python binds a name to the object. x is a reference to the object.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "chamo = 4\n", + "id(chamo)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(chamo)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = 4\n", + "print(type(a))\n", + "print(id(a))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "st1 = 'string'\n", + "dir(st1)\n", + "st1.upper()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 1 # x is an integer\n", + "print(x, id(x))\n", + "x = 'hello' # now x is a string\n", + "print(x, id(x))\n", + "x = [1, 2, 3] # now x is a list\n", + "print(x, id(x))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Python also allows chained assignment, which makes it possible to assign the same value to several variables simultaneously:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = b = c = 300\n", + "print(a, b, c)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!notepad check_variable_object.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%run check_variable_object.py" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Everything is an object:\n", + "* Some associated functionality (methods) and metadata (attributes). \n", + "* These methods and attributes are accessed via the dot(.) syntax.\n", + "* Use `type` to get information on the class\n", + "* Use `dir` to get an overview on the methods\n", + " * Many of the names in the list start and end with two underscores (dunder), like `__add__`. These are all associated with methods and pieces of data used internally by the Python interpreter. \n", + " * The remaining entries in the list are all user-level methods. \n", + "* Use `id`\n", + " * an integer (or long integer) _which is guaranteed to be unique and constant for this object during its lifetime._ (Python Standard Library - Built-in Functions) A unique number. Nothing more, and nothing less.\n", + " * in cpython implementation, it actually is the memory address of the corresponding C object." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 1 # x is an integer\n", + "y = 15\n", + "print(x)\n", + "print(x, id(x))\n", + "print(type(x))\n", + "print(dir(x))\n", + "print(x+y)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = '1' # now x is a string\n", + "y ='15'\n", + "z = 'this is a string'\n", + "print(x)\n", + "print(x, id(x))\n", + "print(type(x))\n", + "print(x+y)\n", + "\n", + "print(dir(z))\n", + "print(z)\n", + "print(z.upper())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = [1, 2, 3] # now x is a list\n", + "print(x)\n", + "print(x, id(x))\n", + "print(type(x))\n", + "print(dir(x))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a = [1, 2, 3]\n", + "print(a)\n", + "b = a\n", + "print(b)\n", + "a.append(6)\n", + "print(a)\n", + "print(b)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Mutable vs Immutable\n", + "\n", + "* Immutability: Some of Python’s data types are immutable, which means they can’t be changed after they’re created. This includes `integers`, `floats`, `strings`, and `tuples`. If you try to change the value of an immutable variable, Python actually creates a new object with the new value.\n", + "* Mutable Types: Other data types in Python are mutable, which means they can be changed after they’re created. This includes `lists`, `dictionaries`, and `sets`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Immutable\n", + "num = 5\n", + "print(num)\n", + "print(id(num)) # Let's say this prints: 140703167764848\n", + "num += 1\n", + "print(num)\n", + "print(id(num)) # This will print a different id: 140703167764880\n", + "\n", + "# Mutable\n", + "lst = [1, 2, 3]\n", + "print(lst)\n", + "print(id(lst)) # Let's say this prints: 1856906640576\n", + "lst.append(4)\n", + "print(lst)\n", + "print(id(lst)) # This will print the same id: 1856906640576\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Global and Local Variables\n", + "\n", + "* Variables defined inside a function are local to that function and cannot be accessed outside of it. \n", + "* Variables defined outside all functions are global and can be accessed anywhere in the program.\n", + "\n", + "* Local Variables:\n", + " * A local variable is declared inside a function.\n", + " * It is only accessible within the function where it is declared.\n", + " * Different functions can use the same name for different local variables.\n", + " * They are created when their function is called and destroyed when the function ends.\n", + "\n", + "* Global Variables:\n", + " * A global variable is declared outside all functions.\n", + " * It is accessible throughout the entire program, including within functions (unless a local variable with the same name exists).\n", + " * There can only be one global variable with a given name in a Python program.\n", + " * They are created when their line of code is executed and exist until the program ends." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# This is a global variable\n", + "x = 10\n", + "\n", + "def my_function():\n", + " # This is a local variable\n", + " y = 5\n", + " print(\"Inside the function, x = \", x, \"and y = \", y)\n", + "\n", + "my_function()\n", + "\n", + "# This will print: Inside the function, x = 10 and y = 5\n", + "print(\"Outside the function, x = \", x)\n", + "\n", + "# This will raise a NameError because y is not defined outside the function\n", + "print(\"Outside the function, y = \", y)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dir()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/scripts/variables_are_pointers.py b/scripts/variables_are_pointers.py new file mode 100644 index 0000000..a0decbb --- /dev/null +++ b/scripts/variables_are_pointers.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 13 14:43:22 2018 + +source: https://jakevdp.github.io/WhirlwindTourOfPython/03-semantics-variables.html + +Variables are pointers +check with id() + The identity of the object is an integer, + which is guaranteed to be the unique and constant for this object + during its lifetime. + The id() is an inbuilt function in Python. + In CPython implementation, it is an address of the object in memory. + +@author: u0015831 +""" + +#%% +x = 1 +print('x = ', x, 'id(x) = ', id(x)) +x = 'abc' +print('x = ', x, 'id(x) = ', id(x)) +x = [1, 2, 3] +print('x = ', x, 'id(x) = ', id(x)) +y = x +print('y = ', y, 'id(y) = ', id(y)) + + +#%% + +x = 'something else' +print('x = ', x, 'id(x) = ', id(x)) +print('y = ', y, 'id(y) = ', id(y)) # y is unchanged + +#%% +x = [1, 2, 3] +y = x +print('y = ', y) + +#%% +x = [1,2,3,4] +print('y = ', y) + +#%% +x = 5 +print('x = ', x, 'id(x) = ', id(x)) +y = x +print('y = ', y, 'id(y) = ', id(y)) + +x = x + 5 +print('x = ', x, 'id(x) = ', id(x)) +print('y = ', y, 'id(y) = ', id(y)) +#%% +# example with mutable list +x = [1, 2, 3] +print('x = ', x, 'id(x) = ', id(x)) +y = x +print('y = ', y, 'id(y) = ', id(y)) + +#%% +x.append(4) # append 4 to the list pointed to by x +print('x = ', x, 'id(x) = ', id(x)) +print('y = ', y, 'id(y) = ', id(y)) # y's list is modified as well! diff --git a/scripts/while_loop_1.py b/scripts/while_loop_1.py new file mode 100644 index 0000000..8f30a90 --- /dev/null +++ b/scripts/while_loop_1.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Jun 20 16:48:54 2018 + +basic while loop + +@author: u0015831 +""" + +count = 1 +while (count <= 10): + print("The count is:", count) + count = count + 1 +else: + print('count is no longer smaller than 10') +print("while loop has ended") \ No newline at end of file diff --git a/scripts/while_loop_break_continue.py b/scripts/while_loop_break_continue.py new file mode 100644 index 0000000..09b3cfe --- /dev/null +++ b/scripts/while_loop_break_continue.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +create a list with floats, +first part increment with 1 +second part incremant with an additional step size 20 + +@author: u0015831 +""" + +x=1. +L=[x] +while x>0: + x=x+1. + L.append(x) + if x >= 10000.0 : break # break out of the loop once x >= 10000 + if x <100.0 : continue # go to the next iteration when x < 100 + x=x+20.0 + +print(L) \ No newline at end of file diff --git a/slides-pdf/01-Python_intro_overview.pdf b/slides-pdf/01-Python_intro_overview.pdf new file mode 100644 index 0000000..2a15145 Binary files /dev/null and b/slides-pdf/01-Python_intro_overview.pdf differ diff --git a/slides-pdf/02-Python_intro-Setup.pdf b/slides-pdf/02-Python_intro-Setup.pdf new file mode 100644 index 0000000..f9baa93 Binary files /dev/null and b/slides-pdf/02-Python_intro-Setup.pdf differ diff --git a/slides-pdf/03-Python_intro-syntax.pdf b/slides-pdf/03-Python_intro-syntax.pdf new file mode 100644 index 0000000..05e2421 Binary files /dev/null and b/slides-pdf/03-Python_intro-syntax.pdf differ diff --git a/slides-pdf/04-Python_intro-variables_operators.pdf b/slides-pdf/04-Python_intro-variables_operators.pdf new file mode 100644 index 0000000..a294fc7 Binary files /dev/null and b/slides-pdf/04-Python_intro-variables_operators.pdf differ diff --git a/slides-pdf/05-Python_intro-builtin_datatypes.pdf b/slides-pdf/05-Python_intro-builtin_datatypes.pdf new file mode 100644 index 0000000..0af01fe Binary files /dev/null and b/slides-pdf/05-Python_intro-builtin_datatypes.pdf differ diff --git a/slides-pdf/06-Python_intro-dataContainers.pdf b/slides-pdf/06-Python_intro-dataContainers.pdf new file mode 100644 index 0000000..a2cf028 Binary files /dev/null and b/slides-pdf/06-Python_intro-dataContainers.pdf differ diff --git a/slides-pdf/07-Python_intro-control_flow.pdf b/slides-pdf/07-Python_intro-control_flow.pdf new file mode 100644 index 0000000..5c78cd7 Binary files /dev/null and b/slides-pdf/07-Python_intro-control_flow.pdf differ diff --git a/slides-pdf/08-Python_intro-functions.pdf b/slides-pdf/08-Python_intro-functions.pdf new file mode 100644 index 0000000..8d6022c Binary files /dev/null and b/slides-pdf/08-Python_intro-functions.pdf differ diff --git a/slides-pdf/09-Python_intro-io.pdf b/slides-pdf/09-Python_intro-io.pdf new file mode 100644 index 0000000..b9b80c2 Binary files /dev/null and b/slides-pdf/09-Python_intro-io.pdf differ diff --git a/slides-pdf/10-Python_intro-vsc-trainings.pdf b/slides-pdf/10-Python_intro-vsc-trainings.pdf new file mode 100644 index 0000000..df37fcc Binary files /dev/null and b/slides-pdf/10-Python_intro-vsc-trainings.pdf differ diff --git a/slides-pdf/11-Python_intro-AI-coding.pdf b/slides-pdf/11-Python_intro-AI-coding.pdf new file mode 100644 index 0000000..d06c077 Binary files /dev/null and b/slides-pdf/11-Python_intro-AI-coding.pdf differ diff --git a/slides-pptx/01-Python_intro_overview.pptx b/slides-pptx/01-Python_intro_overview.pptx new file mode 100644 index 0000000..7e9a4c1 Binary files /dev/null and b/slides-pptx/01-Python_intro_overview.pptx differ diff --git a/slides-pptx/02-Python_intro-Setup.pptx b/slides-pptx/02-Python_intro-Setup.pptx new file mode 100644 index 0000000..e04e833 Binary files /dev/null and b/slides-pptx/02-Python_intro-Setup.pptx differ diff --git a/slides-pptx/03-Python_intro-syntax.pptx b/slides-pptx/03-Python_intro-syntax.pptx new file mode 100644 index 0000000..bc8df92 Binary files /dev/null and b/slides-pptx/03-Python_intro-syntax.pptx differ diff --git a/slides-pptx/04-Python_intro-variables_operators.pptx b/slides-pptx/04-Python_intro-variables_operators.pptx new file mode 100644 index 0000000..a245144 Binary files /dev/null and b/slides-pptx/04-Python_intro-variables_operators.pptx differ diff --git a/slides-pptx/05-Python_intro-builtin_datatypes.pptx b/slides-pptx/05-Python_intro-builtin_datatypes.pptx new file mode 100644 index 0000000..8777a71 Binary files /dev/null and b/slides-pptx/05-Python_intro-builtin_datatypes.pptx differ diff --git a/slides-pptx/06-Python_intro-dataContainers.pptx b/slides-pptx/06-Python_intro-dataContainers.pptx new file mode 100644 index 0000000..4a13045 Binary files /dev/null and b/slides-pptx/06-Python_intro-dataContainers.pptx differ diff --git a/slides-pptx/07-Python_intro-control_flow.pptx b/slides-pptx/07-Python_intro-control_flow.pptx new file mode 100644 index 0000000..f094ce1 Binary files /dev/null and b/slides-pptx/07-Python_intro-control_flow.pptx differ diff --git a/slides-pptx/08-Python_intro-functions.pptx b/slides-pptx/08-Python_intro-functions.pptx new file mode 100644 index 0000000..d7f9aa1 Binary files /dev/null and b/slides-pptx/08-Python_intro-functions.pptx differ diff --git a/slides-pptx/09-Python_intro-io.pptx b/slides-pptx/09-Python_intro-io.pptx new file mode 100644 index 0000000..02effe3 Binary files /dev/null and b/slides-pptx/09-Python_intro-io.pptx differ diff --git a/slides-pptx/10-Python_intro-vsc-trainings.pptx b/slides-pptx/10-Python_intro-vsc-trainings.pptx new file mode 100644 index 0000000..eeccff0 Binary files /dev/null and b/slides-pptx/10-Python_intro-vsc-trainings.pptx differ diff --git a/slides-pptx/11-Python_intro-AI-coding.pptx b/slides-pptx/11-Python_intro-AI-coding.pptx new file mode 100644 index 0000000..d8a49ef Binary files /dev/null and b/slides-pptx/11-Python_intro-AI-coding.pptx differ