# Basics

In this section, we will present classical computer science algorithms such as stacks, sorting etc.; constraint satisfaction algorithms such as knapsack, travelling travelling salesman etc. and market related algorithms such as next-purchase, churn predection etc. However, before all of this we want to show some basics in this story. It will be a live story, so you can always come back and check for the updates. Please not that all scripts will be in Python.

## Python Basic Types

Some familarity with numbers

Let’s represent some basic numerical operations in a table

You can make simple operations like below:

`print(8**3)    print(2**0.5)print(8/3)print(8%3)print(8//3)Output:5121.41421356237309512.666666666666666522`

In Python we can represent complex numbers. As you may know, complex numbers come with real and imaginary component. You can represent the imaginary component via j as below

`a = (3 + 2j)b = (5–3j)`

You can handle all the numerical operations with imaginary numbers in Python.

`print(a+b)print(a*b)print(a/b)Output:(8-1j)(21+1j)(0.2647058823529412+0.5588235294117647j)`

Assignments

We can assign values to any variable easily like (a = x). But also keep in mind that we can assign them in order too. In the below example (c = 6) and
(d =7)

`c, d = 6, 7c += 2print(c)c /= -2print(c)d = d*3print(d)`

In general, c+= 2 would means nothing. However in Python below values are equal

`c = c + 2c += 2`

Specially in our algorithms section, we will use NumPy module quite a lot. Firstly let’s explain the word “module”. A file containing a set of functions you want to include in your application. Numpy is a very useful module in Python. Read the definition from official site https://numpy.org/

NumPy is the fundamental package for scientific computing with Python. It contains among other things:

a powerful N-dimensional array object

tools for integrating C/C++ and Fortran code

useful linear algebra, Fourier transform, and random number capabilities

Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.

In Python, we import modules with import statement on the top of the code.

There are so many great operations options in NumPy here is the list of some

`sqrt(x) square root of xexp(x) exponential of x, i.e., exlog(x) natural log of x, i.e., lnxlog10(x) base 10 log of xdegrees(x) converts x from radians to degreesradians(x) converts x from degrees to radianssin(x) sine of x (x in radians)cos(x) cosine x (x in radians)tan(x) tangent x (x in radians)arcsin(x) Arc sine (in radians) of xarccos(x) arc cosine (in radians) of xarctan(x) arc tangent (in radians) of xfabs(x) absolute value of xmath.factorial(n) n! of an integerround(x) rounds a float to nearest integerfloor(x) rounds a float down to nearest integerceil(x) rounds a float up to nearest integersign(x) -1 if x < 0, +1 if x > 0, 0 if x = 0pi PI number`

Here is a quick example:

`import numpy as npprint(np.sign(5))print(np.round(9.876665))# to nearest integerprint(np.floor(9.86868263))# down to nearest integerprint(np.ceil(9.38792739))# up to nearest integerprint(np.math.factorial(5))# factorialprint(np.degrees(4))# adians to degreesprint(np.radians(90))#degrees to radiansprint(np.sqrt(125))#square rootOutput:110.09.010.0120229.18311805232931.570796326794896611.180339887498949`

Suppose you want to calculate distance between two Cartesian coordinates.

We can easily execute it by NumPy sqrt function

`import numpy as np x1, y1, z1 = 17.2, -6.9, 4.5x2, y2, z2 = -5.6, 12.3, 8.1r = np.sqrt((x2 — x1)**2 + (y2-y1)**2 + (z2-z1)**2)print(r)Output:30.02399040767233`

So let’s create the general form of quadratic function. ( We can do it via python function but let’s don’t do this now)

General Form : ax2+bx+c,where a≠0

We can execute this operation in many ways thanks to NumPy. But the easiest way is using roots function.

`import numpy as np coeff = [1,2,1]t = np.roots(coeff)print(t)Output:[-1. -1.]`

Python Basic Data Structures

Strings

Strings are lists of characters. Any character that you can type from
a computer keyboard, plus a variety of other characters, can be elements
in a string. Strings are created by enclosing a sequence of characters
within a pair of single or double quotes. We can make ordinary operations with strings like we did it in the numbers.

