# Notebook from RahulSinghod/madewithml
Path: notebooks/05_PyTorch.ipynb

 Made With ML

Applied ML · MLOps · Production

Join 20K+ developers in learning how to responsibly deliver value with applied ML.

🔥  Among the top ML repositories on GitHub

_____no_output_____# PyTorch

In this notebook, we'll learn the basics of [PyTorch](https://pytorch.org), which is a machine learning library used to build dynamic neural networks. We'll learn about the basics, like creating and using Tensors. _____no_output_____

_____no_output_____# Set up_____no_output_____

import numpy as np
import torch_____no_output_____SEED = 1234_____no_output_____# Set seed for reproducibility
np.random.seed(seed=SEED)
torch.manual_seed(SEED)_____no_output_____

# Basics_____no_output_____

# Creating a random tensor
x = torch.randn(2, 3) # normal distribution (rand(2,3) -> uniform distribution)
print(f"Type: {x.type()}")
print(f"Size: {x.shape}")
print(f"Values: \n{x}")Type: torch.FloatTensor
Size: torch.Size([2, 3])
Values:
tensor([[ 0.0461,  0.4024, -1.0115],
        [ 0.2167, -0.6123,  0.5036]])
# Zero and Ones tensor
x = torch.zeros(2, 3)
print (x)
x = torch.ones(2, 3)
print (x)tensor([[0., 0., 0.],
        [0., 0., 0.]])
tensor([[1., 1., 1.],
        [1., 1., 1.]])
# List → Tensor
x = torch.Tensor([[1, 2, 3],[4, 5, 6]])
print(f"Size: {x.shape}")
print(f"Values: \n{x}")Size: torch.Size([2, 3])
Values:
tensor([[1., 2., 3.],
        [4., 5., 6.]])
# NumPy array → Tensor
x = torch.Tensor(np.random.rand(2, 3))
print(f"Size: {x.shape}")
print(f"Values: \n{x}")Size: torch.Size([2, 3])
Values:
tensor([[0.1915, 0.6221, 0.4377],
        [0.7854, 0.7800, 0.2726]])
# Changing tensor type
x = torch.Tensor(3, 4)
print(f"Type: {x.type()}")
x = x.long()
print(f"Type: {x.type()}")Type: torch.FloatTensor
Type: torch.LongTensor

# Operations_____no_output_____

# Addition
x = torch.randn(2, 3)
y = torch.randn(2, 3)
z = x + y
print(f"Size: {z.shape}")
print(f"Values: \n{z}")Size: torch.Size([2, 3])
Values:
tensor([[ 0.0761, -0.6775, -0.3988],
        [ 3.0633, -0.1589,  0.3514]])
# Dot product
x = torch.randn(2, 3)
y = torch.randn(3, 2)
z = torch.mm(x, y)
print(f"Size: {z.shape}")
print(f"Values: \n{z}")Size: torch.Size([2, 2])
Values:
tensor([[ 1.0796, -0.0759],
        [ 1.2746, -0.5134]])
# Transpose
x = torch.randn(2, 3)
print(f"Size: {x.shape}")
print(f"Values: \n{x}")
y = torch.t(x)
print(f"Size: {y.shape}")
print(f"Values: \n{y}")Size: torch.Size([2, 3])
Values:
tensor([[ 0.8042, -0.1383,  0.3196],
        [-1.0187, -1.3147,  2.5228]])
Size: torch.Size([3, 2])
Values:
tensor([[ 0.8042, -1.0187],
        [-0.1383, -1.3147],
        [ 0.3196,  2.5228]])
# Reshape
x = torch.randn(2, 3)
z = x.view(3, 2)
print(f"Size: {z.shape}")
print(f"Values: \n{z}")Size: torch.Size([3, 2])
Values:
tensor([[ 0.4501,  0.2709],
        [-0.8087, -0.0217],
        [-1.0413,  0.0702]])
# Dangers of reshaping (unintended consequences)
x = torch.tensor([
    [[1,1,1,1], [2,2,2,2], [3,3,3,3]],
    [[10,10,10,10], [20,20,20,20], [30,30,30,30]]
])
print(f"Size: {x.shape}")
print(f"x: \n{x}\n")

a = x.view(x.size(1), -1)
print(f"\nSize: {a.shape}")
print(f"a: \n{a}\n")

b = x.transpose(0,1).contiguous()
print(f"\nSize: {b.shape}")
print(f"b: \n{b}\n")

c = b.view(b.size(0), -1)
print(f"\nSize: {c.shape}")
print(f"c: \n{c}")Size: torch.Size([2, 3, 4])
x:
tensor([[[ 1,  1,  1,  1],
         [ 2,  2,  2,  2],
         [ 3,  3,  3,  3]],

        [[10, 10, 10, 10],
         [20, 20, 20, 20],
         [30, 30, 30, 30]]])

Size: torch.Size([3, 8])
a:
tensor([[ 1,  1,  1,  1,  2,  2,  2,  2],
        [ 3,  3,  3,  3, 10, 10, 10, 10],
        [20, 20, 20, 20, 30, 30, 30, 30]])

Size: torch.Size([3, 2, 4])
b:
tensor([[[ 1,  1,  1,  1],
         [10, 10, 10, 10]],

        [[ 2,  2,  2,  2],
         [20, 20, 20, 20]],

        [[ 3,  3,  3,  3],
         [30, 30, 30, 30]]])

Size: torch.Size([3, 8])
c:
tensor([[ 1,  1,  1,  1, 10, 10, 10, 10],
        [ 2,  2,  2,  2, 20, 20, 20, 20],
        [ 3,  3,  3,  3, 30, 30, 30, 30]])
# Dimensional operations
x = torch.randn(2, 3)
print(f"Values: \n{x}")
y = torch.sum(x, dim=0) # add each row's value for every column
print(f"Values: \n{y}")
z = torch.sum(x, dim=1) # add each columns's value for every row
print(f"Values: \n{z}")Values:
tensor([[ 0.5797, -0.0599,  0.1816],
        [-0.6797, -0.2567, -1.8189]])
Values:
tensor([-0.1000, -0.3166, -1.6373])
Values:
tensor([ 0.7013, -2.7553])

# Indexing, Splicing and Joining_____no_output_____

x = torch.randn(3, 4)
print (f"x: \n{x}")
print (f"x[:1]: \n{x[:1]}")
print (f"x[:1, 1:3]: \n{x[:1, 1:3]}")x:
tensor([[ 0.2111,  0.3372,  0.6638,  1.0397],
        [ 1.8434,  0.6588, -0.2349, -0.0306],
        [ 1.7462, -0.0722, -1.6794, -1.7010]])
x[:1]:
tensor([[0.2111, 0.3372, 0.6638, 1.0397]])
x[:1, 1:3]:
tensor([[0.3372, 0.6638]])
# Select with dimensional indicies
x = torch.randn(2, 3)
print(f"Values: \n{x}")

col_indices = torch.LongTensor([0, 2])
chosen = torch.index_select(x, dim=1, index=col_indices) # values from column 0 & 2
print(f"Values: \n{chosen}")

row_indices = torch.LongTensor([0, 1])
col_indices = torch.LongTensor([0, 2])
chosen = x[row_indices, col_indices] # values from (0, 0) & (2, 1)
print(f"Values: \n{chosen}") Values:
tensor([[ 0.6486,  1.7653,  1.0812],
        [ 1.2436,  0.8971, -0.0784]])
Values:
tensor([[ 0.6486,  1.0812],
        [ 1.2436, -0.0784]])
Values:
tensor([ 0.6486, -0.0784])
# Concatenation
x = torch.randn(2, 3)
print(f"Values: \n{x}")
y = torch.cat([x, x], dim=0) # stack by rows (dim=1 to stack by columns)
print(f"Values: \n{y}")Values:
tensor([[ 0.5548, -0.0845,  0.5903],
        [-1.0032, -1.7873,  0.0538]])
Values:
tensor([[ 0.5548, -0.0845,  0.5903],
        [-1.0032, -1.7873,  0.0538],
        [ 0.5548, -0.0845,  0.5903],
        [-1.0032, -1.7873,  0.0538]])

# Gradients_____no_output_____* $ y = 3x + 2 $
* $ z = \sum{y}/N $
* $ \frac{\partial(z)}{\partial(x)} = \frac{\partial(z)}{\partial(y)} \frac{\partial(y)}{\partial(x)} = \frac{1}{N} * 3 = \frac{1}{12} * 3 = 0.25 $_____no_output_____

# Tensors with gradient bookkeeping
x = torch.rand(3, 4, requires_grad=True)
y = 3*x + 2
z = y.mean()
z.backward() # z has to be scalar
print(f"x: \n{x}")
print(f"x.grad: \n{x.grad}")x:
tensor([[0.7379, 0.0846, 0.4245, 0.9778],
        [0.6800, 0.3151, 0.3911, 0.8943],
        [0.6889, 0.8389, 0.1780, 0.6442]], requires_grad=True)
x.grad:
tensor([[0.2500, 0.2500, 0.2500, 0.2500],
        [0.2500, 0.2500, 0.2500, 0.2500],
        [0.2500, 0.2500, 0.2500, 0.2500]])

# CUDA tensors_____no_output_____

# Is CUDA available?
print (torch.cuda.is_available())False

If False (CUDA is not available), let's change that by following these steps: Go to *Runtime* > *Change runtime type* > Change *Hardware accelertor* to *GPU* > Click *Save*_____no_output_____

import torch_____no_output_____# Is CUDA available now?
print (torch.cuda.is_available())True
# Set device
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print (device)cuda
x = torch.rand(2,3)
print (x.is_cuda)
x = torch.rand(2,3).to(device) # sTensor is stored on the GPU
print (x.is_cuda)False
True


# Notebook from MCilento/astropgh-boot-camp-2020
Path: notebooks/03-NumpyBasics/numpy-basics-1.ipynb

_____no_output_____# Why NumPy and NumPy arrays?
- A way to represent multi-dimensional arrays (i.e. vectors, matrices, images, tables, tensors, etc.) in Python
- Fast operations on such multi-dimensional arrays (a.k.a vectorized operations)

In this tutorial, we will learn how to use NumPy by going through various examples from Physics and Astronomy. The focus is on learning by doing. It is not possible to cover everything in a tutorial, feel free to refer to the [numpy documentation](https://numpy.org/doc/stable/) and Google things.
To start, lets import NumPy. The recommended way is:_____no_output_____

import numpy as np_____no_output_____

## Representing positions of particles using arrays
### Creating an array_____no_output_____The position of a particle in 3D is represented by a collection of three numbers. We can create a NumPy array to store it's coordinates ($x,y,z$)._____no_output_____

pos_1 = np.array([1,2,3])_____no_output_____

We can print out the array and check its type to see what has been stored._____no_output_____

print(pos_1)_____no_output_____type(pos_1)_____no_output_____

Now store the position of another particle which is located at coordinates (4,5,6)_____no_output_____

pos_2 =                  # COMPLETE THIS LINE OF CODE_____no_output_____

NumPy arrays being Python objects have some properties (attributes) associated with them. The `ndim` and `shape` attributes can be used to check the number of dimensions and the shape of the array._____no_output_____

pos_1.ndim_____no_output_____pos_1.shape_____no_output_____

The above shape indicates that there's only one dimension to the array and there are 3 elements. In NumPy terminology the space of numbers required to denote the index of an element is called an `axis` and the total number of such axes is called the `dimension`.

An object which has 1 dimension is like a vector while an object with 2 dimensions is like a matrix. This idea is generalized to get an `n-dimensional` array, i.e. the location of an element in that array needs to be denoted by specifying `n` numbers (i.e. axes). Check out another array attribute, `dtype`, which tells the type of data the array holds._____no_output_____

pos1.             # COMPLETE THIS LINE OF CODE_____no_output_____

Similar to lists the `len()` function can be used to check out the length of 1-D arrays._____no_output_____

len()                                      # COMPLETE THIS LINE OF CODE_____no_output_____

### Indexing: Accessing elements of an array
Indexing a one dimensional array follows the same syntax as that of lists (i.e. the first element has an index of `0` while the last element has an index of `len(array)-1` and proceeds in steps of 1). If you want to count from the end of an array the last element has an index of `-1`, the second last `-2`, and so on.
So, for example if we want to access the $x$ coordinate of the first particle:_____no_output_____

pos_1[0]_____no_output_____

Calculate the sum of the $y$ and $z$ coordinates of the second particle (i.e. `pos_2`)_____no_output_____

pos2[] + pos2[] # COMPLETE THIS LINE OF CODE_____no_output_____

### Automatically generating arrays
Sometimes it is useful to automatically generate an array of a given length. Some common ways to do these are the functions: `np.ones`, `np.zeros`, `np.arange`, `np.linspace` and `np.logspace`. `np.zeros` and `np.ones` create arrays of a given shape whose all elements are `0` or `1` respectively._____no_output_____

np.zeros(5)_____no_output_____

`np.arange` returns evenly spaced values within a given interval. Let's check the documentation for `np.arange` by typing `?` after the function name:
(Also when using jupyter the documentation can also be accessed by pressing `Shift`+`tab` after typing the function name, i.e. `np.arange` -> `Shift`+`tab`)_____no_output_____

np.arange?_____no_output_____

So, to generate an array whose elements are between 0 to 100 and increase in steps of 10, we do:_____no_output_____

np.arange(0,100,10)_____no_output_____

Now look up the documentation for `np.linspace` and generate the same array we generated above using `np.linspace`_____no_output_____

np.linspace                            # COMPLETE THIS LINE OF CODE_____no_output_____

**Random Arrays:** We can also generate arrays whose elements are random numbers following a specific distribution. The `np.random` module contains a number of functions that can be used to this effect. The following will create a one dimensional array with 5 samples drawn from a standard normal distribution. More such functions can be found in the [documentation](https://numpy.org/doc/stable/reference/random/legacy.html#legacy)._____no_output_____

np.random.randn(5)_____no_output_____

### Slicing: Extracting chunks of an array_____no_output_____We can extract smaller arrays from a longer array, the syntax is `array[start_index:stop_index]`. An important note is that the returned array will **include** the element corresponding to the `start_index` and **exclude** the element corresponding to the `stop_index`, i.e. it will end at `stop_index-1`. For example, lets generate an array with 100 elements_____no_output_____

big_array = np.arange(100)_____no_output_____

**NOTE:** In addition to the usage of `np.arange` shown previously, if you put only an integer as the argument of `np.arange`, it will return an array of integers starting from `0` and of length equal to the argument.

To get a smaller slice of `big_array` beginning at the index `20` and ending at the index `50-1` we do:_____no_output_____

big_array[20:50]_____no_output_____

The syntax is `array[start_index:stop_index:step]` can be used to get a slice of an array where the elements are selected in units of `step`. If no `step` is provided, it is assumed to be 1 and hence all elements are returned in the given range.

So, if we want to extract the sequence `[65, 68, 71, 74, 77, 80, 83]` from `big_array`, what should we do? _____no_output_____

big_array[]    # COMPLETE THIS LINE OF CODE_____no_output_____

**NOTE:** Doing `big_array[:]` is equivalent to selecting the whole array. The elements of an array can be reversed by selecting the whole array and having a step of `-1`_____no_output_____

big_array[::-1]_____no_output_____

## Numerical operations on arrays
### Element wise binary operations_____no_output_____All Python binary operations i.e. `+`,`-`,`*`,`/`and`**` work on arrays too! All these operations are done element wise on NumPy arrays. For example if I want to scale the position of particle 1 by 3 times_____no_output_____

3*pos_1_____no_output_____

This multiplies each element of the array by 3. The same goes for the other operations. Now square each coordinate of particle 2._____no_output_____

pos_2                                    # COMPLETE THIS LINE OF CODE_____no_output_____

Similarly if two arrays are of **same shape** then all these binary operations are performed between elements in the same index for both the arrays. For example to add the position vectors of the two particles we do:_____no_output_____

pos_1 + pos_2_____no_output_____

What happens if we exponentiate the elements of the first array to the power of the elemnts of the second array:_____no_output_____

pos_1 pos_2 # Complete this line of code_____no_output_____

What happens if we try to do such operations between arrays of different shapes?
A short answer is it may or may not give you an error!! We will look into this in the next part of the tutorial._____no_output_____### Other mathematical functions_____no_output_____Numpy has a host of built in mathematical functions which also operate element wise. These functions are generally faster than using loops to calculate the value of the function on each element. Let's see this in action by calculating the $\sin$ of an array using traditional python and also NumPy. We will measure the runtime using the `%%timeit` magic command._____no_output_____

from math import sin_____no_output_____%%timeit

vals = [i for i in range(10000)] # Create a list of 10,000 integers starting with 0
sin_vals = [sin(i) for i in vals] # Use a for loop to calculate the sin of each integers_____no_output_____

**NOTE:** The above way of using `for` loop to generate a list is called list comprehension. So this line of code
```python
numbers = [2*i for i in range(100)]
```
is equivalent to doing
```python
numbers = []
for i in range(100):
    numbers.append(2*i)
```
Both achieve the same thing, the former is the more "pythonic" way._____no_output_____

%%timeit

vals = np.arange(10000)
sin_vals = np.sin(vals)_____no_output_____

As seen above we can use the NumPy `sin` function which takes an array as its input. Almost all common mathematical functions are implemented as native numpy functions. A complete list can be found [here](https://numpy.org/doc/stable/reference/routines.math.html?highlight=mathematical%20functions).

We can see a huge improvement in runtime when using NumPy over barbones Python. This is because NumPy functions (aka `ufuncs`) are implemented in other compiled languages like C or Fortran and made available to be used in Python. Whenever possible it is recommended to use NumPy's inbuilt data structures and functions. These implementations are also called **vectorized** functions. Vectorization is a theme we will visit many times in this tutorial.

**NOTE:** Though they might look very similar Python `lists` are completely different objects than Numpy arrays. `list` is a native Python data type while NumPy arrays are not. Attributes and methods of lists like `.append()` do not work on NumPy arrays and vice versa. Moreover the elements of a list can each be of a different data type, for example
```python
example_list = [2.0, 1, "A sentence"]
```
is a list which has a `float`, an `int` and a `str` as its element. This is not possible in a NumPy array. All the elements need to be of the same datatype._____no_output_____### Array Methods
Like all other data structures in Python, NumPy arrays are objects. These objects have methods associated with them.
Recall that methods are just like functions but are associated with an object. Whereas functions take an object as an input and return another object as the output, methods act on the object they are associated with and may alter the object itself. Here's an example, the `array.sum()` **method** returns the sum of all the elements of the array. The `np.sum()` **function** takes an array as its input and returns the sum of its elements as outputs. Both do the same thing but are accessed in different ways. A complete lists of methods and attributes associated with any NumPy array can be found [here](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html)_____no_output_____

pos_1.sum()_____no_output_____np.sum(pos_1)_____no_output_____

## Plotting the galaxy luminosity function_____no_output_____The number density of galaxies having a given luminosity $(\Phi(L))$ is found to follow the functional form
$$ \Phi(L)=\left( \dfrac{\Phi^*}{L^*} \right) \left( \dfrac{L}{L^*} \right)^{\alpha}10^{\left(-\dfrac{L}{L^*}\right)}$$

Assuming the normalization constant $\left( \dfrac{\Phi^*}{L^*} \right)$ to be unity and $\alpha = -1.5, -1.0 \text{ and} -0.5$,  plot $\log(\Phi(L))$ versus $\dfrac{L}{L^*}$. Follow these steps:_____no_output_____Take a look at the documentation for `np.logspace`. Generate the $x$ axis (i.e.$\dfrac{L}{L^*}$ ) as a logarithmically spaced grid of 50 data points between $10^{-2}$ and $10$._____no_output_____

l = np.logspace()  # COMPLETE THIS LINE OF CODE_____no_output_____

Use NumPy functions and binary operations on the above array to generate the y axis (i.e. $\log(\Phi(L))$). The function to take the logarithm with a base 10 in numpy is `np.log10` whereas the function to take the natural logarithm is `np.log`.

Since we are doing the same operation thrice for different input parameters, it is really helpful to define a function. _____no_output_____

def log_phi(l, alpha):
    """
    Function to calculate the log of luminosity function

    Arguments:
    l (array): Values of L/L^star
    alpha (float): Faint end slope parameter

    Returns:
    array: The log of the luminosity function
    """

    # COMPLETE THESE THREE LINES OF CODE
    phi =
    log_phi =

    return log_phi_____no_output_____

**NOTE:** The chunk of commented text following the function definition is called a docstring. It is a good practice to always add a doctring whenever you define a function and intend to reuse it.

The following is an example of a very basic docstring.

```python
def a_generic_function(input1, input2):
    """
    This is what the funtion does

    Arguments:
    input1 (data_type): Meaning of the input

    Returns
    data_type: Meaning of the return value

    """

    return something
```

There are multiple formatting schemes for doctsrings. The one followed by the Scientific Python community can be found [here](https://docs.scipy.org/doc/numpy/docs/howto_document.html).

This docstring can be accessed using the usual methods of accessing the documentation for any function imported from a library. Access the docstring for the function we defined in the previous cell:_____no_output_____

log_phi                         # COMPLETE THIS LINE OF CODE_____no_output_____import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))

# COMPLETE THESE THREE LINES OF CODE

plt.plot(        ,label=r"$\alpha=-1.5$") # for alpha = -1.5
plt.plot(        ,label=r"$\alpha=-1.0$") # for alpha = -1.0
plt.plot(        ,label=r"$\alpha=-0.5$") # for alpha = -0.5

plt.xlabel(r"$\dfrac{L}{L^{\star}}$", fontsize=20) # Print the x label in latex
plt.ylabel(r"$\log(\Phi(L))$", fontsize=20) # Print the x label in latex
plt.xscale("log") # Set the spacing in the x axis logarithmically
plt.legend()_____no_output_____

## Multi Dimensional Arrays_____no_output_____As mentioned previously, NumPy can be used to represent arrays of any size and dimension. Though all the examples above have used one-dimensional arrays, all of them will work when we have more than one dimension. For example, a list of lists can be used to initialize a two dimensional array just like a list was used to initialize a one dimensional array. All the array attributes also work similarly._____no_output_____

arr_2d_1 = np.array([[1, 2, 3], [4, 5, 6]])_____no_output_____print(arr_2d_1)_____no_output_____arr_2d_1.shape_____no_output_____arr_2d_1.ndim_____no_output_____

`arr_2d_1` has a dimension of 2 i.e. it has two axes (`0` and `1`, since everything in Python is counted from 0). The **0th axis has 2** elements while the **1st axis has 3** elements._____no_output_____Most of the functions to generate arrays listed above can be used with more than one dimension, for example_____no_output_____

np.zeros((2,3))_____no_output_____np.random.randn(2,3)_____no_output_____

Similarly all element wise operations happen similarly on multi-dimensional arrays including binary operations between two arrays._____no_output_____

2*arr_2d_1_____no_output_____arr_2d_2 = np.array([[7, 8, 9], [10, 11, 12]])_____no_output_____arr_2d_1 + arr_2d_2_____no_output_____

### Linear Algebra with NumPy_____no_output_____Up till now you might have noticed that one dimensional arrays behave as row or column matrices, while 2 dimensional arrays behave like a matrix. This analogy holds mostly except for certain situations. lets take this example:_____no_output_____

arr_2d_1 * arr_2d_2_____no_output_____

Though we are multiplying two matrix like objects, their multiplication is not like matrix multiplication, rather the `*` operation denotes element wise product between two arrays. We can use the `np.dot()` function which gives the scalar dot product when its arguments are vectors (i.e.one-dimensional arrays) and the traditional matrix multiplication when one or both of its arguments are two-dimensional arrays.

Also note that the term *dimension* means different things for matrices and NumPy arrays. We have defined `arr_2d_1` which is similar to a $2\times3$ matrix and we have defined `pos_1` which is like a row matrix with three elements (i.e. $3\times1$ matrix). We do their matrix multiplication by:_____no_output_____

np.dot(arr_2d_1, pos_1)_____no_output_____

The `array.T` attribute returns the transpose of the matrix. A lot of linear algebra can be performed in NumPy, you can find the list of all linear algebra related functions [here](https://numpy.org/doc/stable/reference/routines.linalg.html?highlight=linear%20algebra).  For even more linear algebra tools, `scipy.linalg` contains the majority of the tools in the classic LAPACK libraries, you can find those functions [here](https://docs.scipy.org/doc/scipy/reference/linalg.html)

Lets find the matrix multiplication of the `pos_1` and the transposed matrix of `arr_2d_1`_____no_output_____

np.dot()  # COMPLETE THIS LINE OF CODE_____no_output_____

### Indexing and slicing in multi-dimensional arrays_____no_output_____Indexing and slicing for multidimensional arrays work in exactly the same way as in 1D arrays except the indices/slices for each axes are separeted by a `,`. So, if I want to select the element with index 1 along axis 0 and index 2 along axis 1 of the array `arr_2d_1`_____no_output_____

arr_2d_1[1,2]_____no_output_____

We can select all the elements along axis 0 and for the index 2 along axis 1 by_____no_output_____

arr_2d_1[:,2]_____no_output_____

Similarly all other slicing operations can be performed on multi-dimensional arrays. We can select all the elements along the 0th axis corresponding to the first index by_____no_output_____

arr_2d_1[1]_____no_output_____

**NOTE:** The above is equivalent to `arr_2d_1[1,:]`. Python reads script from left to right, if we stop putting indices to the right, it is assumed that all elements are selected._____no_output_____A small illustrated summary of numpy indexing and slicing from [scipylectures.org](https://scipy-lectures.org/intro/numpy/array_object.html): _____no_output__________no_output_____### Reading and writing simple arrays_____no_output_____The most efficient way to save array like objects as binary files is the `.npy` file format. To save an array we do `np.save("file_name", array)`. So to save `arr_2d_1`:_____no_output_____

np.save("my_array.npy", arr_2d_1)_____no_output_____

To read `.npy` files we do `np.load("file_path")`_____no_output_____

np.load("my_array.npy")_____no_output_____

**NOTE:** `.npy` files are by far the best way to save data of a reasonable size. As data size becomes larger and organization more complex, it is preferable to store data in formats like HDF5. Astronomers have a certain affection towards `.fits` files. We will deal with them in a subsequent tutorial.
NumPy can also read text files using `np.loadtxt`. Text files are generally used to store catalogs and tabular data. Better methods than NumPy exist to read and work with such data types. They will be discussed in a subsequent tutorial._____no_output_____## Pretty pictures of galaxies_____no_output_____We will now look at images of galaxies taken by the [Sloan Digital Sky Survey (SDSS)](https://www.sdss.org/). A monochromatic image is basically a 2D array where the brightness of each pixel corresponds to the value of the array element. The supplied data file has images of 15 different galaxies each 64 $\times$ 64 pixels in size. The images were taken in 5 bands of wavelengths (viz. $u$, $g$, $r$, $i$, $z$) ranging from near ultra-violet to mid infrared. We first open the image, read it into an array and check its shape._____no_output_____

imgs = np.load("data/sdss.npy") # MODIFY THE FILE PATH BASED ON YOUR SYSTEM_____no_output_____imgs.shape_____no_output_____

Looking at the shape try to figure out what each axes of this array corresponds to. We will select some of the galaxies from this set and plot their images. First lets select the second galaxy in the given array (Recall that indexing starts from `0`)_____no_output_____

img_1 = imgs[] # COMPLETE THIS LINE OF CODE_____no_output_____

We will now plot the image of the selected galaxy by looping over the wavelength bands. Since the pixels span a huge dynamic range we will scale the pixels by performing the element wise hyperbolic tangent peration (`np.tanh()`)_____no_output_____

# COMPLETE THESE THREE LINES OF CODE
for i in range():                # loop over all the wavelength bands
    selected_filter = img[]      #Select an image in a wavelength band
    scaled_img =                 #scale the image using element wise hyperbolic tan

    plt.figure()
    plt.imshow(scaled_img, cmap="gray")_____no_output_____

Feel free to select other galaxies and plot their images.
As you can see the galaxy mostly occupies the central region of the picture. So we will crop the images to select only the central 32$\times$32 array elements for each wavelength band and plot them._____no_output_____

# COMPLETE THESE FOUR LINES OF CODE
for i in range(): # loop over all the wavelength bands
    selected_filter = img[]            #Select an image in a wavelength band
    cropped_img = selected_filter[]    #Select the central 32x32 elements
    scaled_img =                       #scale the image using element wise hyperbolic tan

    print(scaled_img.shape)
    plt.figure()
    plt.imshow(scaled_img, cmap="gray")_____no_output_____

### Reductions: Numerical operations which return a smaller array_____no_output_____Some numpy functions can take an array as input and return a smaller array as output. An example of such a function would be `np.sum`. If applied on an array, it returns the sum of all elements in the array._____no_output_____

np.sum(arr_2d_1)_____no_output_____

Such numpy functions also have an argument called `axis`. Alternatively we can specify the axis along which the function will operate. The resulting array will have a dimension less than the original array. The `axis` mentioned in the argument will be the one which is reduced._____no_output_____

arr_2d_1_____no_output_____np.sum(arr_2d_1, axis=0)_____no_output_____np.sum(arr_2d_1, axis=1)_____no_output_____

An illustrative representation of `np.sum` across various axes from [scipylectures.org](https://scipy-lectures.org/intro/numpy/operations.html#basic-reductions)_____no_output__________no_output_____Most common statistical functions are implemented in NumPy and can be used in a similar way. We will use the function `np.mean()` to calculate the average values of the image pixels across all the wavelength ranges and plot the average image for all the given galaxies in a similar way as before._____no_output_____

# COMPLETE THESE THREE LINES OF CODE
for i in range():                       # loop over all the galaxies in the dataset
    selected_galaxy = imgs[]            # Select a galaxy from the data set
    mean_img =                          # Calculate the mean value of all the pixels across observed wavelengths
    scaled_img =                        #scale the image using element wise hyperbolic tan

    plt.figure()
    plt.imshow(scaled_img, cmap="gray")_____no_output_____

Want to see more (and prettier) pictures of galaxies?
Check out [legacysurvey.org](http://legacysurvey.org/viewer)!_____no_output_____


# Notebook from tongwade/protein_dynamics_matlab
Path: python_tornado/calculate_pair_sequence_identity.ipynb

<code>
#!/usr/bin/env python

from __future__ import print_function, division

from operator import itemgetter
import os
import sys
import tempfile
import warnings

try:
    from Bio import pairwise2
    from Bio.SubsMat import MatrixInfo as matlist
except ImportError as exception:
    print("[!] Could not import Biopython modules", file=sys.stderr)
    raise exception

#
def align_sequences(sequence_A, sequence_B, **kwargs):
    """
    Performs a global pairwise alignment between two sequences
    using the BLOSUM62 matrix and the Needleman-Wunsch algorithm
    as implemented in Biopython. Returns the alignment, the sequence
    identity and the residue mapping between both original sequences.
    """

    def _calculate_identity(sequenceA, sequenceB):
        """
        Returns the percentage of identical characters between two sequences.
        Assumes the sequences are aligned.
        """

        sa, sb, sl = sequenceA, sequenceB, len(sequenceA)
        matches = [sa[i] == sb[i] for i in xrange(sl)]
        seq_id = (100 * sum(matches)) / sl

        gapless_sl = sum([1 for i in xrange(sl) if (sa[i] != '-' and sb[i] != '-')])
        gap_id = (100 * sum(matches)) / gapless_sl
        return (seq_id, gap_id)

    #
    matrix = kwargs.get('matrix', matlist.blosum62)
    gap_open = kwargs.get('gap_open', -10.0)
    gap_extend = kwargs.get('gap_extend', -0.5)

    alns = pairwise2.align.globalds(sequence_A, sequence_B,
                                    matrix, gap_open, gap_extend)

    best_aln = alns[0]
    aligned_A, aligned_B, score, begin, end = best_aln

    # Calculate sequence identity
    seq_id, g_seq_id = _calculate_identity(aligned_A, aligned_B)
    return ((aligned_A, aligned_B), seq_id, g_seq_id)_____no_output_____import os
pdb_file = open('/home/tongwade780/pdb_website/onebyone_cluster_code/representative_pdbname.csv').readlines ()

pdbname = []
for line in pdb_file:
    pdbname.append(line.rstrip('\r\n').split(',')[0][0:4].lower())_____no_output_____sequence_A = 'MQIFVKTLTGKTITLEVEPSDTIENVKAKIQDKEGIPPDQQRLIFAGKQLEDGRTLSDYNIQKESTLHLVLRLRGG'
sequence_B = 'AAGSITTLPALPEDGGSGAFPPGHFKDPKRLYCKNGGFFLRIHPDGRVDGVREKSDPHIKLQLQAEERGVVSIKGVSANRYLAMKEDGRLLASKSVTDECFFFERLESNNYNTYRSRKYTSWYVALKRTGQYKLGSKTGPGQKAILFLPMSAKS'

((aligned_A, aligned_B), seq_id, g_seq_id) = align_sequences(sequence_A, sequence_B)

seq_id_____no_output_____pdbname = ['1ubq','1bas','3ta8','1azp']_____no_output_____pdbname = ['5ctl','1kh8','2xjx','1ufp','1ymb','4rvr','3dn0','1xr1','4hy8','4n1m','2qu9','1c7p','1q21','4gr3']_____no_output_____sequence_A = ''.join(open('/home/tongwade780/pdb_website/onebyone_cluster_code/test_seq_alin/{0}.fasta.txt'.format(pdbname[0])).read().split('\n')[1:])

#sequence_B = ''.join(open('/home/tongwade780/pdb_website/onebyone_cluster_code/test_seq_alin/{0}.fasta.txt'.format(pdbname[2])).read().split('\n')[1:])

b = open('/home/tongwade780/pdb_website/onebyone_cluster_code/test_seq_alin/{0}.fasta.txt'.format(pdbname[3])).read().split('\n')[1:]
sequence_B = ''
for line in b:
    if line == '':
        break
    elif line[0] == '>':
        break
    else:
        sequence_B = sequence_B+line
((aligned_A, aligned_B), seq_id, g_seq_id) = align_sequences(sequence_A, sequence_B)
seq_id_____no_output_____import numpy
matrix = numpy.zeros((2792,2792))
problem_pdb = []
row = -1
for name1 in pdbname:
    row = row+1
    print(row)
    sequence_A = ''
    a = open('/home/tongwade780/pdb_website/onebyone_cluster_code/representative_fasta_sequence/{0}.fasta.txt'.format(name1)).read().split('\n')[1:]
    for line in a:
        if line == '':
            break
        elif line[0] == '>':
            break
        else:
            sequence_A = sequence_A+line
    for colunm in range(row,2792):
        name2 = pdbname[colunm]
        b = open('/home/tongwade780/pdb_website/onebyone_cluster_code/representative_fasta_sequence/{0}.fasta.txt'.format(name2)).read().split('\n')[1:]
        sequence_B = ''
        for line in b:
            if line == '':
                break
            elif line[0] == '>':
                break
            else:
                sequence_B = sequence_B+line

        ((aligned_A, aligned_B), seq_id, g_seq_id) = align_sequences(sequence_A, sequence_B)
        matrix[row,colunm] = seq_id0
matrix_____no_output_____sa, sb, sl = sequence_A, sequence_B, len(sequence_A)
matches = [sa[i] == sb[i] for i in xrange(sl)]
seq_id = (100 * sum(matches)) / sl

gapless_sl = sum([1 for i in xrange(sl) if (sa[i] != '-' and sb[i] != '-')])
gap_id = (100 * sum(matches)) / gapless_sl_____no_output_____xrange(330)_____no_output_____import pandas as pd
matrix_data=pd.DataFrame(matrix)

matrix_data.columns = pdbname

matrix_data.index = pdbname
_____no_output_____matrix_data.to_csv('/home/tongwade780/pdb_website/onebyone_cluster_code/MD_14_pdb_identity.csv')_____no_output_____matrix[matrix < 30] = 0

matrix[matrix > 30] = 1
_____no_output_____matrix_data=pd.DataFrame(matrix)

matrix_data.columns = pdbname
matrix_data.index = pdbname
matrix_data.to_csv('/home/tongwade780/pdb_website/onebyone_cluster_code/MD_14_pdb_like_or_not.csv')_____no_output_____
</code>


# Notebook from shaggyday/evaluating-human-rationales
Path: movies_stats.ipynb

<code>
import pandas as pd
import os
def avg(l): return sum(l)/len(l)

'''
counts the length of rationales
'''
def count_rationale_length(df, batch=True):
    if batch:
        rationale_dict = {}
        for doc_evidences in df['evidences']:
            for evidence in doc_evidences:
                evidence = evidence[0]
                rationale_length = evidence['end_token'] - evidence['start_token']
                assert (rationale_length == len(evidence['text'].split()))
                doc_id = evidence['docid']
                if doc_id not in rationale_dict.keys(): rationale_dict[doc_id] = rationale_length
                else: rationale_dict[doc_id] += rationale_length
        return list(rationale_dict.values())
    else:
        rationale_len = []
        for doc_evidences in df['evidences']:
            for evidence in doc_evidences:
                rationale_length = evidence[0]['end_token'] - evidence[0]['start_token']
                assert (rationale_length == len(evidence[0]['text'].split()))
                rationale_len.append(rationale_length)
        return rationale_len

'''
counts the average length of the text files
'''
def count_text_length(doc_path):
    def count_file_length(file):
        f = open(file, 'rb')
        text_length = 0
        for line in f.readlines():
            text_length += len(line.rstrip().split())
        return text_length

    text_dict = {}
    data_dir = directory + 'docs'
    for filename in os.listdir(data_dir):
        f = os.path.join(data_dir, filename)
        if os.path.isfile(f):
            text_dict[filename] = count_file_length(f)
    text_lengths = list(text_dict.values())
    return avg(text_length)
#     return text_length_____no_output_____'''
converts rationales to binary masks over text
1 to include a token, 0 to exclude
'''
def evidence_to_mask(tokens, evidence_list):
    mask = [1]*len(tokens)
    for evidence in evidence_list:
        if type(evidence) is list:
            evidence = evidence[0]
        if type(evidence) is not dict:
            print("???")
            return
        else:
            start_token = evidence['start_token']
            end_token = evidence['end_token']
            for i in range(start_token, end_token):
                mask[i] = 0
    return mask

'''
converts dataframe to csv with only the texts, labels and rationale masks
'''
def to_data_df(df):
    data_df = []
    columns = ['text', 'classification', 'rationale']
    for i in range(len(df)):
        df_row = df.loc[i]
        text_id = df_row['annotation_id']
        evidence_list = df_row['evidences']
        classification = df_row['classification']

        file = directory + 'docs/' + text_id
        if os.path.isfile(file):
            f = open(file, 'r')
            text = ''
            for line in f.readlines():
                text += line.rstrip() + ' '
        else:
            print("???")

        tokens = text.split()
        rationale_mask = evidence_to_mask(tokens, evidence_list)

        data_df.append([text, classification, rationale_mask])
    data_df = pd.DataFrame(data_df, columns=columns)
    return data_df

'''
truncates a data_df so that each segment contains at least 1 rationale
'''
def truncate(data_df, lim=512):
    for i in range(len(data_df)):
        row = data_df.iloc[i]
        text = row['text']
        tokens = text.split()
        if len(text) > lim:
            rationale = row['rationale']
            start = rationale.index(0)
            # exceeds limit
            if len(text)-1-start > lim:
                end = start + lim
            # not enough
            else:
                start = len(text) - 1 - lim
                end = -1

            trunc_rationale = rationale[start:end]
            trunc_tokens = tokens[start:end]
            trunc_text = ' '.join([str(token) for token in trunc_tokens])
            data_df.iloc[i]['rationale'] = trunc_rationale
            data_df.iloc[i]['text'] = trunc_text
            print(len(data_df.iloc[i]['rationale']))
    return data_df_____no_output_____data_df = to_data_df(val)
data_df.to_csv('val.csv')
text_len = []
for i in range(len(data_df)):
    row = data_df.iloc[i]
    text = row['rationale']
    text_len.append(len(text))
text_len_____no_output_____data_df = truncate(data_df)83
80
295
512
450
512
191
512
404
253
512
512
512
512
215
512
512
179
512
512
512
445
512
448
512
464
425
349
284
512
63
512
512
512
512
512
486
512
512
512
395
512
512
331
512
512
512
512
512
512
512
512
512
512
256
274
376
98
512
361
121
200
512
512
443
512
512
377
170
512
344
512
512
473
512
168
512
512
512
321
345
264
512
512
455
512
512
275
512
512
512
444
512
512
512
389
512
366
473
384
512
512
512
512
512
512
340
512
512
512
512
416
512
458
247
512
512
512
512
512
512
512
512
344
284
110
311
512
512
512
512
469
357
494
336
138
512
512
303
481
512
190
512
390
512
512
512
173
512
512
278
225
512
249
396
459
512
163
512
512
512
390
512
431
335
512
194
485
512
512
512
370
512
512
273
512
303
344
512
461
512
126
512
46
512
274
317
512
512
512
512
512
512
512
475
512
512
512
254
420
data_df_____no_output_____text_len = []
for i in range(len(data_df)):
    row = data_df.iloc[i]
    text = row['rationale']
    text_len.append(len(text))
avg(text_len)_____no_output_____text_len_____no_output_____directory = 'data/movies/'_____no_output_____train_f_suffix = 'train'
test_f_suffix = 'test'
val_f_suffix = 'val'_____no_output_____train = pd.read_json(directory + train_f_suffix + '.jsonl', lines=True)
train.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1600 entries, 0 to 1599
Data columns (total 5 columns):
 #   Column          Non-Null Count  Dtype
---  ------          --------------  -----
 0   annotation_id   1600 non-null   object
 1   classification  1600 non-null   object
 2   evidences       1600 non-null   object
 3   query           1600 non-null   object
 4   query_type      0 non-null      float64
dtypes: float64(1), object(4)
memory usage: 62.6+ KB
test = pd.read_json(directory + test_f_suffix + '.jsonl', lines=True)
test.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 199 entries, 0 to 198
Data columns (total 6 columns):
 #   Column          Non-Null Count  Dtype
---  ------          --------------  -----
 0   annotation_id   199 non-null    object
 1   classification  199 non-null    object
 2   docids          0 non-null      float64
 3   evidences       199 non-null    object
 4   query           199 non-null    object
 5   query_type      0 non-null      float64
dtypes: float64(2), object(4)
memory usage: 9.5+ KB
val = pd.read_json(directory + val_f_suffix + '.jsonl', lines=True)
val.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200 entries, 0 to 199
Data columns (total 5 columns):
 #   Column          Non-Null Count  Dtype
---  ------          --------------  -----
 0   annotation_id   200 non-null    object
 1   classification  200 non-null    object
 2   evidences       200 non-null    object
 3   query           200 non-null    object
 4   query_type      0 non-null      float64
dtypes: float64(1), object(4)
memory usage: 7.9+ KB
train.iloc[0]['evidences']_____no_output_____data_df = to_data_df(val)
data_df.to_csv('val.csv')_____no_output_____val.iloc[0]['evidences']_____no_output_____train_dict = count_rationale_length(train)
test_dict = count_rationale_length(test)
val_dict = count_rationale_length(val)

# rationale_dict = {**train_dict, **test_dict, **val_dict}
# rationale_len = list(rationale_dict.values())
rationale_len = train_dict + test_dict + val_dict
sum(rationale_len)/len(rationale_len)_____no_output_____def build_rationale_dict(df):
    rationale_dicts = []
    for i in range(len(df)):
        row = df.loc[i]
        classification = row['classification']
        for rationale in row['evidences']:
            rationale = rationale[0]
            text = rationale['text']
            doc_id = rationale['docid']
            rationale_length = rationale['end_token'] - rationale['start_token']
            assert (rationale_length == len(text.split()))
            rationale_dicts.append({'text':text, 'doc_id':doc_id, 'rationale_length':rationale_length, 'class':classification})

    return rationale_dicts

rationale_dicts = build_rationale_dict(train) + build_rationale_dict(test) + build_rationale_dict(val)

neg_lengths = []
pos_lengths = []
neg_ratios = []
pos_ratios = []
for rationale in rationale_dicts:
    text_len = text_dict[rationale['doc_id']]
    rationale_len = rationale['rationale_length']
    ratio = rationale_len/text_len
    if rationale['class'] == 'REFUTES':
        neg_lengths.append(rationale_len)
        neg_ratios.append(ratio)
    else:
        pos_lengths.append(rationale_len)
        pos_ratios.append(ratio)_____no_output_____avg(pos_ratios)_____no_output_____avg(neg_ratio)_____no_output_____avg(pos_ratio)_____no_output_____text_lengths = list(text_dict.values())
rationale_lengths = list(rationale_dict.values())

mean_rationale_length = avg(rationale_lenth)
mean_text_length = avg(text_lengths)
mean_rationale_percent = sum(rationale_lengths)/sum(text_lengths)
mean_rationale_length_class = [avg(neg_lengths), avg(pos_lengths)]
mean_rationale_percent_class = [avg(neg_ratios), avg(pos_ratios)]
mean_text_length_class = 0
mean_text_length_z = mean_text_length
mean_text_length_all = mean_text_length
mean_text_length_train = 0
mean_text_length_dev = 0
mean_text_length_test = 0
mean_rationale_length_z = 0_____no_output_____stats_path = directory + 'stats.csv'
stats = pd.read_csv(stats_path)
scifact = ['SciFact',
          ['REFUTES', 'SUPPORTS'],
          len(train),
          len(test),
          len(val),
          'RC,',
          mean_rationale_length,
          mean_text_length,
          mean_rationale_percent,
          mean_rationale_length_class,
          mean_rationale_percent_class,
          mean_text_length_class,
          mean_text_length_z,
          mean_text_length_all,
          mean_text_length_train,
          mean_text_length_dev,
          mean_text_length_test,
          mean_rationale_length_z]
stats.loc[0] = scifact
stats.to_csv(stats_path)_____no_output_____scifact_____no_output_____a = lambda s: s.strip("[").strip("]").split()_____no_output_____a('[definitely the cinematic equivalent of a sleeper car", "nothing really worth watching]')_____no_output_____len([    0, 40776,  4832,    80,  6066,  8571,   213,     7,    10,  2352,
          537,  2156,  4076,     8,   172,  1305,   479, 10010,   120,    88,
           41,  3213,   479,  1264,     9,     5,  1669,  8524,  2156,    53,
           39,  6096,  1388,     7,   192,   123,    11,    69,   301,  2156,
            8,    34, 31634,   479, 12196,   128,    29,     5,   432, 17487,
        11018,     5,  1569,     8,    22,  2345,   102,    22,   465,    66,
          479,   479,   479, 35031,  5150,  4832,    10,  1508,   111, 26536,
         1569,    13,     5,  6066,  2706,    14, 12325,    15,    10,   182,
         3035,  1114,  2156,    53,  6822,    24,    11,    10,   182,  1099,
         3737,   479,  5488,    16,    99,   817,    42,  1551,    41,   190,
         4851,    65,     7,  3116,  2156,   187,   939,  3489, 19477,  3541,
           61,  2120,     7,  1108,     5, 16140,  2156,  7319,    19,   110,
          471,     8,   215,    36,   685,  6418,   359,   475,  6285,   139,
         4839,  2156,    53,    89,    32,   205,     8,  1099,  1319,     9,
          442,    70,  3505,     9,  3541,  2156,     8,   209,  5450,    95,
          222,   295,    75, 29650,    42,    65, 12461,     4, 10010,  2045,
            7,    33,   551,    42,  1256, 19427,  4286,  2156,    53,  9390,
           24, 23213,   479,  2527,    99,    32,     5,  1272,    19,     5,
         1569, 17487,  3056,  2156,    63,  1049,   936,    16,    14,    24,
          128,    29,  1622,   350,  1236, 10434,     4,   405,  2012,   160,
           22,  2340,    22,    53,   172,   159,  1193, 22833,    88,    42,
           22,  8235,    22,   232,    11,    61,    47,  2156,    25,    41,
         2437,   919,  2156, 11990,   117,  1114,    99,   128,    29,   164,
           15,     4,  8585,    32,  7416,  2156,    89,    32,  3768,   567,
          124,    31,     5,  1462,  2156,    89,    32,   643,    54,   356,
          101,     5,  1462,  2156,    89,    32,  7782, 41736,  8237,  2156,
           89,    32, 14529,  5332,  2156,    89,    32,    10,   784, 41242,
         9210,     9,  7859,  5422,  2156,    89,    32,  7741,     9,  7735,
          383,    14,  1369,  2156,     8,   144,     9,    24,    16,  1622,
           45,  2002,   479,  8310,   939,  5636,   109,   295,    75,  1508,
          667,     7, 21697,    10,   822,   358,   122,     8,   172,  2156,
           53,    77,    70,    24,   473,    16,   492,   162,     5,   276,
        18664,    81,     8,    81,   456,  2156,   939,   120,   761,     9,
         9789,    62,    71,    10,   150,  2156,    61,    16,    42,   822,
          128,    29,   934,   936,   479,   405,   128,    29,  3334,   300,
           42,   380,  3556,     7,  7433,  2156,    53,    24,  1302,     7,
          236,     7,  7433,    24,  2198,   454,    63,   507,   292,   728,
          479,   463,   109,    51,   146,   383, 11110,  2156, 16208,    50,
          190,  7580,  2156,    11,     5, 10299, 17487,  3654,   269,   479,
          627,  5074,   233,    16,    14,     5, 27899,     8,   939,   258,
         8512,    15,   856, 36562,   101,    42,  2156,    98,    52,   888,
        11464,   144,     9,    24,    66,    30,     5,   457,   111,   169,
          477,  2156,    98,    70,     9,     5, 31083, 14186,    71,    14,
          222,   386,     7,   146,    10,   410,   828,     9,  1472,  2156,
           53,    24,   202,   222,   295,    75,     5,   146,     5,   822,
           70,    14,    55, 11110,   479,   118,  4443,     5,  2576,   516,
           19,  4133,   101,    42,    16,    14,    47,   197,   460,   146,
          686,    14,     5,  2437,    16,    22,    88,    24,    22,   190,
          137,    51,    32,   576,     5,  3556, 14844,     7,  2914,   110,
          232,     9,  2969,   479,   118,  1266,  2156,  2018, 15352, 12109,
        17929,   991,  8690,   878,   409,    31, 28420,    13,    59,   291,
          728,     2])_____no_output_____s="""plot : two teen couples go to a church party , drink and then drive .
they get into an accident .
one of the guys dies , but his girlfriend continues to see him in her life , and has nightmares .
what 's the deal ?
watch the movie and " sorta " find out . . .
critique : a mind - fuck movie for the teen generation that touches on a very cool idea , but presents it in a very bad package .
which is what makes this review an even harder one to write , since i generally applaud films which attempt to break the mold , mess with your head and such ( lost highway & memento ) , but there are good and bad ways of making all types of films , and these folks just did n't snag this one correctly
.
they seem to have taken this pretty neat concept , but executed it terribly .
so what are the problems with the movie ?
well , its main problem is that it 's simply too jumbled
.
it starts off " normal " but then downshifts into this " fantasy " world in which you , as an audience member ,
have no idea what 's going on
.
there are dreams , there are characters coming back from the dead , there are others who look like the dead , there are strange apparitions , there are disappearances , there are a looooot of chase scenes , there are tons of weird things that happen , and most of it is simply not explained .
now i personally do n't mind trying to unravel a film every now and then , but when all it does is give me the same clue over and over again , i get kind of fed up after a while , which is this film 's biggest problem .
it 's obviously got this big secret to hide , but it seems to want to hide it completely until its final five minutes .
and do they make things entertaining , thrilling or even engaging , in the meantime ?
not really .
the sad part is that the arrow and i both dig on flicks like this , so we actually figured most of it out by the half - way point , so all of the strangeness after that did start to make a little bit of sense , but it still did n't the make the film all that more entertaining .
i guess the bottom line with movies like this is that you should always make sure that the audience is " into it " even before they are given the secret password to enter your world of understanding .
i mean , showing melissa sagemiller running away from visions for about 20 minutes throughout the movie is just plain lazy ! !
okay , we get it .
. .
there are people chasing her and we do n't know who they are .
do we really need to see it over and over again ?
how about giving us different scenes offering further insight into all of the strangeness going down in the movie ?
apparently , the studio took this film away from its director and chopped it up themselves , and it shows .
there might 've been a pretty decent teen mind - fuck movie in here somewhere , but i guess " the suits " decided that turning it into a music video with little edge , would make more sense .
the actors are pretty good for the most part , although wes bentley just seemed to be playing the exact same character that he did in american beauty , only in a new neighborhood .
but my biggest kudos go out to sagemiller , who holds her own throughout the entire film , and actually has you feeling her character 's unraveling .
overall , the film does n't stick
because it does n't entertain , it 's confusing , it rarely excites and
it feels pretty redundant for most of its runtime , despite a pretty cool ending and explanation to all of the craziness that came before it .
oh ,
and by the way , this is not a horror or teen slasher flick . . .
it 's just packaged to look that way because someone is apparently assuming that the genre is still hot with the kids .
it also wrapped production two years ago and has been sitting on the shelves ever since .
whatever . .
. skip it !
where 's joblo coming from ?
a nightmare of elm street 3 ( 7/10 ) - blair witch 2 ( 7/10 ) - the crow ( 9/10 ) - the crow : salvation ( 4/10 )
- lost highway ( 10/10 ) - memento ( 10/10 ) - the others ( 9/10 ) - stir of echoes ( 8/10 )"""_____no_output_____s="""the happy bastard 's quick movie review damn
that y2k bug .
it 's got a head start in this movie starring jamie lee curtis and another baldwin brother ( william this time ) in a story regarding a crew of a tugboat that comes across a deserted russian tech ship that has a strangeness to it when they kick the power back on .
little do they know the power within . . .
going for the gore and bringing on a few action sequences here and there , virus
still feels very empty , like a movie going for all flash and no substance .
we do n't know why the crew was really out in the middle of nowhere , we do n't know the origin of what took over the ship ( just that a big pink flashy thing hit the mir ) , and , of course , we do n't know why donald sutherland is stumbling around drunkenly throughout .
here , it 's just
" hey , let 's chase these people around with some robots " .
the acting is below average , even from the likes of curtis .
you 're more likely to get a kick out of her work in halloween h20 .
sutherland is wasted and baldwin , well , he 's acting like a baldwin , of course .
the real star here are stan winston 's robot design , some schnazzy cgi , and the occasional good gore shot , like picking into someone 's brain .
so , if robots and body parts really turn you on , here 's your movie .
otherwise , it 's pretty much a sunken ship of a movie ."""_____no_output_____len(s.rstrip().split())_____no_output_____len([    0,   627,  1372, 43143,   128,    29,  2119,  1569,  1551, 16490,
         6025,  1423,   176,   330, 13673,   479,   405,   128,    29,   300,
           10,   471,   386,    11,    42,  1569,  8996, 11914,   324,  2084,
          242,  5350, 42334,     8,   277, 24876,  5640,  2138,    36,    40,
         6009,    42,    86,  4839,    11,    10,   527,  2624,    10,  3419,
            9,    10, 24447, 14859,    14,   606,   420,    10, 31712,   910,
        42472,  2903,  3627,    14,    34,    10, 31083, 14186,     7,    24,
           77,    51,  3151,     5,   476,   124,    15,   479, 27635,   109,
           51,   216,     5,   476,   624,   479,   479,   479, 12891,    13,
            5, 43739,     8,  2406,    15,    10,   367,   814, 26929,   259,
            8,    89,  2156,  6793, 17830,  2653,   182,  5802,  2156,   101,
           10,  1569,   164,    13,    70,  7462,     8,   117,  6572,   479,
         1694,   109,   295,    75,   216,   596,     5,  3419,    21,   269,
           66,    11,     5,  1692,     9,  9261,  2156,    52,   109,   295,
           75,   216,     5,  9813,     9,    99,   362,    81,     5,  3627,
           36,    95,    14,    10,   380,  6907, 31005,   631,   478,     5,
        13235,  4839,  2156,     8,  2156,     9,   768,  2156,    52,   109,
          295,    75,   216,   596,   218,  5618,   579, 48588,    16, 28019,
          198, 19835,   352,  1328,   479, 10859,  2156,    24,   128,    29,
           95,   113, 17232,  2156,   905,   128,    29,  7859,   209,    82,
          198,    19,   103, 12129,    22,   479,   627,  3501,    16,   874,
          674,  2156,   190,    31,     5,  3829,     9,  5350, 42334,   479,
         6968,   128,   241,    55,   533,     7,   120,    10,  3151,    66,
            9,    69,   173,    11,  5179,  1722, 14102,  1368,   844,   479,
           29, 48588,    16, 14260,     8, 24876,  5640,  2156,   157,  2156,
           37,   128,    29,  3501,   101,    10, 24876,  5640,  2156,     9,
          768,   479,   627,   588,   999,   259,    32,  1690,   260,   339,
         6712,   128,    29,  9916,  1521,  2156,   103,   579, 13212,  1222,
         5144,   740, 15696,  2156,     8,     5, 12577,   205, 43739,   738,
         2156,   101,  6201,    88,   951,   128,    29,  2900,   479,  2527,
         2156,   114, 12129,     8,   809,  1667,   269,  1004,    47,    15,
         2156,   259,   128,    29,   110,  1569,   479,  7443, 10715,  2156,
           24,   128,    29,  1256,   203,    10, 21168,   225,  3627,     9,
           10,  1569,   479,     2])_____no_output_____
</code>


# Notebook from lechten/curriculum-notebooks
Path: Lessons/Lesson14_Pandas-Intro.ipynb

# Introduction to Pandas

You may have used a program like Microsoft Excel or Google Sheets to record data or perform calculations for school. Datasets are often organized in rows and columns. Does anyone have an example of a using spreadsheets in school? (e.g. recording measurements in biology class, budgeting for personal finance in econ, etc.)

| Product | Price | Quantity Sold |
|--------------|-------------|------------------------|
| Apples  | \$ 1.50 | 26 |
| Bananas | \$  0.50 | 32 |
| Lemons | \$ 1.99 | 17 |

In this case, we have prices of fruit from a grocery store. Each row in this dataset is a type fruit, and each column is an observation or measurement. What measurements do we have here?

_____no_output_____**Measurements**: _____no_output_____To handle data in Python, we use a package called called `pandas`. (Despite the name, it actually doesn't have anything to do with panda bears).
Before we can use the package, we need to import it. Try writing a line of code to import the `pandas` package:_____no_output_____

# write the code to import the package
_____no_output_____

We're going to be using `pandas` a lot. To save us some time typing, let's tell Python to rename the package for us to something a little shorter:_____no_output_____

import pandas as pd_____no_output_____

Adding "`as pd`" to our import statement tells Python that every time we use `pd`, we actually mean `pandas`. It's like giving the package a nickname! Most people use this same nickname for `pandas`, so if you see other people's code, you'll know that `pd` means `pandas`.

Now that we've imported `pandas`, we're ready to use it. Datasets are stored in `pandas` in a special container called a `DataFrame`. `DataFrames` help us handle data that are organized in rows and columns, just like the grocery store dataset above. We can store that data in a `DataFrame` by calling the `DataFrame` function:_____no_output_____

pd.DataFrame({'Product': ['Apples', 'Bananas', 'Lemons'],
              'Price': [1.50, 0.50, 1.99],
              'QuantitySold': [26, 32, 17]})_____no_output_____

Run the above cell and see what happens! There are a few things to notice:

1. Python helpfully showed us what our `DataFrame` looks like with rows and columns.
1. Python gave each row in the `DataFrame` a number, starting from zero. Does that remind you of something about lists?

When we ran that cell, Python showed us what the `DataFrame` looks like, but it didn't save the `DataFrame` anywhere. If we want to do more things with it, we'll need to save it to a variable. In the below cell to save the `DataFrame` to a variable called `fruit_data`:

(Hint: you may want to copy & paste the cell above to get started!)_____no_output_____

# save the DataFrame to a variable called fruit_data
_____no_output_____

When we run the above cell, does anything happen?

Since we saved the `DataFrame` to a variable, Python assumed that we don't want to take a peek at it. If we do want to see what our `DataFrame` looks like, we can write the variable on a line by itself like this:_____no_output_____

fruit_data_____no_output_____

Sometimes we don't want to see all of the data at once. To view just the first few rows of a `DataFrame`, we use a method called `head`.

Recall: methods are special functions that belong to certain types of variables. They only work with the type of variable that they belong to, so running `head` on a variable that isn't a `DataFrame` will not work.

Let's use the `head` method to view only the first two rows of our fruit data:_____no_output_____

# print head of fruit_data
_____no_output_____

After typing `head`, the name of the method, we wrote the number `2` between the parentheses. This told `head` that we wanted to see only the first two lines of our `DataFrame`. What would you do if you only wanted to see the first line of `fruit_data`?_____no_output_____

# write the code to see only the first line of the DataFrame
_____no_output_____

Great! What if instead of viewing the first few lines, we wanted to see the last few lines? For that we will use another method called `tail`. It is very similar to `head`, except it will show us the last few lines instead of the first few. Try writing a line of code to view the very last line of `fruit_data`:_____no_output_____

# get last line of fruit_data
_____no_output_____

`head` and `tail` are especially useful for big datasets with many rows so you can get a sense for what the `DataFrame` looks like without flooding your notebook with too much information. They will come in handy later!

Now let's talk about the types of variables we have in the `fruit_data` `DataFrame`. What are some of the types of variables we've learned about in Python?_____no_output_____**Types:** _____no_output_____Based on what you know about these types of variables, what `type` do you think the values in each of the columns belong to in `fruit_data`?_____no_output_____**Type of the `Product` column:**

**Type of the `Price` column:**

**Type of the `QuantitySold` column:**_____no_output_____Notice how each of the columns in `fruit_data` have different types. That's one of the many cool things about `pandas` -- it let's us store many different types of data in `DataFrames`._____no_output_____


# Notebook from TinaBBB/bayesian-critiquing-recommender
Path: keyphrase_sanity_check_yelp.ipynb

<code>
import pandas as pd
import scipy.sparse as sp
import numpy as np
import json
import torch_____no_output_____from sklearn.metrics.pairwise import cosine_similarity

def get_similar_keyphrases(input, m_kav_mean):
    cs = cosine_similarity(m_kav_mean[input].reshape(1, -1),m_kav_mean)[0]
    cands = cs.argsort()[::-1][1:6]
    return cands

def get_similar_keyphrases_movies(input, m_kav_mean, m_items):
    cs = cosine_similarity(m_kav_mean[input].reshape(1, -1),m_items)[0]
    cands = cs.argsort()[::-1][:5]
    return cands
_____no_output_____df_tags = pd.read_csv('./data/yelp/fold0/tr_tags.csv')

rows, cols = df_tags.item, df_tags.tag
values = np.ones(len(df_tags))

m_item_keyphrase= sp.csr_matrix((values, (rows, cols)), dtype='float64')_____no_output_____with open('./data/yelp/tag_id_dict.json') as f:
    tag_id_dict = json.load(f)
with open('./data/yelp/id_business_dict.json') as f:
    id_business_dict = json.load(f)

id_tag_dict = {id: tag for tag, id in tag_id_dict.items()}
id_business_dict = {int(id): b for id, b in id_business_dict.items()}_____no_output_____a_____no_output_____PATH = './saves/yelp/VAE_beta_multilayer.pt'
model = torch.load(PATH, map_location=torch.device('cpu'))
item_embeddings = model.decoder.weight.detach().numpy()
item_bias = model.decoder.bias.detach().numpy()_____no_output_____np.quantile(item_bias,0.01)_____no_output_____item_embeddings.shape_____no_output_____from utils.KAVgenerator import KAVgenerator
k = KAVgenerator(m_item_keyphrase,item_embeddings, 20)
keyphrase_embeddings = k.get_all_mean_kav(20, 100)0%|          | 1/245 [00:00<00:25,  9.46it/s]Generate Keyphrase Activation Vector
100%|██████████| 245/245 [00:18<00:00, 13.28it/s](245, 100, 100)

np.mean(np.linalg.norm(item_embeddings, ord=2, axis=1, keepdims=True))_____no_output_____np.mean(np.linalg.norm(keyphrase_embeddings, ord=2, axis=1, keepdims=True))_____no_output_____id_tag_dict _____no_output_____outputs = []_____no_output_____id = tag_id_dict['tea']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['tea'] + output)['milk', 'milk tea', 'bubble', 'noodle', 'soup']
id = tag_id_dict['cheesecake']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['cheesecake'] + output)['cake', 'wing', 'lobster', 'dessert', 'dim sum']
id = tag_id_dict['burger']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['burger'] + output)['fry', 'breakfast', 'pizza', 'pasta', 'juicy']
id = tag_id_dict['taco']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['taco'] + output)['cocktail', 'chip', 'bread', 'octopus', 'mexican']
id = tag_id_dict['italian']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['italian'] + output)['pasta', 'pizza', 'fresh', 'friendly', 'tomato']
id = tag_id_dict['sandwich']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['sandwich'] + output)['friendly', 'coffee', 'latte', 'cocktail', 'spicy']
id = tag_id_dict['japanese']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['japanese'] + output)['salmon', 'miso', 'creamy', 'green tea', 'fish']
id = tag_id_dict['parking']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)['fresh', 'crispy', 'markham', 'store', 'sesame']
id = tag_id_dict['spicy']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['spicy'] + output)['friendly', 'meat', 'fish', 'tuna', 'fresh']
id = tag_id_dict['ramen']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['ramen'] + output)['soup', 'noodle', 'bubble', 'dim sum', 'bubble tea']
id = tag_id_dict['vegetarian']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['vegetarian'] + output)['vegan', 'wrap', 'coffee', 'cozy', 'brunch']
id = tag_id_dict['healthy']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['healthy'] + output)['salad', 'coffee', 'cake', 'potato', 'chocolate']
id = tag_id_dict['french']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['french'] + output)['bread', 'brunch', 'olive', 'toast', 'wine']
id = tag_id_dict['cheap']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['cheap'] + output)['takeout', 'pork', 'noodle', 'pot', 'spring roll']
id = tag_id_dict['seafood']
cands = get_similar_keyphrases(id, keyphrase_embeddings)
output = []
for kp in cands:
    output.append(id_tag_dict[kp])
print(output)
outputs.append(['seafood'] + output)['meat', 'pricey', 'mayo', 'fresh', 'modern']
df = pd.DataFrame(outputs).set_index(0)
df.index.name = None
df_____no_output_____from utils.Dataset import Dataset
dataset = Dataset(data_dir='./data/yelp/fold0/',load_keyphrases=True)Read data from ./data/yelp/fold0/
def get_user_info(user_id, input_matrix):
    user_input = input_matrix[user_id]
    nonzeros = user_input.nonzero()
    items = nonzeros[1]
    ratings = user_input[nonzeros]
    ratings = np.asarray(ratings).reshape(-1)
    sorted_ratings_idx = ratings.argsort()[::-1]
    sorted_items = items[sorted_ratings_idx]
    sorted_ratings = ratings[sorted_ratings_idx]
    return sorted_items, sorted_ratings

def get_user_preds(user_id, input_matrix):
    user_input = input_matrix[user_id]
    mask_index = user_input.nonzero()[1]
    i = torch.FloatTensor(user_input.toarray()).to(torch.device('cpu'))
    with torch.no_grad():
        preds = model.forward(i).cpu().numpy()
    preds = np.asarray(preds).reshape(-1)
    preds[mask_index] = -np.inf
    sorted_pred_items = preds.argsort()[::-1]
    sorted_pred_ratings = preds[sorted_pred_items]
    return sorted_pred_items, sorted_pred_ratings

def get_mu_cov(user_id, input_matrix, moddel):
    user_input = input_matrix[user_id]
    i = torch.FloatTensor(user_input.toarray()).to(torch.device('cpu'))
    with torch.no_grad():
        mu, logvar = model.get_mu_logvar(i)
    std = model.logvar2std(logvar)
    mu, std = mu.numpy().T, std.numpy()

    return mu, np.diagflat(std*std)

def get_user_preds_using_mu(user_mu, input_matrix, model):
    user_input = input_matrix[user_id]
    mask_index = user_input.nonzero()[1]
    _mu = torch.FloatTensor(user_mu.T)

    with torch.no_grad():
        preds = model.decoder(_mu)
    preds = np.asarray(preds).reshape(-1)
    preds[mask_index] = -np.inf
    sorted_pred_items = preds.argsort()[::-1]
    sorted_pred_ratings = preds[sorted_pred_items]
    return sorted_pred_items, sorted_pred_ratings

def update_posterior(x, y, S_0, m_0, prec_y):
    S_0_inv = np.linalg.inv(S_0)
    #S_1 = np.linalg.inv(S_0_inv +prec_y * x @ x.T)
    #print(np.swapaxes(x,-2,-1).shape)
    S_1 = np.linalg.inv(S_0_inv +prec_y * np.matmul(x,np.swapaxes(x,-2,-1)))
    m_1 = S_1 @ (S_0_inv @ m_0 + prec_y * y * x)
    #print(m_1.shape)
    return S_1, m_1
_____no_output_____outputs = []
dataset.train_matrix.shape
_____no_output_____user_id = 351
sorted_items, sorted_ratings = get_user_info(user_id, dataset.train_matrix)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_business_dict[item_id])
print(output)
outputs.append(['user history'] + output)

sorted_items, sorted_ratings = get_user_preds(user_id, dataset.train_matrix)
top10_items = sorted_items[:330]
output = []

for item_id in top10_items:
    output.append(id_business_dict[item_id])
print(output)
outputs.append(['initial recs'] + output)
mu, cov = get_mu_cov(user_id, dataset.train_matrix, model)
['Gandhi Cuisine', 'Sansotei', 'Naniwa-Taro', 'Athens Pastries', 'One2 Snacks', 'Ghazale', 'Pho Linh', 'Von Doughnuts', 'Stop BBQ Chicken', 'Pho Metro']
['Fahrenheit Coffee', 'New Toronto Fish & Chips', 'Golden Dough', "I'll Be Seeing You", 'Shalom Ethopian Restaurant', "The Captain's Boil", 'Noble Coffee', 'Southeast Sandwiches', 'Veghed', 'New Orleans Seafood & Steakhouse', 'Yasu', 'Golden Gecko Coffee', 'Big Cannoli Lane', 'The Alternative Cafe', 'San Antonio Seafood Market', 'Hooked', 'Grill Gate', 'Harvest Green', 'Famiglia Baldassarre', 'The Dumpling Shop', 'Village Juicery', 'Baretto Caffe', 'Pestacio', "Scheffler's Delicatessen", 'Cobs Bread', 'Oakwood Espresso', "Yan's Soy Foods", 'Food Dudes Pantry', 'Porta Via Restaurant & Catering', 'La Cubana', 'De La Mer', 'Kekou Gelato House', "Mother's Deli & Bakery", 'Cakes By Robert', 'Cinnabon', 'Oca Nera', "Taro's Fish", 'Amma Roti House', 'Kristapsons', 'Pascale Gourmet', 'Crimson Teas', 'Alo Restaurant', 'La Salumeria', 'Mr. Chestnut', 'Pasta Pantry', 'DAVIDsTEA', 'Mississauga Rotary Ribfest', 'FK', 'Arabesque Middle Eastern Foods', 'Virtuous Pie', 'Momo Hut & Gardens', 'Bulldog Coffee', "St. Matthew's BBQ Chicken", 'Plentea', 'Viva Shawarma', 'Patisserie Royale', 'Crosstown Coffee Bar', "Dante's Inferno Paninoteca", "Uncle Mikey's", 'Nguyên Huong', 'De Floured', 'Grinning Face Non-Dairy Gelato', 'Bodira Cafe and Fine Foods', 'Quetzal', 'Scaramouche Restaurant Pasta Bar & Grill', 'The Coffee Lab', "Loga's Corner", 'Sugo', 'Starbucks', 'Green Box Express', 'The Butternut Baking', '9 Bars', 'JP Sushi', 'Melrose On Adelaide', 'Wynona', "Ruby's Mediterranean Cuisine", "Wong's Ice Cream & Store", 'Ying Ying Soy Food', 'Road Grill Food Truck', 'Panino Cappuccino', 'Bar Sybanne', 'When The Pig Came Home', 'Mystic Muffin', 'Bar Ape', 'Piedmont Coffee Bar', 'The Olde Yorke', 'Loukoumania Café', 'Zeal Burgers', 'JJ Bean', 'Pomarosa Coffee Shop & Kitchen', 'La Paella', 'Baklawa King', 'El Nahual', 'A-Game Cafe', 'Wallace Espresso', 'Kitten and the Bear', "Gryfe's Bagel Bakery", 'Adamson Barbecue', 'Orly Grill', "Kozlik's Canadian Mustard", 'UB Social Cafe & General Store', 'Pow Wow Cafe', 'Di Manno Bakery', 'Village Meat Products & Deli', 'Ital Vital', 'Taste Seduction', 'Prairie Boy', "Chica's Nashville Hot Chicken", 'Burrito Boyz', 'Ay Caramba, Eh', 'Avoca Choclatier', "Craig's Cookies", 'La Chilaca Taqueria', 'Tuk Tuk Canteen', 'Starbucks', 'The Shore Leave', 'The Ellery', 'Gloria Espresso Bar & Cafe', 'Tdotjerk', 'Vindaloo Indian Cuisine', 'Cafe Tibet Bar & Grill', 'Ideal Catering', "Chubby's Subs", 'Dimpflmeier Bakery', "Grandmama's Waffles", "Blaze Fast-Fire'd Pizza", 'Zezafoun Syrian Cuisine', 'Aielli Ristorante', 'The Grow Op', 'The Golden Pheasant', 'Asteria Souvlaki Place', 'Bagels On Fire', 'Miku', 'Katsuya', 'La Sem Patisserie', "Rose's Vietnamese Sandwiches", "Rose's Halal Kitchen", 'Mallo', 'Zav Coffee Shop & Gallery', 'The Sushi Bar', 'Cafe de Melbourne', 'San Antonio Foods', 'The 5th Taste Sushi Restaurant', 'The Corner Bank', 'Lox + Schmear', 'The Epicure Shop', 'Death in Venice Gelato', 'Maison Close 1888', "Her Father's Cider Bar & Kitchen", 'The Food Dudes', 'Islas Filipino BBQ and Bar', "Joso's", 'Soma Chocolatemaker', 'Le Baratin', 'Pizzeria Defina', 'Grasshopper Restaurant', 'Honest Weight', 'Budapest Restaurant', 'Kekou Gelato', 'Beijing Hot Pot Restaurant', 'Egg Sunrise Grill', 'The Bulging Burger', 'Umami Poke', 'Maple Produce', 'Jugemu', 'Himalayan Kitchen', 'Blooming Orchid', 'Refuel Juicery', 'Futura Granita + Gelato', 'Fragrant Bakery', 'Lageez', 'BB Cafe', 'Millwood Melt Grilled Cheesery', 'The Pie Commission', 'Giulietta', 'Jumbo Burger Restaurant', 'Strange Love', 'Rollz Ice Cream & Desserts', 'Grande Cheese', 'Highland Fish & Chips', 'Famous Last Words', 'Grillway Souvlaki House On Bloor', 'Second Cup', 'Starbucks', "Bud's Coffee Bar", 'Bean and Baker Malt Shop', 'Mama Earth Organics', 'Montmartre Bakery', "Kunafa's", 'St Clair Ice Cream', 'Pita Golden Pocket', 'Felix & Norton', 'San Francesco Foods - Clinton', 'Sweet Flour Bake Shop', 'Itacate', 'Shoushin', 'VOS Restaurante Argentino', 'Madame Gateaux', 'Rise & Dine Eatery', 'Boxcar Social', 'Crepe TO', 'Mrakovic Meat & Deli', 'Pilot Coffee Roasters', 'Bake Shoppe', 'La Limonada', 'Muncheez', 'Porchetta Roll', 'The Art of Cheese', 'Mazar Kabob', 'The Merseyside', 'Sunny Morning', 'Meat Point', 'Pulp Kitchen', 'Northern Belle', "Summer's Ice Cream", "Allwyn's Bakery", 'Tandem Coffee', 'Aloette', 'Sasaki Fine Pastry', 'Rasa', 'Takht-e Tavoos', "Tom's Dairy Freeze", 'Cheese Boutique', 'Gyubee Japanese BBQ - Downtown', 'Koji Japanese Restaurant', 'Kookminhakgyo', 'Karahi Point', 'Douce France', 'Sushi Wa', 'Tasso Bakery ', 'Mon K Patisserie', 'DOMA', "Marcheleo's Gourmet Marketplace", 'Patisserie 27', 'Kay Pacha', 'Hale Coffee', 'Fanzone Wings & Ribs', 'Barans Turkish Cuisine & Bar', 'The Sidekick', 'La Campagna Italian Eatery', 'DAVIDsTEA', 'The Depanneur', 'The Irv Gastro Pub', 'Tropical  Energy Juice Bar', 'The Green Dragon', 'thairoomgrand', 'La Guanaquita', 'Simply Frosted Cupcakery', 'Soul Chocolate', 'Fast Fresh Foods', 'Pantry Foods', 'Local 1794', 'Hodo Kwaja', 'Mare Pizzeria', 'Extra Burger', 'Rikkochez', "Mike's Fish Market", 'Creeds Coffee Bar', 'Lake Inez', 'Bake Sale at Six Points', 'Halo Halo', 'Citizenry', 'HotBlack Coffee', 'Fahrenheit Coffee', 'Booster Juice', 'Fabarnak Community Cafe and Catering', 'Zaza Espresso Bar', 'Cocktail Bar', 'Roselle', 'Shawarma Empire', 'Sidebar', 'Cock-A-Doodle-Doo', 'Fruitti Mix', 'Bolan Thai Cuisine', 'Arigato', 'Omaw', 'Silk Restaurant & Bar', 'Artegelato & Caffe', 'Tinuno', 'Starbucks', "Jordan's Shawarma", 'The Four Seven', 'Canis', 'Black Camel', "Ed's Real Scoop", 'Souv Like', 'Salad Days', "Mama's Tofu", 'Pretty Ugly', '2nd Nature Bakery and Cafe', 'Bloor Fruit Market', 'Pegasus On Church', 'Put A Cone On It', "Mana'ish Global Flatbread Cafe", 'Imm Thai Kitchen', 'deKEFIR', 'The Bake House', 'Tibet Kitchen', 'Freshouse Juice Bar', "Nancy's Cheese", 'Starbucks', 'Blackbird Baking', 'Shawarma Q', 'Coral Sea Fish Market', 'Hailed Coffee', 'Refinery Public House', 'Figs and Olives', 'Civil Liberties', "V's Caribbean Restaurant", 'Estia', "Veggie D'Light", 'Palmyra Mediterranean House', 'Fearless Meat', 'Delight', 'Daddy O Doughnuts and British Baked Goods', 'Zane Patisserie', 'Sushi Omigoto', 'Cobs Bread', 'Saigon Lotus', 'Founder Bar', "Ricci's Pizzeria & Sandwich Shoppe", 'Kings Delight Caribbean Cuisine', 'Royal Jade', 'Rooster Coffee House', 'JJ Bean', 'Ho Sushi Express', 'Noce Restaurant', "Allan's Pastry Shop", 'Rooster Coffee House', 'Pizza Break']
sorted_ratings[1]_____no_output_____seafood = tag_id_dict['chip']_____no_output_____mu.T@keyphrase_embeddings[seafood][:,np.newaxis]_____no_output_____np.quantile(mu.T@(keyphrase_embeddings.T),q=0.01)_____no_output_____np.quantile(mu.T@(item_embeddings.T),q=0.1)_____no_output_____item_embeddings.shape_____no_output_____prec = np.linalg.norm(1/(cov+1e-6))
neg = np.min(mu.T @ keyphrase_embeddings.T)
pos = np.max(mu.T @ keyphrase_embeddings.T)
print(pos, neg)3.2033172233684457 -2.282314772954342
prec_____no_output_____x = keyphrase_embeddings[seafood][:,np.newaxis]
y = [[neg]]

cov1, mu1 = update_posterior(x, y, cov, mu, np.array(1))_____no_output_____mu1.T@keyphrase_embeddings[seafood][:,np.newaxis]_____no_output_____sorted_items, sorted_ratings = get_user_preds_using_mu(mu1, dataset.train_matrix, model)
top10_items = sorted_items[:50]
output = []
for item_id in top10_items:
    output.append(id_business_dict[item_id])
print(output)
outputs.append(['+ franch'] + output)['Fahrenheit Coffee', 'Golden Dough', "The Captain's Boil", 'New Toronto Fish & Chips', "I'll Be Seeing You", 'Shalom Ethopian Restaurant', 'Noble Coffee', 'Southeast Sandwiches', 'Yasu', 'Veghed', 'Big Cannoli Lane', "Yan's Soy Foods", 'The Dumpling Shop', 'Famiglia Baldassarre', 'Golden Gecko Coffee', 'Pestacio', 'New Orleans Seafood & Steakhouse', 'Baretto Caffe', 'Grill Gate', 'Harvest Green', 'San Antonio Seafood Market', 'The Alternative Cafe', 'Cobs Bread', 'Village Juicery', 'Hooked', "Mother's Deli & Bakery", 'Oakwood Espresso', "Scheffler's Delicatessen", 'Porta Via Restaurant & Catering', 'Kekou Gelato House', 'Amma Roti House', 'Oca Nera', "Taro's Fish", 'Food Dudes Pantry', 'De La Mer', 'Kristapsons', 'Cinnabon', 'Cakes By Robert', 'Mr. Chestnut', 'La Cubana', 'Mississauga Rotary Ribfest', 'Alo Restaurant', 'Nguyên Huong', 'Pascale Gourmet', 'Crimson Teas', 'DAVIDsTEA', 'Viva Shawarma', 'Green Box Express', 'Starbucks', "Dante's Inferno Paninoteca"]
seafood = tag_id_dict['dessert']
x = keyphrase_embeddings[seafood][:,np.newaxis]
y = [[pos]]

cov2, mu2 = update_posterior(x, y, cov1, mu1, np.array(1000))

sorted_items, sorted_ratings = get_user_preds_using_mu(mu2, dataset.train_matrix, model)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_business_dict[item_id])
print(output)
outputs.append(['- japanese'] + output)["Yan's Soy Foods", 'Mr. Chestnut', "Allan's Pastry Shop", 'Yasu', 'Grande Cheese', 'The Dumpling Shop', 'Lox + Schmear', 'Fahrenheit Coffee', "Taro's Fish", 'Bodira Cafe and Fine Foods']
df = pd.DataFrame(outputs).set_index(0)
df.index.name = None
df_____no_output_____outputs = []_____no_output_____user_id = 300
sorted_items, sorted_ratings = get_user_info(user_id, dataset.train_matrix)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id][:-7])

outputs.append(['user history'] + output)
print(output)

sorted_items, sorted_ratings = get_user_preds(user_id, dataset.train_matrix)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id][:-7])
outputs.append(['initial recs'] + output)
print(output)

mu, cov = get_mu_cov(user_id, dataset.train_matrix, model)
prec = np.linalg.norm(1/(cov+1e-6))

prec = np.linalg.norm(1/(cov+1e-6))
neg = np.min(mu.T @ keyphrase_embeddings.T)
pos = np.max(mu.T @ keyphrase_embeddings.T)
print(pos, neg)['Pulp Fiction', 'Battleship Potemkin, The (Bronenosets Potyomkin)', 'Woman Under the Influence, A', 'Apocalypse Now', 'Seven Samurai (Shichinin no samurai)', 'Wings of Desire (Der Himmel über Berlin)', 'Son, The (Le Fils)', 'Stroszek', 'Rio Bravo', 'Wallace & Gromit: The Curse of the Were-Rabbit']
['Pier, The (La Jetée)', '2001: A Space Odyssey', '8 1/2', 'Sunrise: A Song of Two Humans', 'Andrei Rublev (Andrey Rublyov)', 'Gerry', 'Paranoid Park', 'Wild Bunch, The', 'Red River', 'Cyclo (Xich lo)']
2.684969023457633 -2.7016516940258937
x = keyphrase_embeddings[18][:,np.newaxis]
y = [[pos]]

cov1, mu1 = update_posterior(x, y, cov, mu, np.array(1))

sorted_items, sorted_ratings = get_user_preds_using_mu(mu1, dataset.train_matrix, model)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id][:-7])
outputs.append(['+ fantasy'] + output)
print(output)

['Pier, The (La Jetée)', '2001: A Space Odyssey', '8 1/2', 'Sunrise: A Song of Two Humans', 'Andrei Rublev (Andrey Rublyov)', 'Gerry', 'Paranoid Park', 'Wild Bunch, The', 'Red River', 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb']
x = keyphrase_embeddings[18][:,np.newaxis]
y = [[neg]]

cov1, mu1 = update_posterior(x, y, cov, mu, np.array(10))

sorted_items, sorted_ratings = get_user_preds_using_mu(mu1, dataset.train_matrix, model)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id][:-7])
outputs.append(['- fantasy'] + output)
print(output)

['Pier, The (La Jetée)', 'Sunrise: A Song of Two Humans', 'Sorrow and the Pity, The (Chagrin et la pitié, Le)', 'Gerry', '2001: A Space Odyssey', 'Paranoid Park', 'Andrei Rublev (Andrey Rublyov)', '8 1/2', 'Au Hasard Balthazar', 'Fat City']
df = pd.DataFrame(outputs).set_index(0)
df.index.name = None
df_____no_output_____mu.T@keyphrase_embeddings[18][:,np.newaxis]_____no_output_____x = keyphrase_embeddings[37][:,np.newaxis]
y = [[2]]

cov2, mu2 = update_posterior(x, y, cov1, mu1, np.array(np.linalg.norm(1/(cov1+1e-6))))
sorted_items, sorted_ratings = get_user_preds_using_mu(mu2, dataset.train_matrix, model)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id])
print(output)

['Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb (1964)', 'City Lights (1931)', 'Chinatown (1974)', '2001: A Space Odyssey (1968)', 'Godfather, The (1972)', 'Maltese Falcon, The (1941)', 'Annie Hall (1977)', 'Godfather: Part II, The (1974)', 'Double Indemnity (1944)', 'Treasure of the Sierra Madre, The (1948)']
user_id = 77
sorted_items, sorted_ratings = get_user_info(user_id, dataset.train_matrix)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id])
print(output)

sorted_items, sorted_ratings = get_user_preds(user_id, dataset.train_matrix)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id])
print(output)

mu, cov = get_mu_cov(user_id, dataset.train_matrix, model)
['Pulp Fiction (1994)', 'Star Trek II: The Wrath of Khan (1982)', '8 1/2 (1963)', 'Sling Blade (1996)', 'Dogma (1999)', 'Fight Club (1999)', 'Third Man, The (1949)', 'Lord of the Rings: The Fellowship of the Ring, The (2001)', 'Boat, The (Das Boot) (1981)', 'Fanny and Alexander (Fanny och Alexander) (1982)']
['Godfather, The (1972)', 'Memento (2000)', 'Usual Suspects, The (1995)', 'Face in the Crowd, A (1957)', 'Saving Private Ryan (1998)', 'Mongol (2007)', 'Bad Santa (2003)', 'Terminator 2: Judgment Day (1991)', 'Curious Case of Benjamin Button, The (2008)', 'Aliens (1986)']
x = keyphrase_embeddings[19][:,np.newaxis]
y = [[5.]]

cov1, mu1 = update_posterior(x, y, cov, mu, np.array(100))
cov1
sorted_items, sorted_ratings = get_user_preds_using_mu(mu1, dataset.train_matrix, model)
top10_items = sorted_items[:10]
output = []
for item_id in top10_items:
    output.append(id_title_dict[item_id])
print(output)

['Usual Suspects, The (1995)', 'Memento (2000)', 'Terminator 2: Judgment Day (1991)', 'Aliens (1986)', 'Saving Private Ryan (1998)', 'Godfather, The (1972)', 'X2: X-Men United (2003)', 'Gattaca (1997)', 'Spider-Man 2 (2004)', 'Monty Python and the Holy Grail (1975)']
id_tag_dict_____no_output_____model.logvar2std(logvar)_____no_output_____sorted_ratings = ratings.argsort()[::-1]
sorted_items = items[sorted_ratings]
sorted_items_____no_output_____arr1inds_____no_output_____ratings[arr1inds]_____no_output_____a =np.random.normal(np.zeros(150),0.01)
a = a[:,np.newaxis]_____no_output_____np.quantile(a.T@(keyphrase_embeddings.T),q=0.99)_____no_output_____np.random.normal(np.zeros(50),0.001)_____no_output_____a = np.zeros((150,150), int)
np.fill_diagonal(a, 1)

np.linalg.norm(a)_____no_output_____def get_predictive_dist(x_pred, S, m, prec_y):
    print(m.T)
    pred_means = m.T @ x_pred
    pred_means = pred_means.flatten()
    pred_vars = np.sum(1/prec_y + x_pred.T @ S * x_pred.T, axis=1)

    return pred_vars, pred_means_____no_output_____x_pred = np.array([[1,2,3],[2,3,4]]).T
S = np.array([[1,1,1],[1,1,1],[1,1,1]])
m = np.array([[1],[2],[3]])
get_predictive_dist(x_pred, S, m, 1)

[[1 2 3]]
np.array([1,2,3]) == 1_____no_output_____np.array(np.linalg.norm(1/(S+1e-6)))**2_____no_output_____
</code>


# Notebook from hcchengithub/peforth
Path: notebook/peforth magic command on jupyter notebook.ipynb

# peforth magic command on jupyter notebook

peforth supports jupyter notebook magic command `  %f  ` since v1.15 _(released to Pypi on 2018.3.12)_ with both _line magic_ and _cell magic_.

If you are running this jupyter notebook page online through [mybinder.org](https://mybinder.org/v2/gh/hcchengithub/peforth/master?filepath=notebook) then no installation is needed.

If you would like to work on your computer, so you can save changes you made, then
`pip install peforth` to install peforth and that's all, assume you already have jupyter notebook installed.
_____no_output_____### 1. import peforth [$^i$](#i.-The-ipython-setting-to-automatically-load-peforth-%f-magic)

peforth magics are unknown to jupyter notebook at first untill we `import peforth`._____no_output_____

import peforthreDef unknown

### 2. Hello World!

Here after, in any python code cell, a `%f` leading line is interpreted as a FORTH line, called _line magic_. The next cell is an example of the `version` command that shows peforth greeting message and leaves the version number on the data stack._____no_output_____

%f version .sp e f o r t h    v1.23
source code http://github.com/hcchengithub/peforth
Type 'peforth.ok()' to enter forth interpreter, 'exit' to come back.

      0: 1.23 (<class 'str'>)
%f ." Hello World!" crHello World!

The amazing thing here is that the ` %f ` line magic can be used in python code. . . _____no_output_____

# use %f line magic in a python code function definition,
def hi():
    %f ." Hello World!" cr

# believe it or not, it works!
hi()Hello World!

### 3. line magic is compiled to a python statement

Now use peforth command `.source` to find out why this is possible . . . _____no_output_____

%f __main__ :> hi .source
def hi():
    get_ipython().run_line_magic('f', '." Hello World!" cr')

The ` %f ` line magic is compiled into a python statement, that's why. [Some more explanations given at the end of this page.](#ii.-A-line-magic-command-line-compiled-to-python-statement)_____no_output_____### 4. peforth `%%f` cell magic

A cell leading with a ` %%f ` (double `%%` instead of single `%` in line magic form) becomes a block of FORTH code._____no_output_____

%%f Nothing allowed before %%f except white spaces; everything in this line after %%f is ignored.

\ Demonstrating the peforth interpret mode [for]..[next] loop

5 [for] t@ . space [next] cr

\ For experienced FORTH users
\ Where t@ is like the FORTH word r@ but it fetches TIB stack instead of the traditional
\ FORTH return stack. Because TIB is the only resource that belongs to this interpreting
\ life cycle alone.5 4 3 2 1

Now use the ` [for] ` loop to print a pyramid:_____no_output_____

%%f
: star ." *" ;
: 2stars star star ;
: stars for star next ;
star cr 2stars cr 10 [for] 13 t@ - stars cr [next] *
**
***
****
*****
******
*******
********
*********
**********
***********
************

### 5. peforth to access the __main__ name space directly

Peforth and the Jupyter Notebook are of different name spaces, meaning that peforth can't see the `x` variable in the example below:_____no_output_____

x = 123
%f x . cr123

The reason why we choose FORTH is for its super flexibility. Now let's redefine the way peforth handles an unknown token, i.e. the `x` of the above example. Instead of alerting `"Error! x unknown."` we let it try to find the token in the Jupyter Notebook `__main__` module object.

_Note: peforth v1.16 and newer version is required to play this trick. Since v1.23 the 'unknown' introduced below has become a built-in so we don't need the re-definition. Instead, use marker command '===' to forget it so the 'x' would be an 'unknown' again.______no_output_____

%%f   Now we redefine the 'unknown' command (it does nothing by default)

: unknown // ( token -- thing y|n) Try to find the unknown token in __main__
  py> getattr(sys.modules['__main__'],pop(),"Ûnknôwn")
  py> str(tos())=="Ûnknôwn" if drop false else true then ;

\ here after, when FORTH come accross an unknown token, instead of printing the
\ error message, it try to find the token in python __main__ module name space.reDef unknown

now test again:_____no_output_____

y = 'abc'
%f y . cr
%f x . crabc
123

peforth seems _know_ the 'x' and 'y' now while it doesn't. This trick is vary useful when we are studying and we can investigate things in FORTH way._____no_output_____### 5. So where is the _muggle FORTH_ that works as a REPL shell environment?_____no_output_____` peforth.ok() ` is the peforth interpreter itself. Run ` peforth.ok() ` to _shell_ a level of the FORTH interpreter and ` exit ` command to come back._____no_output_____

# Run this cell to enter peforth console (REPL loop or command line interface)
# Note the Out[ ] of this cell, the `[*]` indicates that the command line interface
# is running. Play with it or copy-paste this line:
#     "star cr 2stars cr 10 [for] 13 t@ - stars cr [next] exit"
# to try again the pyramid example above. 'exit' command to terminate.
peforth.ok()  star cr 2stars cr 10 [for] 13 t@ - stars cr [next] exit
*
**
***
****
*****
******
*******
********
*********
**********
***********
************
OK

### 6. Cascading peforth exported functions

` %f ` and ` %%f ` magics are actually performing the ` peforth.dictate('command lines') ` exported function, while ` peforth.ok() ` is the REPL loop of the same function. Try:

    peforth.dictate(" .' hello world!' cr ")

that works exactly as we have tried at first._____no_output_____

peforth.dictate(" .' hello world!' cr ")  # Note the Out[ ] of this cellhello world!

Observed from the above outputs, `peforth.ok()` and `peforth.dictate()` both return the peforth module object.  This means that we can _cascade_ these functions. The next example sees the type of the 'star' command that we definded above:_____no_output_____

%%f
' star   \ get the word object, we defined 'star' above remember?
:> type  \ get 'type' attribute of the word object
. cr     \ show what we have got ... it is a 'colon' word, isn't it?colon

It's correctly a 'colon' word. The next example in python code is actually doing the same thing as the above FORTH code:_____no_output_____

# Example of cascaded functions, to check a given FORTH word's type

type_of_star = peforth.push('star').dictate("(') :> type").pop() # cascaded functions
print(type_of_star)colon

Where ` (') ` and ` :> ` are peforth words explained by ` help ` command as shown below. Function cascading is very useful for peforth to debug or to investigate your python target code.

Peforth functions that can be called cascadedly are: ` peforth.ok() `, ` peforth.dictate() ` , ` peforth.push() ` and ` peforth.execute() `._____no_output_____

%f help (')( "name" -- Word ) name>Word like tick but the name is from TOS.

%f help :>         ( obj  -- value ) Simplified form of "obj py> pop().foo.bar" w/return value
	down to the next whitespace

More information about peforth are on [the wiki of the project on Github](http://github.com/hcchengithub/peforth).

May the FORTH be with you!

H.C. Chen @ FigTaiwan

Last Edited: 2018.6.27

_____no_output_____

## Notes _____no_output_____### i. The ipython setting to automatically load peforth %f magic

Optionally if you want ipython to load `%f` magic automatically at startup of every jupyter notebook, so you don't need to `import peforth` explicitly everytime, what you need to do is to make . . .

this config file:

    C:\Users\<your user name>\.ipython\profile_default\ipython_config.py (for Windows)
    or
    ~/.ipython/profile_default/ipython_config.py (for Linux)

this line:

    # A list of dotted module names of IPython extensions to load.
    c.InteractiveShellApp.extensions = ['peforth']

to have 'peforth' in the list as shown above._____no_output_____### ii. A line magic command line compiled to python statement

`__main__` is a peforth word that returns the main program module object which in the current case is this jupyter notebook. `__main__` is the parent module of the funcion `hi()` and ` __main__ :> hi ` is the way peforth gets the `hi` function object. Finally ` .source ` displays the source code on top of the FORTH data stack which is now the ` hi ` function object. So this line magic:

    %f __main__ :> hi cr

is compiled to:

    get_ipython().run_line_magic('f', '." Hello World!" cr')

Where ` 'f' ` is apparently the peforth magic command's name.
_____no_output_____ # --- The End ---_____no_output_____