`a = " stave "b = " partners"c = "For new generation products"print(a + b)print(a, end='')print(b, end= '! ')print(c, end= ' ')Output:stave  partnersstave  partners! For new generation products`

You may notice that print took an end parameter. It’s important to know that, we will use this parameter quite a lot in our algorithms. GeeksForGeeks explained it beautifully:

Python’s print() function comes with a parameter called ‘end’. By default, the value of this parameter is ‘\n’, i.e. the new line character. You can end a print statement with any character/string using this parameter.

We can change types in Python. Let’s try this:

`a = 97b = “97”a = str(97)b = int(“97”)print(a)print(b)print(a+b)Output:9797TypeError: must be str, not int`

So as you can see, it return actually different results. Because numbers are also alpha numeric characters,strings can be made up of numbers. We can fix this error in this script:

`c = “88”d = 88print(c + str(d))print(int(c) + d)Output:8888176`

Lists

Python has 2 simple structure. List ans Tuples. Both are accept strings and numbers.

`a = [9, 1, 1, 7, 4, 5, 8, 32]b = [90., "stabe", 1+0j, "partners", 65]i = aj = bk = b[-2]l = a[:3]m = a[3:]t = a[1:3]y = b[:]print(i)print(j)print(k)print(l)print(m)print(t)print(y)Output:1(1+0j)partners[9, 1, 1][7, 4, 5, 8, 32][1, 1][90.0, 'stabe', (1+0j), 'partners', 65]`

Please read the result carefully. a[x:y] actually return as from x untill y.

We can create list with values in some range. Simply, we can do it by range function. Also please not that list function returns a list and accept iterable.

range(start,stop,step) → Define the start point, stop point and the step size for the range function. For default step size is 1.

`print( list(range(100,110,2)) )print( list(range(10)))print( list(range(5,10)))Output:[100, 102, 104, 106, 108][0, 1, 2, 3, 4, 5, 6, 7, 8, 9][5, 6, 7, 8, 9]`

Tuples

Basicly tuples are immutable lists. You can’t change their value. Except that you can apply all the operations like in the lists.

`a = (7,8,9,12,13) #tupleb = [7,8,9,12,13] #listprint( a[-1] )print( a[2:])b = 199print ( b)a = 99print( a)Output:13(9, 12, 13)199TypeError: 'tuple' object does not support item assignment`

We can also create multidimensional lists and tuples and like always, access them with their index number.

`#2x2 Listliss = [[2,3], [3,4], [5,6], [7,8]]print(liss)print(liss)print(liss)Output:[[2, 3], [3, 4], [5, 6], [7, 8]][2, 3]3`

NumPy Arrays

NumPy Arrays are very useful specially for scientific computation. Basicly they are simple lists. They can accept any kind of object include booleans.

There are several ways for creating NumPy array. First one is array function. Simply, it changes the list to a NumPy array.

`import numpy as npa = [1,2,3,4,7,9,12,12,18]b = np.array(a)print(b)Output:[ 1  2  3  4  7  9 12 12 18]`

Please note that, NumPy array takes many type of objects but return the array elements as most popular object. For example, if our list include mostly strings and integer; our NumPy array will be made of strings.

Second way for creating NumPy array is linspace and logspace functions. The linspace function creates an array of N evenly spaced points between a starting point and an ending point. The form of the function is
linspace(start, stop, N).

`import numpy as npprint(np.linspace(10,15,10))Output:[10.         10.55555556 11.11111111 11.66666667 12.22222222 12.77777778 13.33333333 13.88888889 14.44444444 15.        ]`

NumPy also has a closely related function logspace that produces evenly spaced points on a logarithmically spaced scale.The arguments are the same as those for linspace except that start and stop refer to a power of 10. That is, the array starts at 10**start and ends at 10**stop.

`import numpy as npprint(np.logspace(2,3,5))Output:[ 100.          177.827941    316.22776602  562.34132519 1000.        ]`

NumPy also has a function is very similar to range function (remember from the lists) called arrange. Basicly it do the same thing.

`import numpy as npprint(np.arange(10,20,2))Output:[10 12 14 16 18]`

Lastly we can create arrays with zeros and ones. Also we can create identity matrix with NumPy. For those we will use:

`zeros(num, dtype= ‘float’)ones(num, dtype = ‘float’)eye(num, dtype = ‘float)`

Basically in default type will be float if you won’t change it. What about multidimensional arrays? Here you go:

`import numpy as nparr = np.array([[1,2,3], [1,2,3]])print(arr)Output:[[1 2 3] [1 2 3]]---arr = np.ones((3,4), dtype = ‘float’)print(arr)Output:[[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]]`

So let’s make an example. Suppose you have 2 array p and t for position and time. For an object each cell will return the position for the p and the exact time for the t. So the velocity of the object is:

It’s time to slice the arrays and make the calculation

`import numpy as npp = np.array([0., 1.3, 5. , 10.9, 18.9, 28.7, 40.])t = np.array([0., 0.49, 1. , 1.5 , 2.08, 2.55, 3.2])v = (p[1:] — p[:-1])/(t[1:] — t[-1])print(v)Output:[-1.32       -1.06818182 -0.4047619          inf] (Divide by Zero Error)`

Let’s create a 2D array where all the elements are 5

`import numpy as nparr = 5* np.ones((5,5))print(arr)Output:[[5. 5. 5. 5. 5.] [5. 5. 5. 5. 5.] [5. 5. 5. 5. 5.] [5. 5. 5. 5. 5.] [5. 5. 5. 5. 5.]]`

What about multipication of two matrices? NumPy has dot function for that.

`import numpy as nparr = 5* np.ones((5,5))arr2 = 2* np.ones((5,3))cal = np.dot(arr, arr2)print(cal)Output:[[50. 50. 50.] [50. 50. 50.] [50. 50. 50.] [50. 50. 50.] [50. 50. 50.]]`

Dictionaries

Dictionaries are lists with collection of objects. Suppose we want to make a dictionary of room numbers indexed by the name of the person who occupies each room. We create our dictionary using curly brackets {…}.

` room = {“Emma”:309, “Jake”:582, “Olivia”:764}`

The dictionary above has three entries separated by commas, each entry
consisting of a key, which in this case is a string, and a value, which in this case is a room number. Each key and its value are separated by a colon. The syntax for accessing the various entries is similar to a that of a list, with the key replacing the index number. For example, to find out the room number of Olivia, we type

`room[“Olivia”]Output:764`

Creating dictionary is very straightforward and simple.

`d= {}d[“firstName”] = “Stave”d[“lastName”] = “Partners”print(d)Output:{‘firstName’: ‘Stave’, ‘lastName’: ‘Partners’}`

Objects

Basically, object is a collection of data with associated variables. Suppose we have a 4 kinds of objects. Apple, Orange, Barrel and Basket. In Python, we can say that we have 4 classes. But what is the difference? Classes describe objects. You may have 3 apples. Each one is an object but they could have different weights or colors. So, apples are associated with Apple class. This Apple Class describe the Apple object like it’s have weight and color attributes. In Python 3 Object Oriented Book (Dusty Phillips) there is a great example for this.

As you can see we are stroing oranges in baskets; apples in a barrel. In class level every object may have some behavior. Like we can pick some orange and put it to a basket. For this operation we should update the basket’s size or weight, pop the selected orange from the orange list. For this we can create a pick method. Like in split method in strings, our method should accept some parameter. In this case, our pick method can accept Basket paramet then it can update it.

Adding models and methods to individual objects allows us to create a system of interacting objects. Each object in the system is a member of a certain class. These classes specify what types of data the object can hold and what methods can be invoked on it. The data in each object can be in a different state from other objects of the same class, and each object may react to method calls differently because of the differences in state. Object-oriented analysis and design is all about figuring out what those objects are and how they should interact.

Let’s continoue with an example. Let’s crate a Apple class.

`class Apple: seasion = “winter” vitamin = “C”new_apple = Apple()print(new_apple.seasion)print(new_apple.vitamin)Output:winterC`

new_apple is a a object associated with an Apple class. Notice that, there is no pharantehesis in new_apple.seasion because it’s looking to class and return the value. Class variables are defined within the class construction. Because they are owned by the class itself, class variables are shared by all instances of the class. They therefore will generally have the same value for every instance unless you are using the class variable to initialize a variable.Class variables allow us to define variables upon constructing the class. These variables and their associated values are then accessible to each instance of the class. But what is constructor ? The constructor method is used to initialize data. It is run as soon as an object of a class is instantiated. Also known as the `__init__` method, it will be the first definition of a class and looks like this:

`class Apple: def __init__(self): print(“hello constructor”)`

Constructor method is automatically initialized. You should use this method to carry out any initializing you would like to do with your class objects. For more details check this out:

https://www.digitalocean.com/community/tutorials/how-to-construct-classes-and-define-objects-in-python-3

The key purpose of modeling an object in object-oriented design is to determine what the public interface of that object will be. Process of hiding the implementation, or functional details, of an object is suitably called information hiding. It is also sometimes referred to as encapsulation, but encapsulation is actually a more all-encompassing term. Encapsulated data is not necessarily hidden. Encapsulation is, literally, creating a capsule, so think of creating a time capsule. If you put a bunch of information into a time capsule, lock and bury it, it is both encapsulated and the information is hidden. On the other hand, if the time capsule has not been buried and is unlocked or made of clear plastic, the items inside it are still encapsulated, but there is no information hiding. We will continoue to object oriented design in Basics of Object Oriented Programming later. However this summary should be enough for the moment.

Loops in Action

So let’s explain the for loop with an example.

`import numpy as np import timearr = np.linspace(0,100,10000000)start_time = time.process_time()for i in range(len(arr)): arr[i] = arr[i] * 100end_time = time.process_time()print(“Total Process Time: {}”.format(end_time — start_time))Output:Total Process Time: 9.234375`

time is an another library Python. It comes with great methods and you can check them out:

In this example, we create an array with 10 millions element. len(arr) is the length of our array which is 10 millon. For this array, we wanted to multiply every element with 100 and calculate the total processing time. i is the any element of our array. len() function measure this length and return the value. Then we loop it and change the value of every element. When we reached the 10th millon element our loop terminated then we calculate the end process time. I think it’s time to change my computer, it took 9.2 seconds.

Also we have while loop. It’s condition based and sometimes we wiil use it in our algorithms.

`x, y = 0,1while x < 100: x, y = y, x+yprint(x)print(y)Output:144233`

We exacuted a basic operation which assign the value of y to x and assign the x+y to y. Please note that, we put the print function outside of the while loop. With that, we print the last value of x and y. Let’s put it to inside the loop.

`x,  y = 0,1while x < 100:    x, y = y, x+y    print("X is: {}".format(x))    print("Y is: {}".format(y)))Output:X is: 1Y is: 1X is: 1Y is: 2X is: 2Y is: 3X is: 3Y is: 5X is: 5Y is: 8X is: 8Y is: 13X is: 13Y is: 21X is: 21Y is: 34X is: 34Y is: 55X is: 55Y is: 89X is: 89Y is: 144X is: 144Y is: 233`

List Comprehensions

Now, we can explore the list comprehensions.

`A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]diag = []for i in [0, 1, 2]: diag.append(A[i][i])print(diag)Output:[1, 5, 9]`

We added certain elements of A ( a, A and A) to our empty one dimensional diag list. We could do this by list comprehension.

`A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]arr = [A[i][i] for i in [0,1,2]]print(arr)Output:[1, 5, 9]`

Generally we can use it also for obtaining an element from an array.

`A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]element = [a for a in A]print(element)Output:[2, 5, 8]`

Less elegant way:

`element =[A[i] for i in range(3)]Output:[2, 5, 8]---------A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]element = [a[i] for a in A if a[i]%3 == 0 ]print(element)Output:[3, 6, 9]`

Now, we are good to go.

--

--