+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LeetCode/.DS_Store b/LeetCode/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/LeetCode/.DS_Store differ
diff --git a/LeetCode/.gitignore b/LeetCode/.gitignore
new file mode 100644
index 0000000..496ee2c
--- /dev/null
+++ b/LeetCode/.gitignore
@@ -0,0 +1 @@
+.DS_Store
\ No newline at end of file
diff --git a/LeetCode/MySQL/second-highest-salary.sql b/LeetCode/MySQL/second-highest-salary.sql
new file mode 100644
index 0000000..5da7a47
--- /dev/null
+++ b/LeetCode/MySQL/second-highest-salary.sql
@@ -0,0 +1,21 @@
+# Write a SQL query to get the second highest salary from the Employee table.
+# Alias Salary as SecondHighestSalary.
+#
+# +----+--------+
+# | Id | Salary |
+# +----+--------+
+# | 1 | 100 |
+# | 2 | 200 |
+# | 3 | 300 |
+# +----+--------+
+# For example, given the above Employee table, the second highest salary is 200.
+# If there is no second highest salary, then the query should return null.
+#
+# Write your MySQL query statement below
+
+select max(Salary) as "SecondHighestSalary"
+from Employee
+where Salary < (
+ select max(Salary)
+ from Employee
+ );
diff --git a/LeetCode/README.md b/LeetCode/README.md
new file mode 100644
index 0000000..1d3b2c0
--- /dev/null
+++ b/LeetCode/README.md
@@ -0,0 +1,4 @@
+# LeetCode
+
+## [LeetCode](https://leetcode.com) problems that I have solved.
+
diff --git a/README.md b/README.md
index 9b633bc..ded8abc 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1 @@
-## Short Python programming exercises.
-
-### Books:
- * Think Python by Allen B.Downey
- * Practical Programming
- An Introduction to Computer Science Using Python
- by J.Campbell, P.Gries, J.Montojo, G.Wilson
-
-### Quizzes from:
-http://www.mypythonquiz.com/
\ No newline at end of file
+# udacity-bertelsmann-data-science-challenge-scholarship-2018
diff --git a/Tournament-Planner b/Tournament-Planner
new file mode 160000
index 0000000..5a1bbdb
--- /dev/null
+++ b/Tournament-Planner
@@ -0,0 +1 @@
+Subproject commit 5a1bbdb229fa4c8bd7043d49fad3dce1e89c9803
diff --git a/book_practice.py b/book_practice.py
deleted file mode 100644
index 2093dae..0000000
--- a/book_practice.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Creating a function
-def hello():
- print('Hello')
-
-
-def area(width, height):
- return width * height
-
-
-def print_welcome(name):
- #print Welcome
- print('Welcome', name)
-
-
-# calling function def hello()
-hello()
-hello()
-
-# pass the value to the name argument
-print_welcome('Fred')
-
-w = 4
-h = 5
-
-print('width =', w, 'height =', h, 'area =', area(w, h))
-#
-#
-# Variables in function
-# global variable
-a = 4
-
-
-def print_func():
- #local variable
- a = 17
- print('in print_func a =', a)
-
-
-print_func()
-print('a = ', a)
-
diff --git a/boolean_practice/.gitignore b/boolean_practice/.gitignore
deleted file mode 100644
index 6a04314..0000000
--- a/boolean_practice/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-./
\ No newline at end of file
diff --git a/boolean_practice/boolean_exercises.py b/boolean_practice/boolean_exercises.py
deleted file mode 100644
index 98b18b2..0000000
--- a/boolean_practice/boolean_exercises.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# 3.1. Expression that evaluates to True if both variables are True
-# and that evaluates to False otherwise
-
-x = True
-y = True
-print(x and y)
-
-# 3.2. Expression that evaluates to True if x is False and evaluates
-# to False otherwise
-
-x = False
-y = True
-print(not x)
-
-# 3.3. Expression that evaluates to True if at least one of the variables is True
-# and evaluates to False otherwise
-
-x = True
-y = False
-print(x or y)
-
-# 4. Expression that evaluates to True if at most one of the variables is True
-# and evaluates to False otherwise
-
-full = True
-empty = False
-print(not full or empty)
-
-# 5. True if the light level is less than 0.01 or if the temperature
-# is above freezing, but not if both condition are true
-
-
-def automate_camera(light, temperature):
- return (light < 0.01) != (temperature > 0.0)
-
-
-automate_camera(0.01, -2)
-
-
-# exclusive or
-
-def automate_camera(light, temperature):
- if (light < 0.01) != (temperature > 0.0):
- return True
- else:
- return False
-
-
-automate_camera(0.00, -2)
-
-# 6.
-
-
-# 7. The function returns True if a and b refer to different values and
-# returns False otherwise
-
-def different(a, b):
- return a != b
-
-
-different(2, 2)
-
-
-# 8. You are given two float variables, population and land_area.
-# a. Write an if statement that will print the population if it is less than
-# 10,000,000
-
-
-population = 1.340000
-land_area = 1222.33
-
-if population < 10000000:
- print(f"{population} million")
-
-
-# b. Write an if statement that will print the population if it is between
-# 10,000,000 and 35,000,000
-
-population = 33.000000
-land_area = 1222.33
-
-if 10.000000 < population < 35.000000:
- print(f"{population} millions")
-
-
-# c. Write an if statement that will print "Densely populated" if the land
-# density(number of people per unit of area) is greater than 100.
-# d. Write an if statement that will print "Densely populated!" if the land
-# density print is greater than 100 and that will print "Sparsely populated"
-# otherwise.
-
-density = 90
-
-if density > 100:
- print("Densely populated")
-else:
- print("Sparsely populated")
-
-
-# 9. Function convert_temperature converts temperature t from source units
-# to target units using. Function convert_to_celsius convert all source units
-# to celsius, than function convert_from_celsius converts celsius to target
-# units and returns result.
-
-def convert_to_celsius(t, source):
- if source == "F":
- return round(t - 32 * 5.0/9.0, 2)
- elif source == "K":
- return round(t - 273.15, 2)
- elif source == 'C':
- return t
-
-
-print(convert_to_celsius(32, "K"))
-
-
-def convert_from_celsius(t, target):
- if target == "F":
- return t + 32 * 9.0/5.0
- elif target == "K":
- return t + 273.15
- elif target == "C":
- return t
-
-
-print(convert_from_celsius(32, "F"))
-
-
-def convert_temperatures(t, source, target):
- print('step 1', t, source, target)
- celsius = convert_to_celsius(t, source)
- print('step 2', celsius, t, source, target)
- result = convert_from_celsius(celsius, target)
- print('step 3', result, celsius, t, source, target)
- return result
-
-
-# 10. If ph value is below 3.0 - very acidic, between 3 and 7 - acidic
-
-user_input = input("Enter an acidity level: \n")
-
-if len(user_input) > 0:
- ph = float(user_input)
- if 3.0 < ph < 7.0:
- print(f"{ph} is acidic.")
- elif ph < 3.0:
- print(f"{ph} is VERY acidic! Be careful!")
-else:
- print("No ph value was given!")
-
-
diff --git a/boolean_practice/boolean_expressions.py b/boolean_practice/boolean_expressions.py
deleted file mode 100644
index ae8fef9..0000000
--- a/boolean_practice/boolean_expressions.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# For each of the expressions, what value will the expression give?
-
-
-True and not False
-# True
-
-
-True or True and False
-# True
-
-
-not True or not False
-# True
-
-
-True and not 0
-# True
-
-
-1 + 55 < 55.2
-# False
-
-
-4 != 4.0
-# False
diff --git a/boolean_practice/break_continue.py b/boolean_practice/break_continue.py
deleted file mode 100644
index e0e4a79..0000000
--- a/boolean_practice/break_continue.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Finds which line in a txt file contains string "Earth".
-
-text_line = 1
-file = open("data.txt", "r")
-for line in file:
- line = line.strip()
- if "Earth" in line:
- print(f"Earth is at line {text_line}")
- break
- text_line = text_line + 1
-
-
-# Finds which line in a txt file contains string "Earth".
-# This function uses continue statement to include all lines and skip comment lines.
-
-entry_num = 0
-file = open("data.txt", "r")
-for line in file:
- line = line.strip()
- entry_num = entry_num + 1
-
- if line.startswith("#"):
- continue
-
- if "Earth" in line:
- print(f"Number: {entry_num}")
- break
diff --git a/boolean_practice/check_rectangle.py b/boolean_practice/check_rectangle.py
deleted file mode 100644
index 154dd54..0000000
--- a/boolean_practice/check_rectangle.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Function checks if the given points make rectangle.
-from nose.tools import *
-
-
-def check_rect(points):
- # Check if in the list points four elements
- if len(points) == 4:
- a, b, c, d = points
-
- if len(a) == 2 and len(b) == 2 and len(c) == 2 and len(d) == 2:
- if (a[0] == b[0] and a[1] == d[1] and b[0] == a[0] and b[1] == c[1] and
- c[0] == d[0] and c[1] == b[1] and d[0] == c[0] and d[1] == a[1]):
- return True
-
- return False
-
-
-def calc_area(rectangle):
- if len(rectangle) == 4:
- a, b, c, d = rectangle
- area = abs(a[1] - b[1]) * abs(b[0] - c[0])
- return area
-
- return -1
-
-
-def test_check_rect():
- rectangle = [[1, 2], [1, 4], [5, 4], [5, 2]]
- assert_true(check_rect(rectangle))
-
- rectangle = [[], [1, 4], [5, 4], [5, 2]]
- assert_false(check_rect(rectangle))
-
- rectangle = [[1, 2], [1, 4]]
- assert_false(check_rect(rectangle))
-
- rectangle = [[1, 1], [1, 4], [5, 4], [5, 2]]
- # assert check_rect(rectangle)
- assert_false(check_rect(rectangle))
-
- print('Test passed')
-
-
-def test_calc_area():
- rectangle = [[0, 0], [0, 0], [0, 0], [0, 0]]
- assert_equal(calc_area(rectangle), 0)
-
- rectangle = [[0, 0], [0, 0]]
- assert_equal(calc_area(rectangle), -1)
-
- rectangle = [[1, 2], [1, 4], [5, 4], [5, 2]]
- assert_equal(calc_area(rectangle), 8)
-
- rectangle = [[1, 1], [1, 2], [2, 2], [2, 1]]
- assert_equal(calc_area(rectangle), 1)
-
- print('Test passed')
-
-
-if __name__ == '__main__':
- test_check_rect()
- test_calc_area()
-
- # List of points
- rectangle = [[1, 2], [1, 4], [5, 4], [5, 2]]
-
- print("Yes, this is rectangle!" if check_rect(rectangle) is True else "No!")
diff --git a/boolean_practice/floyd's_triangle.py b/boolean_practice/floyd's_triangle.py
deleted file mode 100644
index 8015068..0000000
--- a/boolean_practice/floyd's_triangle.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Print Floyd's triangle. It's a right-angled triangular array of natural numbers.
-
-# Triangle range
-rows = int(input("Enter the number or rows: \n"))
-n = 10
-
-print(f"Floyd's Triangle with {rows} rows! \n")
-for i in range(1, rows + 1):
- for j in range(1, i + 1):
- print(n, end=" ")
- n += 1
- print()
-
-
-# Print Floyd's Triangle using while loop.
-
-
-# Triangle range
-rows = int(input("Enter the number or rows: \n"))
-n = 1
-
-print(f"Floyd's Triangle with {rows} rows! \n")
-
-i = 1
-while i <= rows:
- j = 1
- while j <= i:
- print(n, end=" ")
- n += 1
- j += 1
- i += 1
- print()
diff --git a/boolean_practice/repetition.py b/boolean_practice/repetition.py
deleted file mode 100644
index d8d35e9..0000000
--- a/boolean_practice/repetition.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Practical Programming, Chapter7: Repetition
-
-
-# 1. Function replaces each value in a list with twice the preceding value and first value with 0.
-
-def double_preceding(values):
- if values == []:
- pass
- else:
- temp = values[0]
- values[0] = 0
- for i in range(1, len(values)):
- values[i] = 2 * temp
- temp = values[i]
- return values
-
-
-lst = [1, 2, 3]
-lst2 = [2, 4, 9, 12]
-double_preceding(lst)
-
-
-# 2. r1 greater r2, r1 > r2 and r1[-1] > r2[-1]
-
-def weight_rats(rat1, rat2):
-
- if rat1[0] > rat2[0]:
- print("Rat 1 weighed more than Rat 2 on Day 1")
- else:
- print("Rat 1 weighed less than Rat 2 on Day 1")
-
- if (rat1[0] > rat2[0]) and (rat1[-1] > rat2[-1]):
- print("Rat 1 remained heavier than Rat 2")
- else:
- print("Rat 2 became heavier than Rat1")
-
-
-r1 = [1.1, 2, 3, 4, 5, 6, 7, 8, 9, 10.1]
-r2 = [1.2, 2.3, 3, 4.5, 5.6, 6.7, 7.9, 8, 9.1, 10]
-weight_rats(r1, r2)
-
-
-# 3.
-for num in range(33, 50):
- print(num)
-
-
-# 4.
-
-for num in range(10, 0, -1):
- print(num)
-
-# 4. Print
-
-num = 1
-while num < 11:
- print(num)
- num += 1
- #num += 2 # only odd numbers
-
-# 5.
-
-
-# 6.
-
-
-# 7. Print a triangle of the character T
-
-for num in range(1, 8):
- print("T" * num)
-
-# 7. Use while loop to print a triangle.
-
-times = 1
-while times < 8:
- print("T" * times)
- times += 1
-
-
-# 8. Print a triangle on the left side of the character T
-
-last_num = 12
-# i loop for columns, j loop for row
-for i in range(0, 7):
- for j in range(0, last_num):
- print(end=" ")
- last_num = last_num - 2
- for j in range(0, i + 1):
- print("T ", end="")
- print()
-
-
-# Double all values in a list using built-in range function.
-
-values = [1, 2, 3]
-for i in range(len(values)):
- values[i] = 2 * values[i]
-
-print(values)
-
-
-# Double all values using enumerate built-in function.
-
-values = [1, 2, 3]
-for pair in enumerate(values):
- i = pair[0]
- v = pair[1]
- values[i] = 2 * v
-
-print(values)
-
-
-# Easier to read solution
-
-values = [1, 2, 3]
-for (i, v) in enumerate(values): # i stands for index in the list values, v stands for value in the list values
- values[i] = 2 * v
-
-print(values)
-
-# Example of ragged list
-
-times = [["8:30", "9:03", "10:20", "11:23", "13:00"],
- ["8:01", "9:35", "10:00", "11:01", "11:02"],
- ["9:15", "10:01", "11:11", "11:29", "13:00"],
- ["10:20", "11:00", "11:02", "11:07", "12:07"],
- ["9:01", "12:23", "13:23", "14:00", "14:01"]]
-for day in times:
- for time in day:
- print(time)
-
-
-# Calculate the growth of a bacteria colony using a simple exponential growth model
-# P(t + 1) = P(t) + rP(t)
-# P(t) population size at time, r is the growth rate
-
-time = 0
-population = 1000
-growth_rate = 0.21 # 21% growth per minute
-while population < 2000:
- population = round(population + growth_rate * population, 2)
- print(population)
- time = time + 1
-print(f"It took {time} minutes for the bacteria to double")
-print(f" and the final population was {population} bacteria")
-
-
diff --git a/boolean_practice/searching_and_sorting/searching.py b/boolean_practice/searching_and_sorting/searching.py
deleted file mode 100644
index 782c686..0000000
--- a/boolean_practice/searching_and_sorting/searching.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Linear Search - lst.index(value, [start, [stop]])
-
-l = [22, 3, 4, 5, 1, 4, 33, 1]
-print(l.index(1, 0, 33))
-
-# Basic Linear Search
-
-
-def linear_search(v, l):
- """Return the index of the first occurrence of v in list l or return len(l)
- if v is not in l"""
- i = 0
- # Keep going until reach the end of L or until find v.
- while i != len(l) and l[i] != v:
- i += 1
- return i
-
-
-print(linear_search(3, [1, 5, 6, 3]))
-
-
-# for loop Version of Linear Search
-
-def linear_search(v, l):
- """Return the index of the first occurrence of v in list l or return len(l)
- if v is not in l"""
- i = 0
- for value in l:
- if value == v:
- return i
- i += 1
- return len(l)
-
-
-print(linear_search(52, [12, 52, 26, 13]))
-
-
-# Sentinel Search
-# Using Basic Linear search checks i!=len(l) every time through the loop even though it can
-# never be False except when v isn't in l list.
-# Add v to the end of l list before searching so that it guaranteed to be there. Then remove it
-# before the function exists so the list look unchanged at the end.
-
-def linear_search(v, l):
- """Return the index of the first occurrence of v in list l or return len(l)
- if v is not in l"""
-
- # Add the sentinel.
- l.append(v)
- i = 0
-
- # Keep going until find v.
- while l[i] != v:
- i += 1
-
- # Remove the sentinel.
- l.pop()
- return i
-
-
-print(linear_search(2, [11, 2, 26, 13]))
-
-
-# Binary Search - each step divides the data into two equal parts: values that came before the one being looked for
-# and values that come after.
-
-def binary_search(v, l):
- """Return the index of the leftmost occurrence of v in list L or -1 if v is not in l list"""
-
- # Mark the left and right indices of the unknown section.
- i = 0
- j = len(l) - 1
-
- while i != j +1:
- m = (i + j)/2
- if l[m] < v:
- i = m +1
- else:
- j = m -1
- if 0 <= i < len(l) and l[i] == v:
- return i
- else:
- return -1
-
diff --git a/boolean_practice/storing_conditionals.py b/boolean_practice/storing_conditionals.py
deleted file mode 100644
index e59ebf6..0000000
--- a/boolean_practice/storing_conditionals.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Calculate risk of heart disease based on age and body mass
-# index (BMI).
-
-
-def heart_risk(age, bmi):
-
- young = age <= 45
- slim = bmi < 22.0
- if young and slim:
- risk = 'low'
- elif young and not slim:
- risk = 'medium'
- elif not young and slim:
- risk = 'medium'
- elif not young and not slim:
- risk = 'high'
- return risk
-
-
-heart_risk(45, 15)
-heart_risk(42, 20)
-heart_risk(18, 23)
-
-
-#
-def calculate_heart_risk(age, bmi):
-
- table = [['medium', 'high'],
- ['low', 'medium']]
- young = age <= 45
- heavy = bmi >= 22.0
- risk = table[young][heavy]
- return risk
-
-
-calculate_heart_risk(23, 32)
diff --git a/char_returns.py b/char_returns.py
deleted file mode 100644
index f1279d7..0000000
--- a/char_returns.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Function takes a string as an input from user, asks to enter a character and returns
-# an index of the character in the string
-
-user_string = input("Enter any string: \n").lower()
-char = input("Enter a character to find: ").lower()
-
-# One line solution
-# index = user_string.index(char)
-
-index = 0
-
-if char not in user_string:
- print("Check your spelling! Your letter not in a string!")
-
-elif char == "":
- print("Empty string!")
-
-else:
- for ch in user_string:
- if ch == char:
- break # stops after first char detection
- index += 1
-
- print(f"Index number: {index}")
-
diff --git a/count_unique_letter.py b/count_unique_letter.py
deleted file mode 100644
index ffc426d..0000000
--- a/count_unique_letter.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# 1
-
-def check_duplicates(text):
- """ Checks if text contains duplicates.
-
- Parameters:
- - text (str) - string to check
-
- Returns:
- - True/False - True if string contains duplicates and False otherwise
- """
-
- # get rid off any spaces: (' ', '')
- text = text.replace(' ', '')
-
- return len(set(text)) != len(text)
-
-
-print(check_duplicates('llll p mmkj'))
-print(check_duplicates('l c n'))
-
-
-# 2
-
-def count_unique_letters(text):
- """ Counts quantity of all letters in a string.
-
- Parameters:
- - text (str) - letters to count
-
- Returns:
- - Dictionary with key and value
- """
-
- text = text.replace(' ', '')
- letters = {}
-
- for letter in text:
- if letter not in letters:
- letters[letter] = 1
- else:
- letters[letter] += 1
-
- return letters
-
-
-print(count_unique_letters('b d a'))
-print(count_unique_letters('b dd a cccc'))
diff --git a/do_four.py b/do_four.py
deleted file mode 100644
index df8c56a..0000000
--- a/do_four.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Runs the function twice.
-def do_twice(func, arg):
-
- func(arg)
- func(arg)
-
-
-# Prints the argument twice.
-def print_twice(arg):
-
- print(arg)
- print(arg)
-
-
-# Runs the function four times.
-def do_four(func, arg):
- do_twice(func, arg)
- do_twice(func, arg)
-
-
-do_twice(print_twice, 'spam')
-print('')
-
-do_four(print_twice, 'spam')
diff --git a/do_twice.py b/do_twice.py
deleted file mode 100644
index bb6db95..0000000
--- a/do_twice.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# do_tvice takes a function object as an argument
-# and calls it twice
-
-
-def do_twice(f, k): # f=print_spam, k=2
- f(k) # print_spam()
- f(k)
-
-
-def print_spam(v):
- print('spam')
-
-
-do_twice(print_spam, 1)
-
-
-# Runs a function twice
-# func: functional object
-# arg: argument passed to the function
-def do_twice(func, arg):
-
- func(arg)
- func(arg)
\ No newline at end of file
diff --git a/download_html_pages.py b/download_html_pages.py
deleted file mode 100644
index fb5251c..0000000
--- a/download_html_pages.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from url_input import fetch_save_url
-
-
-def download_urls(file_name):
-
- with open(file_name) as file:
-
- count = 1
- for url in file:
-
- url = url.strip("\n")
- print("Fetching", url)
-
- f_name = f"output{count}.html"
- fetch_save_url(url, f_name)
-
- print("Saved to", f_name)
-
- count += 1
-
-download_urls("url.txt")
\ No newline at end of file
diff --git a/file_processing/numbers.csv b/file_processing/numbers.csv
deleted file mode 100644
index 2645cc5..0000000
--- a/file_processing/numbers.csv
+++ /dev/null
@@ -1,8 +0,0 @@
-name; age
-John; 21
-Anna; 13
-Kolt; 33
-Micha; 98
-Lolo; 54
-Kalo; 44
-
diff --git a/file_processing/numbers.py b/file_processing/numbers.py
deleted file mode 100644
index 41cea21..0000000
--- a/file_processing/numbers.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import csv
-# Find sum, average, min and max ages in csv file
-
-count = 0
-with open("numbers.csv", "r") as file:
- header_line = next(file) # skip header
- total = 0
- min_value = []
- rows = []
-
- for row in csv.reader(file,delimiter=";"):
- if row == []: # check if there an empty string
- continue
-
- rows.append(row)
- total += int(row[1])
- count = count + 1
-
- min_value = min(rows, key=lambda item: int(item[1]))
- max_value = max(rows, key=lambda item: int(item[1]))
- average_age = total / count
- print(f"Sum of all user ages: {total}")
- print(f"Average age: {round(average_age)}")
- print(min_value[0])
- print(max_value[0])
diff --git a/file_processing/old_young_num.py b/file_processing/old_young_num.py
deleted file mode 100644
index 901827a..0000000
--- a/file_processing/old_young_num.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import csv
-# Find sum, average, min and max ages in csv file
-
-
-def elements(min_value):
-
- count = 0
- with open("numbers.csv", "r") as file:
- #header_line = next(file) # skip header
- total = 0
- #min_value = []
- rows = []
-
- for row in csv.reader(file,delimiter=";"):
- if row == []: # check if there an empty string
- continue
-
- rows.append(row)
- total += int(row[1])
- count = count + 1
-
-# for min_value in total:
-# total += min_value.sort()
-# total = min_value[0]
-# print(min_value)
-
- min_value = sorted(rows, key=min)
-
- print(min_value)
diff --git a/file_processing/online_file.py b/file_processing/online_file.py
deleted file mode 100644
index 0720d97..0000000
--- a/file_processing/online_file.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import urllib.request
-
-url = "https://github.com/irsol"
-web_page = urllib.request.urlopen(url)
-for line in web_page:
- line = line.strip()
- print(line)
-web_page.close()
diff --git a/find_elements.py b/find_elements.py
deleted file mode 100644
index b3ce37e..0000000
--- a/find_elements.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# This function find elements that bigger then 4 in my_list[]
-
-'''
-def find_elements(lst, value):
-
- new_list = []
- for element in lst:
- if element > value:
- new_list.append(element)
- return new_list
-
-my_list = [1, 3, 5, 6, 9, 3, 5, 4, 7]
-
-print(find_elements(my_list, 2))
-'''
-
-# Find elements <= 22
-
-
-def find_elements(lst, value):
- new_list = []
- for element in lst:
- if element <= value:
- new_list.append(element)
- return new_list
-
-my_list = [22, 22.4, 21.9, 2, 1, 0.5]
-
-print(find_elements(my_list, 22))
-
-
-# Here use extend, extend takes 2 lists
-# and appends all of the elements
-
-
-def find_elements(lst, value):
- new_list = []
-
- for element in lst:
- if element > value:
- new_list.append(element)
- new_list.sort()
- return new_list
-
-
-my_list = [2, 3, 4, 6, 122, 3, 0.3]
-my_second_list = [3, 4, 9, 0, 333]
-my_list.extend(my_second_list)
-print(find_elements(my_list, 7))
diff --git a/first_n_fibonacci.py b/first_n_fibonacci.py
deleted file mode 100644
index 38088e1..0000000
--- a/first_n_fibonacci.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Fibonacci series program using for loop displays sequence up to n term
-# n is provided by the user
-
-# Starts from 0
-num = int(input("Enter the number of digits of the series: "))
-
-# Initialized first two numbers
-n1 = 0
-n2 = 1
-
-print("\nFibonacci series: ")
-
-# Check if the number of term is valid
-if num <= 0:
- print("Enter a positive digit!")
-
-elif num == 1:
- print(n1)
-
-elif num >= 2:
- print("{}, {}".format(n1, n2), end=" , ")
-
- for n in range(2, num):
- next_n = n1 + n2
- print(next_n, end=", ")
-
- # Update values
- n1 = n2
- n2 = next_n
-
diff --git a/first_n_fibonacci_function.py b/first_n_fibonacci_function.py
deleted file mode 100644
index b3d000b..0000000
--- a/first_n_fibonacci_function.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# def fibo(num):
-# n1 = 0
-# n2 = 1
-# result = [n1, n2]
-# print("Fibonacci sequence: ")
-#
-# for n in range(2, num):
-# n3 = n1 + n2
-# result.append(n3)
-# n1 = n2
-# n2 = n3
-# print(result)
-#
-# fibo(5)
-
-
-def fibo(num):
- result = [0, 1]
- print("Fibonacci sequence: ")
-
- for n in range(2, num):
- n3 = 0 + 1
- result.append(n3)
-
- print(result)
-
-fibo(5)
diff --git a/flask-exercises/.idea/misc.xml b/flask-exercises/.idea/misc.xml
new file mode 100644
index 0000000..ba24381
--- /dev/null
+++ b/flask-exercises/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/flask-exercises/factors.py b/flask-exercises/factors.py
new file mode 100644
index 0000000..62ea386
--- /dev/null
+++ b/flask-exercises/factors.py
@@ -0,0 +1,17 @@
+from flask import Flask
+
+app = Flask(__name__)
+
+
+def find_factors(num):
+ return [x for x in range(1, num + 1) if num % x == 0]
+
+
+# convert integers to numbers
+@app.route("/factors/")
+def find_factors_route(num):
+ return f"The factor of {num} are {find_factors(num)}"
+
+
+if __name__ == '__main__':
+ app.run(host='0.0.0.0', port=5000)
diff --git a/boolean_practice/practice_file.py b/flask-exercises/hello.py
similarity index 100%
rename from boolean_practice/practice_file.py
rename to flask-exercises/hello.py
diff --git a/freeCodeCamp b/freeCodeCamp
new file mode 160000
index 0000000..7d3bc85
--- /dev/null
+++ b/freeCodeCamp
@@ -0,0 +1 @@
+Subproject commit 7d3bc8545ac0c39c5f79f418fe0d66162f911639
diff --git a/get_content_disposition_name.py b/get_content_disposition_name.py
deleted file mode 100644
index 6892306..0000000
--- a/get_content_disposition_name.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import requests
-import re
-# name extracted from the string with regular expression or re module
-
-
-def get_filename(content_disposition):
-
- # Get file name from content-disposition
- if not content_disposition:
- return None
- f_name = re.findall("filename=(.+)", content_disposition)
- return f_name[0]
-
-
-url = "https://github.com/irsol"
-r = requests.get(url, allow_redirects=True)
-filename = get_filename(r.headers.get("content-disposition"))
-
-with open(filename, "w") as file:
- file.write(r.content)
- print("ok")
diff --git a/get_from_url_filename.py b/get_from_url_filename.py
deleted file mode 100644
index 9f7c2f8..0000000
--- a/get_from_url_filename.py
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-url = "https://docs.python.org/3/library/urllib.request.html#request-objects"
-
-if url.find("/"):
- # fetches the last string after a backslash
- print(url.split("/")[-1])
diff --git a/irsol.github.io b/irsol.github.io
new file mode 160000
index 0000000..83c2e89
--- /dev/null
+++ b/irsol.github.io
@@ -0,0 +1 @@
+Subproject commit 83c2e897127db9a54f39767c09173fc7058e35c8
diff --git a/my_print_grid.py b/my_print_grid.py
deleted file mode 100644
index 2baeb57..0000000
--- a/my_print_grid.py
+++ /dev/null
@@ -1,15 +0,0 @@
-def print_grid(rows, columns):
-
- cell_height = 3
- cell_width = 3
- v_line = ("|")
- h_line = ("-")
-
- for i in range(rows):
- print(h_line)
-
- for j in range(columns):
- print(v_line)
-
-
-print_grid(2, 4)
diff --git a/mypolygon.py b/mypolygon.py
deleted file mode 100644
index ae87ec6..0000000
--- a/mypolygon.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import turtle
-bob = turtle.Turtle()
-bob.fd(100)
-bob.lt(90)
-bob.fd(100)
-
-bob.lt(90)
-bob.fd(100)
-bob.lt(90)
-bob.fd(100)
-
-for i in range(4):
- bob.fd(100)
- bob.lt(90)
-
-for i in range(4):
- print('Hello!')
-
-print(bob)
-turtle.mainloop()
diff --git a/mypythonquiz1.py b/mypythonquiz1.py
deleted file mode 100644
index 3fd7370..0000000
--- a/mypythonquiz1.py
+++ /dev/null
@@ -1,212 +0,0 @@
- # 1: what does the following code do?
-
-
-def a(b, c, d):
- pass
-# The 'def' statement defines a function.
-# The 'pass' statement is a null operation.
-
-
-# 2: what is the output of the following code?
-
-
-print(type([1, 2]))
-# Lists are formed by placing a comma-separated
-# list of expressions in square brackets
-
-
-# 3: what gets printed?
-
-
-def f():
- pass
-
-
-print(type(f()))
-# The argument to the type() call is a return value of
-# a function call, which returns None
-
-
-# 4: what should the below code print?
-print(type(1J))
-# or j means complex number
-# you can put ‘j’ or ‘J’ after a number to make it imaginary,
-# so you can write complex literals
-
-# 5: what is the output of the following code?
-print(type(lambda: None))
-#
-# 'lambda arguments: expression' yields a function object
-
-
-# 6: what is the output of the below program?
-a = [1, 2, 3, None, (), [], ]
-print(len(a))
-# 6
-# The trailing comma in the list is ignored, the rest are legitimate values
-
-# 7: what gets printed?
-print(type(1/2))
-#
-# division of an integer by another integer yields a float
-
-# 8: What gets printed?
-d = lambda p: p * 2
-t = lambda p: p * 3
-x = 2
-x = d(x)
-x = t(x)
-x = d(x)
-print(x)
-
-# 10: What gets printed?
-nums = set([1, 1, 2, 3, 3, 3, 4])
-print(len(nums))
-# nums is a set, so only unique values are retained.
-
-# 11: What gets printed?
-
-x = True
-y = False
-z = False
-
-if x or y and z:
- print("yes")
-else:
- print("no")
-# yes
-# AND is higher precedence than OR in python and is evaluated first
-
-# 12: What gets printed?
-
-x = True
-y = False
-z = False
-
-if not x or y:
- print(1)
-elif not x or not y and z:
- print(2)
-elif not x or y or not y and x:
- print(3)
-else:
- print(4)
-# 3
-# NOT has first precedence, then AND, then OR
-
-
-# 14: What gets printed?
-
-counter = 1
-
-
-def do_lots_of_stuff():
- global counter
- for num in (1, 2, 3):
- counter += 1
-
-
-do_lots_of_stuff()
-print(counter)
-
-# 4
-# the counter variable being referenced in the function is the global
-# variable defined outside of the function. Changes to the variable in
-# the function affect the original variable.
-
-# 16: What gets printed?
-print("\x48\x49!")
-# HI!
-# \x is an escape sequence that means the following 2 digits ares
-# a hexadicmal number encoding a character.
-
-# 17: What gets printed?
-print(0xA + 0xa)
-# 20
-# 0xA and 0xa are both hexadecimal integer literals representing the decimal
-# value 10. Their sum is 20.
-
-
-# 18: What gets printed?
-class Parent:
- def __init__(self, param):
- self.v1 = param
-
-
-class Child(Parent):
- def __init__(self, param):
- self.v2 = param
-
-
-obj = Child(11)
-print(obj.v1 + " " + obj.v2)
-# AttributeError: child instance has no attribute 'v1'. self.v1 was never
-# created as a variable since the parent __init__ was not explicitly called.
-
-
-# 19: What following python function will return?
-def my_cool_func(a, b, c):
- if a > (b + c):
- return a
- elif b == c:
- return b
- else:
- return c
-
-
-my_cool_func(5, 3, 2)
-my_cool_func(7, 4, 4)
-my_cool_func(3, 5, 9)
-# 2 c
-# 4 b
-# 9 c
-
-
-# 20
-for i in range(2):
- print(i)
-
-for i in range(4, 6):
- print(i)
-# 0 , 1, 4, 5
-# If only 1 number is supplied to range it is the end of the range. (0 , 1)
-# The default beginning of a range is 0. The range will include the beginning
-# of the range and all numbers up to but not including the end of range(4,5)
-
-# 21
-lst = [3, 4, 7, 1, 1]
-result = 0
-for i in range(len(lst)):
- result += lst[i]
-print(result)
-# 16
-
-# 22 Tuples
-lst = [("a", 1), ("b", 2), ("c", 3)]
-for letter, number in lst:
- print('{"letter=number"}'.format(*lst))
-
-# 23 Dictionary
-d = {"cat": "no",
- "dog": "yes"}
-print("fox" in d)
-
-# 24
-a = 10
-b = 7
-if a < 7:
- print("1")
-elif a == 7:
- print("2")
-elif b < 10:
- print("3")
-elif a > b:
- print("4")
-else:
- print("end")
-
-# 25 String
-g = "I'm cat"
-print(g.replace("cat", "fox"))
-
-
diff --git a/non_repeat.py b/non_repeat.py
deleted file mode 100644
index 8dc1128..0000000
--- a/non_repeat.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# 1
-def count_non_repetitive(s):
- s = s.replace(' ', '').lower()
- letters_count = {}
-
- for letter in s:
- if letter in letters_count:
- letters_count += 1
- else:
- letters_count == 1
-
- return letters_count
-
-
-print(count_non_repetitive('Ky lle fi'))
diff --git a/print_grid.py b/print_grid.py
deleted file mode 100644
index e0cfccb..0000000
--- a/print_grid.py
+++ /dev/null
@@ -1,38 +0,0 @@
-def print_grid():
-
- print('+', '-' * 4, '+', '-' * 4, '+')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('+', '-' * 4, '+', '-' * 4, '+')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('|', ' ' * 4, '|', ' ' * 4, '|')
- print('+', '-' * 4, '+', '-' * 4, '+')
-
-#print_grid()
-
-
-def grid_print(rows, columns):
- #h_line = ("+ " + "- " * 4) * rows
- #v_line = ("| " + " " * 8) * v_lines
-
- #print(h_line + "\n" + v_line)
-
- cell_width = 4
- cell_height = 4
- h_line = ("+" + "-" * cell_width) * columns + "+"
- v_line = ("|" + " " * cell_width) * (columns + 1)
-
- for i in range(rows):
- print(h_line)
-
- for j in range(cell_height):
- print(v_line)
-
- print(h_line)
-
-grid_print(2, 5)
-
diff --git a/python-exercises b/python-exercises
new file mode 160000
index 0000000..9266878
--- /dev/null
+++ b/python-exercises
@@ -0,0 +1 @@
+Subproject commit 9266878189601f148331ead16b403d9ade8cc28e
diff --git a/python-projects b/python-projects
new file mode 160000
index 0000000..1438ab4
--- /dev/null
+++ b/python-projects
@@ -0,0 +1 @@
+Subproject commit 1438ab4a05c691e2cf77696978a0b08f82a15a94
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/action_provision b/restaurant-menu-server/.vagrant/machines/default/virtualbox/action_provision
new file mode 100644
index 0000000..5c496ed
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/action_provision
@@ -0,0 +1 @@
+1.5:1f5db447-8ea0-4c09-b774-c51bb57ab36a
\ No newline at end of file
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/action_set_name b/restaurant-menu-server/.vagrant/machines/default/virtualbox/action_set_name
new file mode 100644
index 0000000..5cbbd6b
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/action_set_name
@@ -0,0 +1 @@
+1516045229
\ No newline at end of file
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/creator_uid b/restaurant-menu-server/.vagrant/machines/default/virtualbox/creator_uid
new file mode 100644
index 0000000..ec52cb8
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/creator_uid
@@ -0,0 +1 @@
+501
\ No newline at end of file
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/id b/restaurant-menu-server/.vagrant/machines/default/virtualbox/id
new file mode 100644
index 0000000..71fdc3f
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/id
@@ -0,0 +1 @@
+1f5db447-8ea0-4c09-b774-c51bb57ab36a
\ No newline at end of file
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/index_uuid b/restaurant-menu-server/.vagrant/machines/default/virtualbox/index_uuid
new file mode 100644
index 0000000..29852b6
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/index_uuid
@@ -0,0 +1 @@
+f3ff04f3a0c644c69134084ef9c8b180
\ No newline at end of file
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/private_key b/restaurant-menu-server/.vagrant/machines/default/virtualbox/private_key
new file mode 100644
index 0000000..6a461bb
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/private_key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAxedN0WVdA9RvZKXGNJ+N/NA3d2yA2sJCtIBsj/MrMYMgyToG
+Jst1PIie3kXARI7qYxNrf2Xi4FdHY3CwYrPe6NKe4hqhGmIl99jKisJUqAc0Io3v
+pkc2qTbtxdjQJWlowtZKhMsT5hm5VUmNujg64SBWlPEXvMJEt1OL3Pa57PzThOrP
+vXHBwBBDeYSns8dfM7AwCJMHbW8wpqXFyjo977qsV0Sg+fBzjFXa5HzxR4kfGRVH
+h4HWPUy34P6JSdvooNtTq+IgutRpldEiVE6CZS9kDQo+B8SB2WA4N1JLWjg0JPfE
+SbwCR2GtCxTkbaJztMpKKjQsMS03vqAPB7xG9QIDAQABAoIBAQCnEnmYoEkhNZOA
+1Y552IVG/AUHdftmMv+bYJvF/tTlLL1eA/UzhSoJG5F7Nkl11206jSeAWuRo3mXv
+JjBSc2VpCn6FhVOicV96WHPNJvfPDp3N2iOKLa6QtkWPdFVscAu4CK7KYqL+65KR
+1NGod1YFvoY5oTuX6C2Y0xhNR6F41g/4rSEXQOJ4zTq8rrJwvD3hrBDX05zZr6dJ
+Vrc/XNcXVmcIcSoWj1Bvluc4c3rqa2uY59CnQ9FzCFoRrqaacNutiLOBXEBHUpf9
+9qFUmQNlTHckLhUFwO8MwEVnwGEpFA0/kcWC7kyFxCE6Mvld+2NoYnm6ek1zvpap
+kudojm4hAoGBAOkc3wACjiidFwkWF03BjzxpXPIT/edzsxgRWhaH3hiPOe3KuulK
+2NiHUT7mpds4yF0allYsTdrk/j6bN07d26tz2iXXLR3eywHmGdBXMzbkXf8aLBWg
+pEHMFfT+aOKSQNxGPounNH5uYwUkcQuMImhVny9e/BY6clPlSUun1IatAoGBANlV
+eQZCBGHLSbjdO1sMzsVUSPxyQow1suSaZQYv3YLdiqiJ9IVbYfUYNGqwWRS+d7vc
+npND3xFaENPG+JMAXVy1DTRazxc/iq7Vb/vg5gwKvcOwW5YpWJN111JZFaO5CdOl
+HLmqcBYUhe6RcQVuHx2PyjDdcLF6bd3UFaku+HJpAoGBANLHUjP2G4hJklya5vNd
+wyACvRH+VaSEDzoB5o1cyMs4Jk8G8j6jeLNAl4vijbFNBI56zdiZMsRsLh95xWbA
+YDIFDQkOKTNLEhBjeI/TaPGHSB60EYx0tlDwMiJWL4w+ZftGYKNxyptPQKWTr8ub
+KDliwg7ZOeL3cgy906pe1GH5AoGBANWo1sMVMdOmlAJ+1DSN4dVTKDGubsgCnq1p
+L/omImHeRMuuXEqibSoUMqvUVK81FOcGXIswhWM8pSBeEtAJ4r8aazHWOJOFb2S0
+BlScY+zgvnBct51nZmIJzrZxR/neFtAQGa5Z5bl/UbAZIgCRo1tfmgnyGTERyGL1
+dpoNyEhJAoGAEb9UBC8yc/AOl52j9u/Dch6egEkyDYPxV+O+AjiCznGuPp2Z4PwP
+14MRllx+r9flcX30Z+UJgwih5iMxOi36HHYtEfYYzeNKhE/CNDgm4j8ALBmNnUGG
+g2U9ZBjke5xPr1XaTlqdJPPnArBHcNspTDT3g3lv6bVHS9IzkoszlaU=
+-----END RSA PRIVATE KEY-----
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/synced_folders b/restaurant-menu-server/.vagrant/machines/default/virtualbox/synced_folders
new file mode 100644
index 0000000..611b9c4
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/synced_folders
@@ -0,0 +1 @@
+{"virtualbox":{"/vagrant":{"guestpath":"/vagrant","hostpath":"/Users/irynasoltyska/Documents/udacity/full_stack/restaurant-menu-server","disabled":false,"__vagrantfile":true}}}
\ No newline at end of file
diff --git a/restaurant-menu-server/.vagrant/machines/default/virtualbox/vagrant_cwd b/restaurant-menu-server/.vagrant/machines/default/virtualbox/vagrant_cwd
new file mode 100644
index 0000000..c837038
--- /dev/null
+++ b/restaurant-menu-server/.vagrant/machines/default/virtualbox/vagrant_cwd
@@ -0,0 +1 @@
+/Users/irynasoltyska/Documents/udacity/full_stack/restaurant-menu-server
\ No newline at end of file
diff --git a/restaurant-menu-server/README.md b/restaurant-menu-server/README.md
new file mode 100644
index 0000000..b168dfa
--- /dev/null
+++ b/restaurant-menu-server/README.md
@@ -0,0 +1,75 @@
+# CRUD Review
+
+## Udacity small "restaurant-menu" project.
+
+## Operations with SQLAlchemy on an SQLite database.
+
+### To connect to restaurantMenu.db, and create a session to interface with the database:
+
+`from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+from database_setup import Base, Restaurant, MenuItem
+engine = create_engine('sqlite:///restaurantMenu.db')
+Base.metadata.bind=engine
+DBSession = sessionmaker(bind = engine)
+session = DBSession()`
+
+
+### CREATE
+#### Create a new Restaurant and called it Pizza Pasta:
+
+`myFirstRestaurant = Restaurant(name = "Pizza Pasta")
+session.add(myFirstRestaurant)
+sesssion.commit()`
+
+#### Create a cheese pizza menu item and added it to the Pizza Pasta Menu:
+
+`cheesepizza = menuItem(name="Cheese Pizza", description = "Made with all natural ingredients and fresh mozzarella", course="Entree", price="$8.99", restaurant=myFirstRestaurant)
+session.add(cheesepizza)
+session.commit()`
+
+### READ
+#### Read out information in our database using the query method in SQLAlchemy:
+
+`firstResult = session.query(Restaurant).first()
+firstResult.name
+items = session.query(MenuItem).all()
+for item in items:
+ print item.name`
+
+### UPDATE
+#### In order to update and existing entry in database, execute the following commands:
+
+* Find Entry
+* Reset value(s)
+* Add to session
+* Execute session.commit()
+
+#### Find the veggie burger that belonged to the Urban Burger restaurant by
+executing the following query:
+
+`veggieBurgers = session.query(MenuItem).filter_by(name= 'Veggie Burger')
+for veggieBurger in veggieBurgers:
+ print veggieBurger.id
+ print veggieBurger.price
+ print veggieBurger.restaurant.name
+ print "\n"`
+
+#### Then update the price of the veggie burger to $2.99:
+
+`UrbanVeggieBurger = session.query(MenuItem).filter_by(id=8).one()
+UrbanVeggieBurger.price = '$2.99'
+session.add(UrbanVeggieBurger)
+session.commit()`
+
+### DELETE
+#### To delete an item from database, follow the following steps:
+
+* Find the entry
+* Session.delete(Entry)
+* Session.commit()
+#### Deleted spinach Ice Cream from Menu Items database with the following operations:
+
+`spinach = session.query(MenuItem).filter_by(name = 'Spinach Ice Cream').one()
+session.delete(spinach)
+session.commit()`
diff --git a/restaurant-menu-server/Vagrantfile b/restaurant-menu-server/Vagrantfile
new file mode 100644
index 0000000..14fdc93
--- /dev/null
+++ b/restaurant-menu-server/Vagrantfile
@@ -0,0 +1,43 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Vagrant.configure("2") do |config|
+ config.vm.box = "bento/ubuntu-16.04-i386"
+ config.vm.box_version = "= 2.3.5"
+ config.vm.network "forwarded_port", guest: 8000, host: 8000, host_ip: "127.0.0.1"
+ config.vm.network "forwarded_port", guest: 8080, host: 8080, host_ip: "127.0.0.1"
+ config.vm.network "forwarded_port", guest: 5000, host: 5000, host_ip: "127.0.0.1"
+
+ # Work around disconnected virtual network cable.
+ config.vm.provider "virtualbox" do |vb|
+ vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
+ end
+
+ config.vm.provision "shell", inline: <<-SHELL
+ apt-get -qqy update
+
+ # Work around https://github.com/chef/bento/issues/661
+ # apt-get -qqy upgrade
+ DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade
+
+ apt-get -qqy install make zip unzip postgresql
+
+ apt-get -qqy install python3 python3-pip
+ pip3 install --upgrade pip
+ pip3 install flask packaging oauth2client redis passlib flask-httpauth
+ pip3 install sqlalchemy flask-sqlalchemy psycopg2 bleach requests
+
+ apt-get -qqy install python python-pip
+ pip2 install --upgrade pip
+ pip2 install flask packaging oauth2client redis passlib flask-httpauth
+ pip2 install sqlalchemy flask-sqlalchemy psycopg2 bleach requests
+
+ su postgres -c 'createuser -dRS vagrant'
+ su vagrant -c 'createdb'
+
+ vagrantTip="[35m[1mThe shared directory is located at /vagrant\\nTo access your shared files: cd /vagrant[m"
+ echo -e $vagrantTip > /etc/motd
+
+ echo "Done installing your virtual machine!"
+ SHELL
+end
diff --git a/restaurant-menu-server/database_setup.py b/restaurant-menu-server/database_setup.py
new file mode 100644
index 0000000..0ff43ed
--- /dev/null
+++ b/restaurant-menu-server/database_setup.py
@@ -0,0 +1,31 @@
+import os
+import sys
+from sqlalchemy import Column, ForeignKey, Integer, String
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship
+from sqlalchemy import create_engine
+
+Base = declarative_base()
+
+
+class Restaurant(Base):
+ __tablename__ = 'restaurant'
+
+ id = Column(Integer, primary_key=True)
+ name = Column(String(250), nullable=False)
+
+
+class MenuItem(Base):
+ __tablename__ = 'menu_item'
+
+ name = Column(String(80), nullable=False)
+ id = Column(Integer, primary_key=True)
+ description = Column(String(250))
+ price = Column(String(8))
+ course = Column(String(250))
+ restaurant_id = Column(Integer, ForeignKey('restaurant.id'))
+ restaurant = relationship(Restaurant)
+
+
+engine = create_engine('sqlite:///restaurantmenu.db')
+Base.metadata.create_all(engine)
diff --git a/restaurant-menu-server/database_setup.pyc b/restaurant-menu-server/database_setup.pyc
new file mode 100644
index 0000000..d6102b0
Binary files /dev/null and b/restaurant-menu-server/database_setup.pyc differ
diff --git a/restaurant-menu-server/lotsofmenus.py b/restaurant-menu-server/lotsofmenus.py
new file mode 100644
index 0000000..268bb2c
--- /dev/null
+++ b/restaurant-menu-server/lotsofmenus.py
@@ -0,0 +1,345 @@
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+
+from database_setup import Restaurant, Base, MenuItem
+
+engine = create_engine('sqlite:///restaurantmenu.db')
+# Bind the engine to the metadata of the Base class so that the
+# declaratives can be accessed through a DBSession instance
+Base.metadata.bind = engine
+
+DBSession = sessionmaker(bind=engine)
+# A DBSession() instance establishes all conversations with the database
+# and represents a "staging zone" for all the objects loaded into the
+# database session object. Any change made against the objects in the
+# session won't be persisted into the database until you call
+# session.commit(). If you're not happy about the changes, you can
+# revert all of them back to the last commit by calling
+# session.rollback()
+session = DBSession()
+
+
+
+#Menu for UrbanBurger
+restaurant1 = Restaurant(name = "Urban Burger")
+
+session.add(restaurant1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Veggie Burger", description = "Juicy grilled veggie patty with tomato mayo and lettuce", price = "$7.50", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+
+menuItem1 = MenuItem(name = "French Fries", description = "with garlic and parmesan", price = "$2.99", course = "Appetizer", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Chicken Burger", description = "Juicy grilled chicken patty with tomato mayo and lettuce", price = "$5.50", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem3 = MenuItem(name = "Chocolate Cake", description = "fresh baked and served with ice cream", price = "$3.99", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem3)
+session.commit()
+
+menuItem4 = MenuItem(name = "Sirloin Burger", description = "Made with grade A beef", price = "$7.99", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem4)
+session.commit()
+
+menuItem5 = MenuItem(name = "Root Beer", description = "16oz of refreshing goodness", price = "$1.99", course = "Beverage", restaurant = restaurant1)
+
+session.add(menuItem5)
+session.commit()
+
+menuItem6 = MenuItem(name = "Iced Tea", description = "with Lemon", price = "$.99", course = "Beverage", restaurant = restaurant1)
+
+session.add(menuItem6)
+session.commit()
+
+menuItem7 = MenuItem(name = "Grilled Cheese Sandwich", description = "On texas toast with American Cheese", price = "$3.49", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem7)
+session.commit()
+
+menuItem8 = MenuItem(name = "Veggie Burger", description = "Made with freshest of ingredients and home grown spices", price = "$5.99", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem8)
+session.commit()
+
+
+
+
+#Menu for Super Stir Fry
+restaurant2 = Restaurant(name = "Super Stir Fry")
+
+session.add(restaurant2)
+session.commit()
+
+
+menuItem1 = MenuItem(name = "Chicken Stir Fry", description = "With your choice of noodles vegetables and sauces", price = "$7.99", course = "Entree", restaurant = restaurant2)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Peking Duck", description = " A famous duck dish from Beijing[1] that has been prepared since the imperial era. The meat is prized for its thin, crisp skin, with authentic versions of the dish serving mostly the skin and little meat, sliced in front of the diners by the cook", price = "$25", course = "Entree", restaurant = restaurant2)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem3 = MenuItem(name = "Spicy Tuna Roll", description = "Seared rare ahi, avocado, edamame, cucumber with wasabi soy sauce ", price = "15", course = "Entree", restaurant = restaurant2)
+
+session.add(menuItem3)
+session.commit()
+
+menuItem4 = MenuItem(name = "Nepali Momo ", description = "Steamed dumplings made with vegetables, spices and meat. ", price = "12", course = "Entree", restaurant = restaurant2)
+
+session.add(menuItem4)
+session.commit()
+
+menuItem5 = MenuItem(name = "Beef Noodle Soup", description = "A Chinese noodle soup made of stewed or red braised beef, beef broth, vegetables and Chinese noodles.", price = "14", course = "Entree", restaurant = restaurant2)
+
+session.add(menuItem5)
+session.commit()
+
+menuItem6 = MenuItem(name = "Ramen", description = "a Japanese noodle soup dish. It consists of Chinese-style wheat noodles served in a meat- or (occasionally) fish-based broth, often flavored with soy sauce or miso, and uses toppings such as sliced pork, dried seaweed, kamaboko, and green onions.", price = "12", course = "Entree", restaurant = restaurant2)
+
+session.add(menuItem6)
+session.commit()
+
+
+
+
+#Menu for Panda Garden
+restaurant1 = Restaurant(name = "Panda Garden")
+
+session.add(restaurant1)
+session.commit()
+
+
+menuItem1 = MenuItem(name = "Pho", description = "a Vietnamese noodle soup consisting of broth, linguine-shaped rice noodles called banh pho, a few herbs, and meat.", price = "$8.99", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Chinese Dumplings", description = "a common Chinese dumpling which generally consists of minced meat and finely chopped vegetables wrapped into a piece of dough skin. The skin can be either thin and elastic or thicker.", price = "$6.99", course = "Appetizer", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem3 = MenuItem(name = "Gyoza", description = "The most prominent differences between Japanese-style gyoza and Chinese-style jiaozi are the rich garlic flavor, which is less noticeable in the Chinese version, the light seasoning of Japanese gyoza with salt and soy sauce, and the fact that gyoza wrappers are much thinner", price = "$9.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem3)
+session.commit()
+
+menuItem4 = MenuItem(name = "Stinky Tofu", description = "Taiwanese dish, deep fried fermented tofu served with pickled cabbage.", price = "$6.99", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem4)
+session.commit()
+
+menuItem2 = MenuItem(name = "Veggie Burger", description = "Juicy grilled veggie patty with tomato mayo and lettuce", price = "$9.50", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+
+#Menu for Thyme for that
+restaurant1 = Restaurant(name = "Thyme for That Vegetarian Cuisine ")
+
+session.add(restaurant1)
+session.commit()
+
+
+menuItem1 = MenuItem(name = "Tres Leches Cake", description = "Rich, luscious sponge cake soaked in sweet milk and topped with vanilla bean whipped cream and strawberries.", price = "$2.99", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Mushroom risotto", description = "Portabello mushrooms in a creamy risotto", price = "$5.99", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem3 = MenuItem(name = "Honey Boba Shaved Snow", description = "Milk snow layered with honey boba, jasmine tea jelly, grass jelly, caramel, cream, and freshly made mochi", price = "$4.50", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem3)
+session.commit()
+
+menuItem4 = MenuItem(name = "Cauliflower Manchurian", description = "Golden fried cauliflower florets in a midly spiced soya,garlic sauce cooked with fresh cilantro, celery, chilies,ginger & green onions", price = "$6.95", course = "Appetizer", restaurant = restaurant1)
+
+session.add(menuItem4)
+session.commit()
+
+menuItem5 = MenuItem(name = "Aloo Gobi Burrito", description = "Vegan goodness. Burrito filled with rice, garbanzo beans, curry sauce, potatoes (aloo), fried cauliflower (gobi) and chutney. Nom Nom", price = "$7.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem5)
+session.commit()
+
+menuItem2 = MenuItem(name = "Veggie Burger", description = "Juicy grilled veggie patty with tomato mayo and lettuce", price = "$6.80", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+
+
+#Menu for Tony's Bistro
+restaurant1 = Restaurant(name = "Tony\'s Bistro ")
+
+session.add(restaurant1)
+session.commit()
+
+
+menuItem1 = MenuItem(name = "Shellfish Tower", description = "Lobster, shrimp, sea snails, crawfish, stacked into a delicious tower", price = "$13.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Chicken and Rice", description = "Chicken... and rice", price = "$4.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem3 = MenuItem(name = "Mom's Spaghetti", description = "Spaghetti with some incredible tomato sauce made by mom", price = "$6.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem3)
+session.commit()
+
+menuItem4 = MenuItem(name = "Choc Full O\' Mint (Smitten\'s Fresh Mint Chip ice cream)", description = "Milk, cream, salt, ..., Liquid nitrogen magic", price = "$3.95", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem4)
+session.commit()
+
+menuItem5 = MenuItem(name = "Tonkatsu Ramen", description = "Noodles in a delicious pork-based broth with a soft-boiled egg", price = "$7.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem5)
+session.commit()
+
+
+
+
+#Menu for Andala's
+restaurant1 = Restaurant(name = "Andala\'s")
+
+session.add(restaurant1)
+session.commit()
+
+
+menuItem1 = MenuItem(name = "Lamb Curry", description = "Slow cook that thang in a pool of tomatoes, onions and alllll those tasty Indian spices. Mmmm.", price = "$9.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Chicken Marsala", description = "Chicken cooked in Marsala wine sauce with mushrooms", price = "$7.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem3 = MenuItem(name = "Potstickers", description = "Delicious chicken and veggies encapsulated in fried dough.", price = "$6.50", course = "Appetizer", restaurant = restaurant1)
+
+session.add(menuItem3)
+session.commit()
+
+menuItem4 = MenuItem(name = "Nigiri Sampler", description = "Maguro, Sake, Hamachi, Unagi, Uni, TORO!", price = "$6.75", course = "Appetizer", restaurant = restaurant1)
+
+session.add(menuItem4)
+session.commit()
+
+menuItem2 = MenuItem(name = "Veggie Burger", description = "Juicy grilled veggie patty with tomato mayo and lettuce", price = "$7.00", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+
+
+
+#Menu for Auntie Ann's
+restaurant1 = Restaurant(name = "Auntie Ann\'s Diner' ")
+
+session.add(restaurant1)
+session.commit()
+
+menuItem9 = MenuItem(name = "Chicken Fried Steak", description = "Fresh battered sirloin steak fried and smothered with cream gravy", price = "$8.99", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem9)
+session.commit()
+
+
+
+menuItem1 = MenuItem(name = "Boysenberry Sorbet", description = "An unsettlingly huge amount of ripe berries turned into frozen (and seedless) awesomeness", price = "$2.99", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Broiled salmon", description = "Salmon fillet marinated with fresh herbs and broiled hot & fast", price = "$10.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem3 = MenuItem(name = "Morels on toast (seasonal)", description = "Wild morel mushrooms fried in butter, served on herbed toast slices", price = "$7.50", course = "Appetizer", restaurant = restaurant1)
+
+session.add(menuItem3)
+session.commit()
+
+menuItem4 = MenuItem(name = "Tandoori Chicken", description = "Chicken marinated in yoghurt and seasoned with a spicy mix(chilli, tamarind among others) and slow cooked in a cylindrical clay or metal oven which gets its heat from burning charcoal.", price = "$8.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem4)
+session.commit()
+
+menuItem2 = MenuItem(name = "Veggie Burger", description = "Juicy grilled veggie patty with tomato mayo and lettuce", price = "$9.50", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+menuItem10 = MenuItem(name = "Spinach Ice Cream", description = "vanilla ice cream made with organic spinach leaves", price = "$1.99", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem10)
+session.commit()
+
+
+
+#Menu for Cocina Y Amor
+restaurant1 = Restaurant(name = "Cocina Y Amor ")
+
+session.add(restaurant1)
+session.commit()
+
+
+menuItem1 = MenuItem(name = "Super Burrito Al Pastor", description = "Marinated Pork, Rice, Beans, Avocado, Cilantro, Salsa, Tortilla", price = "$5.95", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+menuItem2 = MenuItem(name = "Cachapa", description = "Golden brown, corn-based Venezuelan pancake; usually stuffed with queso telita or queso de mano, and possibly lechon. ", price = "$7.99", course = "Entree", restaurant = restaurant1)
+
+session.add(menuItem2)
+session.commit()
+
+
+restaurant1 = Restaurant(name = "State Bird Provisions")
+session.add(restaurant1)
+session.commit()
+
+menuItem1 = MenuItem(name = "Chantrelle Toast", description = "Crispy Toast with Sesame Seeds slathered with buttery chantrelle mushrooms", price = "$5.95", course = "Appetizer", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit
+
+menuItem1 = MenuItem(name = "Guanciale Chawanmushi", description = "Japanese egg custard served hot with spicey Italian Pork Jowl (guanciale)", price = "$6.95", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+
+
+menuItem1 = MenuItem(name = "Lemon Curd Ice Cream Sandwich", description = "Lemon Curd Ice Cream Sandwich on a chocolate macaron with cardamom meringue and cashews", price = "$4.25", course = "Dessert", restaurant = restaurant1)
+
+session.add(menuItem1)
+session.commit()
+
+
+print "added menu items!"
diff --git a/restaurant-menu-server/restaurantmenu.db b/restaurant-menu-server/restaurantmenu.db
new file mode 100644
index 0000000..880ce8c
Binary files /dev/null and b/restaurant-menu-server/restaurantmenu.db differ
diff --git a/right_justify.py b/right_justify.py
deleted file mode 100644
index ceda019..0000000
--- a/right_justify.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#Function takes a string named s as a parameter.
-#Prints the string so the last letter of the string in column 70.
-
-
-def right_justify(s):
- max_length = 70
- space = ' '
- num_length = max_length - len(s)
- s = space * num_length + s
- print(s)
-
-right_justify('monty')
-right_justify('cat')
-right_justify('dddddfffffffggggggg')
\ No newline at end of file
diff --git a/sequence_of_numbers.py b/sequence_of_numbers.py
deleted file mode 100644
index cc460fe..0000000
--- a/sequence_of_numbers.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# The filter will return all items from the list values which return True
-# when passed to the function checkit. checkit will check if the value is in
-# the set. Since all the numbers in the set come from the values list,
-# all of the original values in the list will return True.
-
-
-values = [1, 2, 1, 3]
-nums = set(values)
-
-
-def checkit(num):
- if num in nums:
- return True
- else:
- return False
-
-
-for i in filter(checkit, values):
- print(i)
-
diff --git a/turtle_exercises.py b/turtle_exercises.py
deleted file mode 100644
index 09b3525..0000000
--- a/turtle_exercises.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import turtle
-bob = turtle.Turtle()
-
-
-def square(t, length):
- for i in range(4):
- t.fd(length)
- t.lt(length)
-
-
-#square(bob, 90)
-#turtle.mainloop()
-
-
-# n is a number of polygon sides
-def polygon(t, length, n):
- for i in range(n):
- t.fd(length)
- t.lt(360/n)
-
-
-
-#def circle(t, r):
-# c = length * n
-
-
-#circle(polygon, 10)
-
-
-polygon(bob, 90, 9)
-turtle.mainloop()
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/.gitignore b/udacity-bertelsmann-data-science-challenge-scholarship-2018/.gitignore
new file mode 100644
index 0000000..8904509
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+.idea
+sql_subqueries_temporary_table_lesson31/subquery_mani_u_solutions.py
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/README.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/README.md
new file mode 100644
index 0000000..023e747
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/README.md
@@ -0,0 +1,19 @@
+## About
+
+##### This repository for my study notes, exercises, quizzes during Udacity Bertelsmann Scholarship Challenge 2018.
+
+Notes are sorted by lessons.
+
+## Lessons:
+
+- [Lessons 1-5](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/blob/master/intro_to_research_methods_lessons_1_5/terminology_intro_to_research_methods.md)
+- [Lesson 6](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/visualizing_data_lesson_6)
+- [Lesson 13](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/variability_lesson_13)
+- [Lesson 24](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/data_types_and_operators_lesson_24)
+- [Lesson 25](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/control_flow_lesson_25)
+- [Lesson 26](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/functions_lesson_26)
+- [Lesson 28](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/basic_sql_lesson28)
+- [Lesson 29](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/sql_joins_lesson_29)
+- [Lesson 30](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/aggregations_lesson_30)
+- [Lesson 31](https://github.com/irsol/udacity-bertelsmann-data-science-challenge-scholarship-2018/tree/master/sql_subqueries_temporary_table_lesson31)
+- [Lesson 32]()
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/aggregations.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/aggregations.md
new file mode 100644
index 0000000..fdd7224
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/aggregations.md
@@ -0,0 +1,173 @@
+# Aggregations.
+
+## NULLs
+
+`NULL`s are a datatype that specifies where no data exists in SQL. Mean no data. It's different from a zero or space (space is a value).
+
+NULLs are different than a zero (zero is a value) - they are cells where data does not exist. When identifying NULLs in a WHERE clause, we write IS NULL or IS NOT NULL. We don't use =, because NULL isn't considered a value in SQL. Rather, it is a property of the data.
+
+## NULLs - Expert Tip
+There are two common ways in which you are likely to encounter NULLs:
+
++ **NULL**s frequently occur when performing a LEFT or RIGHT JOIN. When some rows in the left table of a left join are not matched with rows in the right table, those rows will contain some NULL values in the result set.
+
++ **NULL**s can also occur from simply missing data in our database.
+
+## NULLs and COUNT
+
+`count()` function is returning of all the rows that contain some non-null data.
+
+`count()` can also be used to count the number of non-null records in an individual column or any column in a table.
+
+Notice that COUNT does not consider rows that have NULL values. Therefore, this can be useful for quickly identifying which rows have missing data.
+
+## SUM
+
+**SUM** works similarly to **COUNT** except you'll want to specify column names rather than using star.
+
+Can't use `SUM(*)` the way you canuse `COUNT(*)`. Unlike COUNT, you can only use SUM on numeric columns. However, SUM will ignore NULL values and treat NULLs as zero!
+
+Aggregation Reminder
+An important thing to remember: **aggregators only aggregate vertically - the values of a column**. If you want to perform a calculation across rows, you would do this with [simple arithmetic](https://community.modeanalytics.com/sql/tutorial/sql-operators/#arithmetic-in-sql).
+
+## MIN and MAX
+
+The syntax for MIN and MAx is similar to SUM and COUNT. MIN and MAX ignore NULL values.
+
+#####Expert Tip:
+functionally, MIN and MAX are similar to COUNT in that they can be used on non-numerical columns. Depending on the column type, MIN will return the lowest number, earliest date, or non-numerical value as early in the alphabet as possible. As you might suspect, MAX does the opposite—it returns the highest number, the latest date, or the non-numerical value closest alphabetically to “Z.”
+
+
+## AVG
+
+`AVG` is a SQL aggregate function that calculates the average of a selected group of values. AVG has similar syntax to all of the other aggregation functions. AVG can be only used on numerical columns, it ignores nulls completely!!
+
+If you want to count NULLs as zero, you will need to use SUM and COUNT. However, this is probably not a good idea if the NULL values truly just represent unknown values for a cell.
+
+#####MEDIAN - Expert Tip
+One quick note that a median might be a more appropriate measure of center for this data, but finding the median happens to be a pretty difficult thing to get using SQL alone — so difficult that finding a median is occasionally asked as an interview question.
+
+## MEDIAN
+
+"Calculates a percentile based on a continuous distribution of the column value in SQL Server. The result is interpolated and might not be equal to any of the specific values in the column."
+
+```
+PERCENTILE_CONT ( numeric_literal )
+
+ WITHIN GROUP ( ORDER BY order_by_expression [ ASC | DESC ] )
+
+ OVER ( [ ] )
+```
+
+[Median: PERCENTILE_CONT](https://docs.microsoft.com/en-us/sql/t-sql/functions/percentile-cont-transact-sql?view=sql-server-2017)
+
+
+## GROUP BY
+
+`GROUP BY` allows to take the sum of data limited to each account rather than across the enrire dataset.
+
++ **GROUP BY** can be used to aggregate data within subsets of the data. For example, grouping for different accounts, different regions, or different sales representatives.
+
++ The GROUP BY always goes between WHERE and ORDER BY
+
++ ORDER BY works like SORT in spreadsheet software
+
++ Any column in the SELECT statement that is not within an aggregator must be in the GROUP BY clause.
+
+Example:
+
+```
+SELECT account_id,
+ SUM(standard_qty) as standard_sum,
+ SUM(gloss_qty) as gloss_sum,
+ SUM(poster_qty) as poster_sum
+FROM demo.orders
+GROUP BY account_id
+ORDER BY account_id;
+```
+
+##### GROUP BY - Expert Tip
+it is worth noting that SQL evaluates the aggregations before the LIMIT clause. If you don’t group by any columns, you’ll get a 1-row result—no problem there. If you group by a column with enough unique values that it exceeds the LIMIT number, the aggregates will be calculated, and then some rows will simply be omitted from the results.
+
+This is actually a nice way to do things because you know you’re going to get the correct aggregates. If SQL cuts the table down to 100 rows, then performed the aggregations, your results would be substantially different. The above query’s results exceed 100 rows, so it’s a perfect example.
+
+You can GROUP BY multiple columns at once. This is often useful to aggregate across a number of different segments.
+
+Example:
+```
+SELECT account_id,
+ channel,
+ COUNT(id) as events
+FROM demo.web_events_full
+GROUP BY account_id, channel
+ORDER BY account_id, events DESC;
+```
+The order in the `ORDER BY` determines which column is ordered on first.
+You can order `DESC` for any column in `ORDER BY`.
+
+#####GROUP BY - Expert Tips
++ The order of column names in your `GROUP BY` clause doesn’t matter—the results will be the same regardless. If we run the same query and reverse the order in the GROUP BY clause, you can see we get the same results.
+
+
++ As with ORDER BY, you can substitute numbers for column names in the `GROUP BY` clause. It’s generally recommended to do this only when you’re grouping many columns, or if something else is causing the text in the GROUP BY clause to be excessively long.
+
+
++ A reminder here that any column that is not within an aggregation must show up in your GROUP BY statement. If you forget, you will likely get an error.
+
+
+## DISTINCT
+
+If you want to group by some columns but you don't want to include any aggregations you can use `DISTINCT`.
+
+`DISTINCT` is always used in SELECT statements, and it provides the unique rows for all columns written in the SELECT statement. Therefore, you only use DISTINCT once in any particular SELECT statement.
+
+```
+SELECT DISTINCT column1, DISTINCT column2, DISTINCT column3
+FROM table1;
+```
+
+**DISTINCT - Expert Tip**
+It’s worth noting that using `DISTINCT`, particularly in aggregations, can slow your queries down quite a bit.
+
+
+## HAVING
+**HAVING - Expert Tip**
+
+`HAVING` is the “clean” way to filter a query that has been aggregated, but this is also commonly done using a subquery. Essentially, any time you want to perform a WHERE on an element of your query that was created by an aggregate, you need to use HAVING instead.
+
+**WHERE** subsets the returned data based on a logical condition.
+**WHERE** appears after the FROM, JOIN, ON clauses, but before GROUP BY.
+**HAVING** appears after he GROUP BY clause but before the ORDER BY.
+**HAVING** is leki **WHERE**, but it works on logical statement involving aggregations.
+
+**Query clause order**
+1. `SELECT`
+2. `FROM`s
+3. `WHERE`
+4. `GROUP BY`
+5. `HAVING`
+6. `ORDER BY`
+
+
+## DATE Functions
+
+GROUPing BY a date column is not usually very useful in SQL, as these columns tend to have transaction data down to a second.
+There are a number of built in SQL functions that are aimed at helping us improve our experience in working with dates.
+
+`DATE_TRUNC` allows you to truncate your date to a particular part of your date-time column. Common trunctions are day, month, and year. Here is a great blog post by Mode Analytics on the power of this function.
+
+`DATE_PART` can be useful for pulling a specific portion of a date, but notice pulling month or day of the week (dow) means that you are no longer keeping the years in order. Rather you are grouping for certain components regardless of which year they belonged in.
+
+You can reference the columns in your select statement in GROUP BY and ORDER BY clauses with numbers that follow the order they appear in the select statement. For example
+
+```
+SELECT standard_qty, COUNT(*)
+
+FROM orders
+
+GROUP BY 1 (this 1 refers to standard_qty since it is the first of the columns included in the select statement)
+
+ORDER BY 1 (this 1 refers to standard_qty since it is the first of the columns included in the select statement)
+```
+
+`DATE_PART('dow')` pulls day of the week andr returns a value from 0 to 6 (0 is Sunday, 6 is Saturday).
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/aggregations.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/aggregations.sql
new file mode 100644
index 0000000..aa36e7c
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/aggregations.sql
@@ -0,0 +1,426 @@
+# Aggregation Questions
+#
+#
+# 1.Find the total amount of poster_qty paper ordered in the orders table.
+
+SELECT SUM(poster_qty) as total_poster_sales
+FROM orders;
+
+# 2.Find the total amount of standard_qty paper ordered in the orders table.
+
+SELECT COUNT(standard_qty) as total_standard_sales
+FROM orders;
+
+# 3.Find the total dollar amount of sales using the total_amt_usd in the orders table.
+
+SELECT COUNT(total_amt_usd) as total_dollar_sales
+FROM orders;
+
+# 4.Find the total amount spent on standard_amt_usd and gloss_amt_usd paper for each
+# order in the orders table. This should give a dollar amount for each order in the table.
+
+SELECT standard_amt_usd + gloss_amt_usd as total
+FROM orders;
+
+# 5. Find the standard_amt_usd per unit of standard_qty paper. Your solution should use
+# both an aggregation and a mathematical operator.
+
+SELECT SUM(standard_amt_usd)/SUM(standard_qty) as unit_price_standard_qty
+FROM orders;
+
+
+# MAX, MIN, AVG
+#
+#
+# 1.When was the earliest order ever placed? You only need to return the date.
+
+SELECT MIN(occurred_at) as earliest_order
+FROM orders;
+
+# 2.Try performing the same query as in question 1 without using an aggregation function.
+
+SELECT occurred_at as earliest_order
+FROM orders
+ORDER BY occurred_at ASC
+LIMIT 1;
+
+# 3.When did the most recent (latest) web_event occur?
+
+SELECT MAX(occurred_at) as latest_web_event
+FROM web_events;
+
+# 4.Try to perform the result of the previous query without using an aggregation function.
+
+SELECT occurred_at as latest_web_event
+FROM web_events
+ORDER BY occurred_at DESC
+LIMIT 1;
+
+# 5.Find the mean (AVERAGE) amount spent per order on each paper type, as well as the mean
+# amount of each paper type purchased per order. Your final answer should have 6 values -
+# one for each paper type for the average number of sales, as well as the average amount.
+
+SELECT AVG(standard_qty) as avg_standard,
+ AVG(gloss_qty) as avg_gloss,
+ AVG(poster_qty) as avg_poster,
+ AVG(standard_amt_usd) as avg_standart_usd,
+ AVG(gloss_amt_usd) as avg_gloss_usd,
+ AVG(poster_amt_usd) as avg_poster_usd
+FROM orders;
+
+# 6.What is the MEDIAN total_usd
+# spent on all orders?
+
+/*
+PERCENTILE_CONT interpolates the appropriate value, whether or not it exists in the data set,
+while PERCENTILE_DISC always returns an actual value from the set.
+*/
+
+SELECT PERCENTILE_CONT(0.5)
+WITHIN GROUP (ORDER BY total_amt_usd) as median_total_usd
+FROM orders;
+
+
+# Udycity solution:
+
+/*Since there are 6912 orders - we want the average of the 3457 and 3456 order amounts when ordered.
+This is the average of 2483.16 and 2482.55. This gives the median of 2482.855. This obviously isn't
+an ideal way to compute. If we obtain new orders, we would have to change the limit. SQL didn't even
+calculate the median for us. The above used a SUBQUERY, but you could use any method to find the two
+necessary values, and then you just need the average of them.
+*/
+
+SELECT *
+FROM (SELECT total_amt_usd
+ FROM orders
+ ORDER BY total_amt_usd
+ LIMIT 3457) AS Table1
+ORDER BY total_amt_usd DESC
+LIMIT 2;
+
+
+
+# GROUP BY
+
+# 1.
+# Which account (by name) placed the earliest order? Your solution should have the account name
+# and the date of the order.
+
+SELECT accounts.name as account_name,
+ orders.occurred_at as order_date
+FROM accounts
+JOIN orders
+ON accounts.id = orders.account_id
+ORDER BY accounts.name
+LIMIT 1;
+
+# or
+
+SELECT accounts.name as account_name,
+ MIN(orders.occurred_at) as order_date
+FROM orders, accounts
+GROUP BY accounts.name
+ORDER BY accounts.name
+LIMIT 1;
+
+# 2.
+# Find the total sales in usd for each account. You should include two columns - the total sales
+# for each company's orders in usd and the company name.
+
+
+SELECT accounts.name as account_name,
+ SUM(orders.total_amt_usd) as total_sales_per_oder
+FROM orders
+JOIN accounts
+ON accounts.id = orders.account_id
+GROUP BY accounts.name;
+
+# 3.
+# Via what channel did the most recent (latest) web_event occur, which account was associated
+# with this web_event? Your query should return only three values - the date, channel, and account name.
+
+SELECT occurred_at as latest_web_events,
+ accounts.name as account_name,
+ web_events.channel as channel_name
+FROM web_events
+JOIN accounts
+ON web_events.account_id = accounts.id
+ORDER BY web_events.occurred_at DESC
+LIMIT 1;
+
+# 4.
+# Find the total number of times each type of channel from the web_events was used. Your final
+# table should have two columns - the channel and the number of times the channel was used.
+
+SELECT COUNT(occurred_at) as use_web_events,
+ channel as channel_name
+FROM web_events
+GROUP BY web_events.channel;
+
+# 5.Who was the primary contact associated with the earliest web_event?
+
+SELECT primary_poc
+FROM web_events
+JOIN accounts
+ON web_events.account_id = accounts.id
+ORDER BY web_events.occurred_at
+LIMIT 1;
+
+# 6.
+# What was the smallest order placed by each account in terms of
+# total usd. Provide only two columns - the account name and the total usd. Order from smallest
+# dollar amounts to largest.
+
+SELECT MIN(total_amt_usd) as smallest_order,
+ accounts.name as account_name
+FROM accounts
+JOIN orders
+ON orders.account_id = accounts.id
+GROUP BY accounts.name
+ORDER BY smallest_order;
+
+# 7.
+# Find the number of sales reps in each region. Your final table should have two columns -
+# the region and the number of sales_reps. Order from fewest reps to most reps.
+
+SELECT region.name as region_name,
+COUNT(*) as number_sales_reps
+FROM region
+JOIN sales_reps
+ON sales_reps.region_id = region.id
+GROUP BY region.name
+ORDER BY number_sales_reps;
+
+
+# GROUP BY Part 2
+#
+
+# 1.
+# For each account, determine the average amount of each type of paper they purchased
+# across their orders. Your result should have four columns - one for the account name and one
+# for the average quantity purchased for each of the paper types for each account.
+
+SELECT accounts.name as account_name,
+ AVG(standard_qty) as avg_standard,
+ AVG(gloss_qty) as avg_gloss,
+ AVG(poster_qty) as avg_poster
+FROM accounts
+JOIN orders on accounts.id = orders.account_id
+GROUP BY account_name;
+
+# 2.
+# For each account, determine the average amount spent per order on each paper type.
+# Your result should have four columns - one for the account name and one for the average
+# amount spent on each paper type.
+
+SELECT accounts.name as account_name,
+ AVG(standard_amt_usd) as avg_standard,
+ AVG(gloss_amt_usd) as avg_gloss,
+ AVG(poster_amt_usd) as avg_poster
+FROM accounts
+JOIN orders on accounts.id = orders.account_id
+GROUP BY account_name;
+
+
+# 3.
+# Determine the number of times a particular channel was used in the web_events table for each sales rep.
+# Your final table should have three columns - the name of the sales rep, the channel, and the number of occurrences.
+# Order your table with the highest number of occurrences first.
+
+SELECT sales_reps.name as name, web_events.channel as channel, COUNT(channel) as num_events
+
+FROM sales_reps
+JOIN accounts on sales_reps.id = accounts.sales_rep_id
+JOIN web_events on accounts.id = web_events.account_id
+GROUP BY sales_reps.name, web_events.channel
+ORDER BY num_events DESC;
+
+# or
+
+SELECT s.name, w.channel, COUNT(*) num_events
+FROM accounts a
+JOIN web_events w
+ON a.id = w.account_id
+JOIN sales_reps s
+ON s.id = a.sales_rep_id
+GROUP BY s.name, w.channel
+ORDER BY num_events DESC;
+
+# 4.
+# Determine the number of times a particular channel was used in the web_events table for each region. Your final
+# table should have three columns - the region name, the channel, and the number of occurrences. Order your table
+# with the highest number of occurrences first.
+
+SELECT COUNT(web_events.channel) as num_occurences, region.name as name, web_events.channel as channel
+FROM web_events
+JOIN accounts on web_events.account_id = accounts.id
+JOIN sales_reps on accounts.sales_rep_id = sales_reps.id
+JOIN region on sales_reps.region_id = region.id
+GROUP BY region.name, web_events.channel
+ORDER BY num_occurences DESC;
+
+
+# DISTINCT
+#
+# 1.Use DISTINCT to test if there are any accounts associated with more than one region.
+
+SELECT DISTINCT id, name
+FROM accounts;
+
+# Solution with JOIN
+
+SELECT a.name AS account_name,r.name AS region_name, COUNT(r.name)
+FROM accounts a
+JOIN sales_reps s
+ON a.sales_rep_id=s.id
+JOIN region r
+ON s.region_id=r.id
+GROUP BY a.name, r.name
+Order by a.name;
+
+# Solution with COUNT and DISTINCT to count unique and all data
+SELECT COUNT(region.id) as all_records, COUNT(DISTINCT region_id) as unique_records
+FROM sales_reps, region;
+
+# Udacity solution
+# If each account was associated with more than one region, the first query should
+# have returned more rows than the second query.
+
+SELECT a.id as "account id", r.id as "region id",
+a.name as "account name", r.name as "region name"
+FROM accounts a
+JOIN sales_reps s
+ON s.id = a.sales_rep_id
+JOIN region r
+ON r.id = s.region_id;
+
+#and
+SELECT DISTINCT id, name
+FROM accounts;
+
+# 2. Have many sales reps worked on more than one account?
+
+SELECT DISTINCT id, name
+FROM sales_reps;
+
+# or
+
+SELECT sales_reps.name, COUNT(*) num_accounts,
+sales_reps.id
+FROM accounts
+JOIN sales_reps
+ON sales_reps.id = accounts.sales_rep_id
+GROUP BY sales_reps.id, sales_reps.name
+ORDER BY num_accounts;
+
+
+# HAVING
+# 1.How many of the sales reps have more than 5 accounts that they manage?
+#
+
+SELECT s.id, s.name, COUNT(*) num_accounts
+FROM sales_reps s
+JOIN accounts a on s.id = a.sales_rep_id
+GROUP BY s.id, s.name
+HAVING COUNT(*) > 5
+ORDER BY num_accounts;
+
+# Using SUBQUERY
+
+SELECT COUNT(*) num_reps_above5
+FROM(SELECT s.id, s.name, COUNT(*) num_accounts
+ FROM accounts a
+ JOIN sales_reps s
+ ON s.id = a.sales_rep_id
+ GROUP BY s.id, s.name
+ HAVING COUNT(*) > 5
+ ORDER BY num_accounts) AS Table1;
+
+
+# 2. How many accounts have more than 20 orders?
+SELECT a.id, a.name, COUNT(*) num_orders
+FROM accounts a
+JOIN orders o
+ON a.id = o.account_id
+GROUP BY a.id, a.name
+HAVING COUNT(*) > 20
+ORDER BY num_orders;
+
+# 3. Which account has the most orders?
+
+SELECT a.id, a.name, COUNT(*) num_orders
+FROM accounts a
+JOIN orders o
+ON a.id = o.account_id
+GROUP BY a.id, a.name
+ORDER BY num_orders DESC
+LIMIT 1;
+
+# 4. How many accounts spent more than 30,000 usd total across all orders?
+
+SELECT a.id, a.name, SUM(o.total_amt_usd) total_spent
+FROM accounts a
+JOIN orders o
+ON a.id = o.account_id
+GROUP BY a.id, a.name
+HAVING SUM(o.total_amt_usd) > 30000
+ORDER BY total_spent;
+
+# 5. How many accounts spent less than 1,000 usd total across all orders?
+
+SELECT a.id, a.name, SUM(o.total_amt_usd) total_spent
+FROM accounts a
+JOIN orders o
+ON a.id = o.account_id
+GROUP BY a.id, a.name
+HAVING SUM(o.total_amt_usd) < 1000
+ORDER BY total_spent;
+
+# 6. Which account has spent the most with us?
+
+SELECT a.id, a.name, SUM(o.total_amt_usd) total_spent
+FROM accounts a
+JOIN orders o
+ON a.id = o.account_id
+GROUP BY a.id, a.name
+ORDER BY total_spent DESC
+LIMIT 1;
+
+# 7. Which account has spent the least with us?
+
+SELECT a.id, a.name, SUM(o.total_amt_usd) total_spent
+FROM accounts a
+JOIN orders o
+ON a.id = o.account_id
+GROUP BY a.id, a.name
+ORDER BY total_spent
+LIMIT 1;
+
+# 8. Which accounts used facebook as a channel to contact customers more than 6 times?
+
+SELECT a.id, a.name, w.channel, COUNT(*) count_channel
+FROM accounts a
+JOIN web_events w ON a.id = w.account_id
+GROUP BY a.id, a.name, w.channel
+HAVING COUNT(*) > 6
+ORDER BY count_channel;
+
+# 9. Which account used facebook most as a channel?
+
+SELECT a.id, a.name, w.channel, COUNT(*) channel_use
+FROM accounts a
+JOIN web_events w ON a.id = w.account_id
+WHERE w.channel = 'facebook'
+GROUP BY a.id, a.name, w.channel
+ORDER BY channel_use DESC
+LIMIT 1;
+
+
+# 10. Which channel was most frequently used by most accounts?
+
+SELECT a.id, a.name, w.channel, COUNT(*) channel_use
+FROM accounts a
+JOIN web_events w ON a.id = w.account_id
+GROUP BY a.id, a.name, w.channel
+ORDER BY channel_use DESC
+LIMIT 10;
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/cas_statement.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/cas_statement.sql
new file mode 100644
index 0000000..9c83350
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/cas_statement.sql
@@ -0,0 +1,108 @@
+# 1. Quiz: CASE
+
+/*
+We would like to understand 3 different levels of customers based on the amount associated with their purchases.
+The top branch includes anyone with a Lifetime Value (total sales of all orders) greater than 200,000 usd.
+The second branch is between 200,000 and 100,000 usd. The lowest branch is anyone under 100,000 usd.
+Provide a table that includes the level associated with each account. You should provide the account name,
+the total sales of all orders for the customer, and the level. Order with the top spending customers listed first.
+*/
+
+SELECT a.name,
+ SUM(o.total_amt_usd),
+ CASE WHEN SUM(o.total_amt_usd) > 200000 THEN 'Over 200,000'
+ WHEN SUM(o.total_amt_usd) > 100000 THEN 'Over 100,000 '
+ ELSE 'Less 100,000' END as total_level
+FROM orders o
+JOIN accounts a on a.id = o.account_id
+GROUP BY a.name
+ORDER BY 2 DESC;
+
+
+# 2. Quiz: CASE
+
+/*
+We would now like to perform a similar calculation to the first, but we want to obtain the total amount spent
+by customers only in 2016 and 2017. Keep the same levels as in the previous question. Order with the top spending
+customers listed first.
+*/
+
+SELECT DATE_TRUNC('year', o.occurred_at) as year,
+ a.name,
+ SUM(o.total_amt_usd),
+ CASE WHEN SUM(o.total_amt_usd) > 200000 THEN 'Over 200,000'
+ WHEN SUM(o.total_amt_usd) > 100000 THEN 'Over 100,000 '
+ ELSE 'Less 100,000' END as total_level
+FROM orders o
+JOIN accounts a on a.id = o.account_id
+WHERE o.occurred_at BETWEEN '2016-01-01' and '2017-12-31'
+GROUP BY a.name, year
+ORDER BY 3 DESC;
+
+# 2. Udacity solution
+
+SELECT a.name, SUM(total_amt_usd) total_spent,
+ CASE WHEN SUM(total_amt_usd) > 200000 THEN 'top'
+ WHEN SUM(total_amt_usd) > 100000 THEN 'middle'
+ ELSE 'low' END AS customer_level
+FROM orders o
+JOIN accounts a
+ON o.account_id = a.id
+WHERE occurred_at > '2015-12-31'
+GROUP BY 1
+ORDER BY 2 DESC;
+
+# 3. Quiz: CASE
+
+/*
+We would like to identify top performing sales reps, which are sales reps associated with more than 200 orders.
+Create a table with the sales rep name, the total number of orders, and a column with top or not depending on if
+they have more than 200 orders. Place the top sales people first in your final table.
+*/
+
+SELECT s.name,
+ COUNT(*) as number_of_orders,
+ CASE WHEN COUNT(*) > 200 THEN 'top'
+ ELSE 'not' END as sales_level
+FROM orders o
+JOIN accounts a on o.account_id = a.id
+JOIN sales_reps s on a.sales_rep_id = s.id
+GROUP BY s.name
+ORDER BY 2 DESC;
+
+# 4. Quiz: CASE
+
+/*
+The previous didn't account for the middle, nor the dollar amount associated with the sales. Management
+decides they want to see these characteristics represented as well. We would like to identify top performing
+sales reps, which are sales reps associated with more than 200 orders or more than 750000 in total sales.
+The middle group has any rep with more than 150 orders or 500000 in sales. Create a table with the sales rep name,
+the total number of orders, total sales across all orders, and a column with top, middle, or low depending on this
+criteria. Place the top sales people based on dollar amount of sales first in your final table.
+*/
+
+SELECT s.name,
+ COUNT(*) as number_of_orders,
+ SUM(total_amt_usd) as total_usd,
+ CASE WHEN COUNT(*) > 200 and SUM(total_amt_usd) > 750000 THEN 'top'
+ WHEN COUNT(*) > 150 and SUM(total_amt_usd) > 500000 THEN 'middle'
+ ELSE 'not' END as sales_level
+FROM orders o
+JOIN accounts a on o.account_id = a.id
+JOIN sales_reps s on a.sales_rep_id = s.id
+GROUP BY s.name
+ORDER BY sales_level DESC;
+
+# 4. Udacity Solution
+
+SELECT s.name, COUNT(*), SUM(o.total_amt_usd) total_spent,
+ CASE WHEN COUNT(*) > 200 OR SUM(o.total_amt_usd) > 750000 THEN 'top'
+ WHEN COUNT(*) > 150 OR SUM(o.total_amt_usd) > 500000 THEN 'middle'
+ ELSE 'low' END AS sales_rep_level
+FROM orders o
+JOIN accounts a
+ON o.account_id = a.id
+JOIN sales_reps s
+ON s.id = a.sales_rep_id
+GROUP BY s.name
+ORDER BY 3 DESC;
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/case_statement.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/case_statement.md
new file mode 100644
index 0000000..9e2316a
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/case_statement.md
@@ -0,0 +1,50 @@
+Derive column take data from existing colimns and modify them.
+
+"CASE" statement handles "if", "Then" logic, is follwed by at least one pair of "When" and "Then" statements. Must end with the world "END".
+
+**CASE - Expert Tip**
++ The CASE statement always goes in the SELECT clause.
+
++ CASE must include the following components: WHEN, THEN, and END. ELSE is an optional component to catch cases that didn’t meet any of the other previous CASE conditions.
+
++ You can make any conditional statement using any conditional operator (like WHERE) between WHEN and THEN. This includes stringing together multiple conditional statements using AND and OR.
+
++ You can include multiple WHEN statements, as well as an ELSE statement again, to deal with any unaddressed conditions.
+
+Example
+In a quiz question in the previous Basic SQL lesson, you saw this question:
+
+Create a column that divides the standard_amt_usd by the standard_qty to find the unit price for standard paper for each order. Limit the results to the first 10 orders, and include the id and account_id fields. NOTE - you will be thrown an error with the correct solution to this question. This is for a division by zero. You will learn how to get a solution without an error to this query when you learn about CASE statements in a later section.
+
+Let's see how we can use the CASE statement to get around this error.
+
+```
+SELECT id, account_id, standard_amt_usd/standard_qty AS unit_price
+FROM orders
+LIMIT 10;
+```
+
+Now, let's use a CASE statement. This way any time the standard_qty is zero, we will return 0, and otherwise we will return the unit_price.
+```
+SELECT account_id, CASE WHEN standard_qty = 0 OR standard_qty IS NULL THEN 0
+ ELSE standard_amt_usd/standard_qty END AS unit_price
+FROM orders
+LIMIT 10;
+```
+
+Example:
+```
+SELECT CASE WHEN total > 500 THEN 'Over 500'
+ ELSE '500 or under' END as total_group,
+ COUNT(*) as order_count
+FROM orders
+GROUP BY 1;
+```
+
+Using `WHERE` clause means only being able to get one set of data at a time.
+
+```
+SELECT COUNT(1) as oredrs_ver_500_units
+FROM orders
+WHERE total > 500;
+```
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/date_functions_quizzes.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/date_functions_quizzes.sql
new file mode 100644
index 0000000..1e81f36
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/aggregations_lesson_30/date_functions_quizzes.sql
@@ -0,0 +1,49 @@
+# 1. Find the sales in terms of total dollars for all orders in each year.
+
+SELECT DATE_TRUNC('year', occurred_at) as year,
+ SUM(total) as total
+FROM orders
+GROUP BY 1
+ORDER BY 2 DESC;
+
+# 2. Which month did Parch & Posey have the greatest sales in terms of
+# total dollars? Are all months evenly represented by the dataset?
+
+SELECT DATE_TRUNC('month', occurred_at) as month,
+ SUM(total_amt_usd) as total
+FROM orders
+WHERE occurred_at BETWEEN '2014-01-01' AND '2017-01-01' # remove the sales from 2013 and 2017
+GROUP BY 1
+ORDER BY 2 DESC;
+
+# 3. Which year did Parch & Posey have the greatest sales in terms
+# of total number of orders? Are all years evenly represented by the dataset?
+
+SELECT DATE_TRUNC('year', occurred_at) as year,
+ COUNT(*) as total_sales
+FROM orders
+GROUP BY 1
+ORDER BY 2 DESC;
+
+
+# 4. Which month did Parch & Posey have the greatest sales in terms of total
+# number of orders? Are all months evenly represented by the dataset?
+
+SELECT DATE_TRUNC('month', occurred_at) as month,
+ COUNT(*) as total_sales
+FROM orders
+WHERE occurred_at BETWEEN '2014-01-01' AND '2017-01-01'
+GROUP BY 1
+ORDER BY 2 DESC;
+
+# 5. In which month of which year did Walmart spend the most on gloss paper in terms of dollars?
+
+SELECT DATE_TRUNC('month', occurred_at) as month,
+ SUM(o.gloss_amt_usd) as gloss_paper_usd
+
+FROM orders o
+JOIN accounts a
+ON a.id = o.account_id
+WHERE a.name = 'Walmart'
+GROUP BY 1
+ORDER BY 2 DESC;
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/notes.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/notes.md
new file mode 100644
index 0000000..6fcd923
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/notes.md
@@ -0,0 +1,47 @@
+# Basic SQL.
+
+One way to store data is to use spreadsheets. To visualize the relationships between spreadsheets using **ERD** (Entity Relationship Diagram). Each spreadsheet is represented on a table. At the top is a name of the table, below each column name is listed. For example:
+
+
+SQL is a language used to interact with a database. It can query one table or across multiple tables.
+
+Database is a collection of tables that share connected data tored in a computer.
+
+Below is the ERD for the database we will use from Parch & Posey. These diagrams help you visualize the data you are analyzing including:
+
+1. The names of the tables.
+2. The columns in each table.
+3. The way the tables work together.
+4. You can think of each of the boxes below as a spreadsheet.
+
+Note: glossy_qty is incorrect, it is actually gloss_qty in the database
+
+# Why SQL?
+
+**SQL** has a variety of functions that allows to read, manipulate and change data. Why **SQL** is so popular for data analyses:
+
+1. **SQL** is easy to understand and learn.
+2. Access data directly.
+3. Easy to audit and copy data.
+4. **SQL** can run queries on multiple tables at once, across large datasets.
+5. You can do: sum, count, max, min..
+6. **SQL** is flexible compare to Google Analytics and Excel.
+
+**NoSQL** stands for not only **SQL**. **NoSQL** envirenments popular for web based data, but less popular for data that lives in spreedsheets.
+
+One of the most popular **NoSQL** database is **MongoDB**. Instead of storing data in tables made out of individual rows, like a relational database does, it stores data in collections made out of individual documents.
+
+## Why Businesses like Databases?
+
+1. Data integrity is ensured - only the data you want entered is entered, and only certain users are able to enter data into the database.
+2. Data can be accessed quickly - SQL allows you to obtain results very quickly from the data stored in a database.
+3. Data is easily shared - multiple individuals can access data stored in a database, and the data is the same for all users allowing for consistent results for anyone with access to your database.
+
+## How DB store data?
+
+Data in DB is stored in tables. DB tables can be organized by column, each column must have a `unique name`. All dat in a column must be of the same type (don't mix string, text or numbers).
+
+Consistent column types are one of the main reasons working with db is fast.
+
+[Comparison of Relational
+ Database](https://www.digitalocean.com/community/tutorials/sqlite-vs-mysql-vs-postgresql-a-comparison-of-relational-database-management-systems)
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/parch_posey_db.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/parch_posey_db.png
new file mode 100644
index 0000000..101cfa7
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/parch_posey_db.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/quizzes.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/quizzes.sql
new file mode 100644
index 0000000..2614b04
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/quizzes.sql
@@ -0,0 +1,213 @@
+### Limits
+
+SELECT occurred_at, account_id, channel
+FROM web_events
+LIMIT 15;
+
+### ORDER BY
+
+/*1.Write a query to return the 10 earliest orders in the orders table.
+Include the id, occurred_at, and total_amt_usd.*/
+
+SELECT id, occurred_at, total_amt_usd
+FROM orders
+LIMIT 10;
+
+/*2.Write a query to return the top 5 orders in terms of largest total_amt_usd.
+Include the id, account_id, and total_amt_usd.*/
+
+SELECT id, account_id, total_amt_usd
+FROM orders
+ORDER BY total_amt_usd desc
+LIMIT 5;
+
+/*3.Write a query to return the bottom 20 orders in terms of least total.
+Include the id, account_id, and total.*/
+
+SELECT id, account_id, total
+FROM orders
+ORDER BY total
+LIMIT 20;
+
+
+## ORDER BY Part 2
+
+/*Write a query that returns the top 5 rows from orders ordered according to newest to oldest,
+but with the largest total_amt_usd for each date listed first for each date.*/
+
+SELECT total_amt_usd
+FROM orders
+ORDER BY total_amt_usd desc
+LIMIT 5;
+
+/*Write a query that returns the top 10 rows from orders ordered according to oldest
+to newest, but with the smallest total_amt_usd for each date listed first for each date.*/
+
+SELECT total_amt_usd
+FROM orders
+ORDER BY total_amt_usd
+LIMIT 10;
+
+## WHERE
+
+/*Pull the first 5 rows and all columns from the orders table that have
+a dollar amount of gloss_amt_usd greater than or equal to 1000.*/
+
+SELECT *
+FROM orders
+WHERE gloss_amt_usd >= 1000
+LIMIT 5;
+
+/*Pull the first 10 rows and all columns from the orders table that
+have a total_amt_usd less than 500.*/
+
+SELECT *
+FROM orders
+WHERE total_amt_usd < 500
+LIMIT 10;
+
+
+## WHERE with Non-Numeric Data
+
+/*Filter the accounts table to include the company name, website, and the
+primary point of contact (primary_poc) for Exxon Mobil in the accounts table.*/
+
+SELECT name, website
+From accounts
+WHERE primary_poc = 'Exxon Mobil';
+
+## Arithmetic Operators
+
+/*Using the orders table:
+
+Create a column that divides the standard_amt_usd by the standard_qty to find the
+unit price for standard paper for each order. Limit the results to the first 10 orders, and include the id and account_id fields.*/
+
+SELECT standard_amt_usd,
+ standard_qty,
+ id,
+ account_id,
+ standard_amt_usd / standard_qty AS unit_cost
+FROM orders
+LIMIT 10;
+
+/*Write a query that finds the percentage of revenue that comes from poster paper for each order. You will need to use only the columns
+that end with _usd. (Try to do this without using the total column). Include the id and account_id fields.*/
+
+SELECT id,
+ account_id,
+ poster_amt_usd / (standard_amt_usd + gloss_amt_usd + poster_amt_usd ) AS poster_paper
+FROM orders;
+
+## LIKE
+
+/*All the companies whose names start with 'C'. */
+
+SELECT *
+FROM accounts
+WHERE name LIKE '%C%';
+
+/*All companies whose names contain the string 'one' somewhere in the name.*/
+
+SELECT *
+FROM accounts
+WHERE name LIKE '%one%';
+
+/*All companies whose names end with 's'.*/
+
+SELECT *
+FROM accounts
+WHERE name LIKE '%s%';
+
+## IN
+/*Use the accounts table to find the account name, primary_poc, and sales_rep_id for Walmart, Target, and Nordstrom.*/
+
+SELECT name, primary_poc, sales_rep_id
+FROM accounts
+WHERE name IN ('Walmart', 'Target', 'Nordstrom');
+
+/*Use the web_events table to find all information regarding individuals who were contacted via the channel of organic or adwords.*/
+
+SELECT channel
+FROM web_events
+WHERE channel IN ('organic', 'adwords');
+
+## NOT
+
+/*Use the accounts table to find the account name, primary poc, and sales rep id for all stores except Walmart, Target, and Nordstrom.*/
+
+SELECT name, primary_poc, sales_rep_id
+FROM accounts
+WHERE name NOT IN ('%Walmart%', '%Target%', '%Nordstrom%');
+
+/*Use the web_events table to find all information regarding individuals who were contacted via any method except using organic or adwords methods.*/
+
+SELECT *
+FROM web_events
+WHERE channel NOT IN ('%organic%', '%adwords%');
+
+/*All the companies whose names do not start with 'C'.*/
+
+SELECT name
+FROM accounts
+WHERE name NOT LIKE ('%C%');
+
+/*All companies whose names do not contain the string 'one' somewhere in the name*/
+
+SELECT name
+FROM accounts
+WHERE name NOT LIKE ('%one%');
+
+/*All companies whose names do not end with 's'.*/
+
+SELECT name
+FROM accounts
+WHERE name NOT LIKE ('%s%');
+
+## AND and BETWEEN
+
+/* 1. Write a query that returns all the orders where the standard_qty is over 1000, the poster_qty is 0, and the gloss_qty is 0.*/
+
+SELECT standard_qty, poster_qty, gloss_qty
+FROM orders
+WHERE standard_qty > 1000 and poster_qty = 0 and gloss_qty = 0;
+
+/* 2. Using the accounts table find all the companies whose names do not start with 'C' and end with 's'.*/
+
+SELECT name
+FROM accounts
+WHERE name NOT LIKE 'C%' AND name LIKE '%s';
+
+/* 3. Use the web_events table to find all information regarding individuals who were contacted via organic or adwords and started their
+account at any point in 2016 sorted from newest to oldest.
+*/
+
+SELECT *
+FROM web_events
+WHERE channel IN ('organic', 'adwords')
+AND occurred_at BETWEEN '2016.01.01' AND '2017.01.01'
+ORDER BY channel DESC;
+
+## OR
+
+/*1.Find list of orders ids where either gloss_qty or poster_qty is greater than 4000. Only include the id field in the resulting table.*/
+
+SELECT *
+FROM orders
+WHERE gloss_qty = 4000 OR poster_qty = 4000
+ORDER BY id;
+
+/*2.Write a query that returns a list of orders where the standard_qty is zero and either the gloss_qty or poster_qty is over 1000.*/
+
+SELECT *
+FROM orders
+WHERE standard_qty = 0 OR poster_qty = 1000
+OR gloss_qty = 1000;
+
+/*3.Find all the company names that start with a 'C' or 'W', and the primary contact contains 'ana' or 'Ana', but it doesn't contain 'eana'.*/
+
+SELECT *
+FROM accounts
+WHERE (name LIKE 'C%' OR name LIKE 'W%')
+ AND ((primary_poc LIKE '%ana%' OR primary_poc LIKE '%Ana%' )
+ AND primary_poc NOT LIKE '%eana%');
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/syntax_sql.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/syntax_sql.md
new file mode 100644
index 0000000..78dcc42
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/syntax_sql.md
@@ -0,0 +1,151 @@
+## Types of Statements.
+
+The SQL laguage has a few different elements, the most basic of which is a statements. `Statements` tell the db what you'd like to do with the data.
+
+`CREATE TABLE` is a statement that creates a new table in a db, changes the data in a db.
+
+`DROP TABLE` removes a table in a db, changes the data in a db.
+
+`SELECT` allows to read data and displays it. Select statements are commonly referred as **queries**.
+
+## SELECT and FROM
+
+In order to generate the list of all orders, write a SELECT statement.
+
+`SELECT` is where you tell the query what columns you want back. Column names are separated by commas with no comma after the last column name.
+
+`SELECT *` select with asterik means select all.
+
+`FROM` is where you tell the query what table you are querying from. Notice the columns need to exist in this table.
+
+Both SELECT and FROM clauses are mandatory.
+
+## Formatting.
+
+It is common practice to capitalize commands (SELECT, FROM). This makes queries easier to read, which will matter more as you write more complex queries.
+
+It is common to use underscores and avoid spaces in column names. It is a bit annoying to work with spaces in SQL.
+
+SQL is not case sensitive. But it's a good habits to capitalize commands.
+
+Depending on your SQL environment, your query may need a semicolon at the end to execute. Other environments are more flexible in terms of this being a "requirement."
+
+Best practice:
+
+```
+SELECT column
+
+FROM table;
+```
+
+## LIMIT
+
+LIMIT statement is used to retrieve records from one or more tables in a database and limit the number of records returned based on a limit value.
+
+```
+SELECT *
+FROM table
+LIMIT 10;
+```
+
+## ORDER BY
+
+ORDER BY statement allows to order table by any row. It goes between the FROM and LIMIT clauses. By default ORDER BY goes from `a to z`, lowest to highest or earliest to latest if working with dates. This is referred to as ascending order.
+
+To sort in descending order, add DESC (from biggest to lowest) after the column in ORDER BY statement.
+
+## WHERE
+
+WHERE statement allows to filter a set of results based on specific criteria. WHERE claus goes after FROM but before ORDER BY or LIMIT.
+
+Comparison operators:
+```
+> (greater than)
+
+< (less than)
+
+>= (greater than or equal to)
+
+<= (less than or equal to)
+
+= (equal to)
+
+!= (not equal to)
+```
+
+## WHERE with Non-Numerical Data.
+
+Comparison operators can work with non-numerical data as well. If you're using an operator with values that are non-numerical you'll need to put the value in single quotes.
+
+## Arithmetic Operators
+
+**Derived Column** a new column that is a manipulation of the existing columns in your db.
+Can include simple arithmetic or any number of advanced conculations.
+```
+* (Multiplication)
+
++ (Addition)
+
+- (Subtraction)
+
+/ (Division)
+```
+
+To rename a derived column: add AS to the end of the line that produced the derived column
+and give then it a name:
+
+```
+glossy_qty + poster_qty AS nonstandard_qty
+```
+
+## Logical Operators
+
+1. LIKE
+This allows you to perform operations similar to using WHERE and =, but for cases when you might not know exactly what you are looking for.
+
+2. IN
+This allows you to perform operations similar to using WHERE and =, but for more than one condition.
+
+3. NOT
+This is used with IN and LIKE to select all of the rows NOT LIKE or NOT IN a certain condition.
+
+4. AND & BETWEEN
+These allow you to combine operations where all combined conditions must be true.
+
+5. OR
+This allow you to combine operations where at least one of the combined conditions must be true.
+
+## LIKE
+
+The `LIKE` operator is exremely useful working with text. Use LIKE within a WHERE clause.
+The LIKE operator is frequently used with '%Example%' or 'S%' or '%s'.
+
+## IN
+
+The `IN` operator is useful for working with both numeric and text columns. This operators allows you to use `=` but for more than one item
+of that particular column and all within the same query.
+
+`IN` requaries single quotation marks around **non-numerical data**, **numerical data** can be entered directly.
+
+## NOT
+
+The `NOT` operator useful for working with the `IN` and `LIKE` operators. By specifying `NOT IN` and `NOT LIKE` we can grab all of the rows
+that don't meet a particular criteria.
+
+`NOT` provides the inverse results for IN, LIKE and similar operators.
+
+## AND and BETWEEN
+The `AND` operator is used within a WHERE statement to consider more than one logical clause at a time. Each time you link a new statement with an AND, you will need to specify the column you are interested in looking at. You may link as many statements as you would like to consider at the same time. This operator works with all of the operations we have seen so far including arithmetic operators (+, *, -, /). LIKE, IN, and NOT logic can also be linked together using the AND operator.
+ The `BETWEEN` operator:
+```
+WHERE column BETWEEN 6 AND 10
+```
+The same as:
+```
+WHERE column >= 6 AND column <= 10
+```
+
+
+## OR
+
+`OR` is a logical operator in SQL that allows to select rows that satisfy either of two conditions. It works similary to `AND` which select the rows that satisfy both of 2 conditions. `OR` works with all the operations including arithmetic operators (+, -, *, /). When combining multiple of these operations, might need to use **parentheses** to assure that the logic you want to perform is being executed correctly.
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/table.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/table.png
new file mode 100644
index 0000000..8db2fd1
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/basic_sql_lesson28/table.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow.md
new file mode 100644
index 0000000..fde96f3
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow.md
@@ -0,0 +1,181 @@
+# Control flow
+
+We'll learn:
+* conditional statements
+* **for** and **while** loop
+* exit or skip loops with **break** and **continue**
+* use **built-in functions**: **zip** and **enumerate**
+* list comprehensions
+
+## **if** statement
+
+An **if** statement is a conditional statement that runs or skips code based on whether a condition is true or false. Example:
+
+```
+if phone_balance < 5:
+ phone_balance += 10
+ bank_balance -= 10
+```
+
+## Comparison Operators in Conditional Statements
+
+`=` assignment operator that assigns value on the left to the name on the right
+
+`==` comparison operator that evaluates whether objects on both sides are equal
+
+## **if**, **elif**, **else**
+
+**if**: An if statement must always start with an if clause, which contains the first condition that is checked. If this evaluates to True, Python runs the code indented in this if block and then skips to the rest of the code after the if statement.
+
+**elif**: elif is short for "else if." An elif clause is used to check for an additional condition if the conditions in the previous clauses in the if statement evaluate to False.
+
+**else**: Last is the else clause, which must come at the end of an if statement if used. This clause doesn't require a condition. The code in an else block is run if all conditions above that in the if statement evaluate to False.
+
+```
+if season == 'spring':
+ print('plant the garden!')
+elif season == 'summer':
+ print('water the garden!')
+elif season == 'fall':
+ print('harvest the garden!')
+elif season == 'winter':
+ print('stay indoors!')
+else:
+ print('unrecognized season')
+```
+
+## Indentation
+
+In Python, indents conventionally come in multiples of four spaces. Be strict about following this convention, because changing the indentation can completely change the meaning of the code.
+
+The [Python Style Guide](https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces) recommends using 4 spaces to indent, rather than using a tab. Whichever you use, be aware that "Python 3 disallows mixing the use of tabs and spaces for indentation."
+
+## Boolean expressions
+
+A **boolean expression** is an expression that is either True or False.
+
+There are tree **logical operatos**: and, or, not. Use parentheses if you need to make the combinations clear.
+
+**if** statements sometimes use more complicated boolean expressions for their conditions. They may contain multiple comparisons operators, logical operators, and even calculations. Examples:
+
+```
+if 18.5 <= weight / height**2 < 25:
+ print("BMI is considered 'normal'")
+
+if is_raining and is_sunny:
+ print("Is there a rainbow?")
+
+if (not unsubscribed) and (location == "USA" or location == "CAN"):
+ print("send email")
+```
+
+However simple or complex, the condition in an **if** statement must be a boolean expression that evaluates to either True or False and it is this value that decides whether the indented block in an if statement executes or not.
+
+## Good and Bad Examples
+
+**Don't use**: `if True:` or `if False:`
+
+Bad example:
+```if True:
+ print("This indented code will always get run.")
+```
+While `True` is a valid boolean expression, it's not useful as a condition since it always evaluates to True, so the indented code will always get run. Similarly, if `False` is not a condition you should use either - the statement following this `if` statement would never be executed.
+
+
+**Be careful** writing expression that use **logical operators**: `and`, `or`, `not`:
+
+Bad example:
+```
+if weather == "snow" or "rain":
+ print("Wear boots!")
+```
+This code is valid in Python, but it is not a boolean expression, although it reads like one. The reason is that the expression to the right of the or operator, "rain", is not a boolean expression - it's a string! Later we'll discuss what happens when you use non-boolean-type objects in place of booleans.
+
+
+**Don't evaluate** the truth of a boolean variable with `== True` or `== False`:
+
+Bad example:
+This comparison isn’t necessary, since the boolean variable itself is a boolean expression.
+```
+if is_cold == True:
+ print("The weather is cold!")
+```
+This is a valid condition, but we can make the code more readable by using the variable itself as the condition instead, as below.
+
+Good example:
+```
+if is_cold:
+ print("The weather is cold!")
+```
+
+If you want to check whether a boolean is False, you can use the **not** operator.
+
+## Truth Value Testing
+If we use a **non-boolean object** as a condition in an if statement in place of the boolean expression, Python will check for its truth value and use that to decide whether or not to run the indented code. By default, the truth value of an object in Python is considered True unless specified as False in the documentation.
+
+Here are most of the built-in objects that are considered False in Python:
+
+* constants defined to be false: `None` and `False`
+
+* zero of any numeric type: `0`, `0.0`, `0j`, `Decimal(0)`, `Fraction(0, 1)`
+
+* empty sequences and collections: `""`, `()`, `[]`, `{}`, `set()`, `range(0)`
+
+Example:
+```
+errors = 3
+if errors:
+ print("You have {} errors to fix!".format(errors))
+else:
+ print("No errors to fix!")
+```
+In this code, errors has the truth value True because it's a non-zero number, so the error message is printed.
+
+## Quiz: Boolean Expressions for Conditions
+
+Imagine an air traffic control program that tracks three variables, altitude,
+speed, and propulsion which for a particular airplane have the values
+specified below:
+```
+altitude = 10000
+speed = 250
+propulsion = "Propeller"
+```
+Expressions:
+
+1.`altitude < 1000 and speed > 100`
+
+ `altitude < 1000` is False, so we don't even need to check the second condition - the whole expression
+ is False.
+
+
+2.`(propulsion == "Jet" or propulsion == "Turboprop") and speed < 300 and altitude > 20000 `
+
+ `propulsion == "Jet"` is False, and `propulsion == "Turboprop"` is False, so the whole expression inside
+ the parentheses is False.
+
+
+3.`not (speed > 400 and propulsion == "Propeller") `
+
+ To work this one out, we need to look at the inside of the parentheses first, then apply not to that.
+ `speed > 400` is False, and because we are using and this makes the whole of the expression inside the
+ parentheses False. Applying not reverses this, so this expression is True.
+
+
+
+4.`(altitude > 500 and speed > 100) or not propulsion == "Propeller" `
+
+ `altitude > 500` is True, and speed is greater than 100, so the expression inside the parenthesis is True.
+ Whatever the value of the other expression, because they are connected by or, the whole expression will
+ evaluate to True.
+
+
+# Break and Continue:
+
+`for` loops iterate over every element in a sequence.
+`while` loops iterate until they're stopping condition is met.
+
+`break` lterminates loop (for or while) immediately if it get a break statement.
+
+`continue` terminates one iteration od a `for` or `while` loop.
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow_practice.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow_practice.py
new file mode 100644
index 0000000..ba2ef7f
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow_practice.py
@@ -0,0 +1,102 @@
+# Practice: Conditional Statement
+
+points = 174 # use this input to make your submission
+
+if points <= 50:
+ result = "Congratulations! You won a wooden rabbit!"
+
+elif 51 <= points <= 150:
+ result = "Oh dear, no prize this time."
+
+elif 151 <= points <= 180:
+ result = "Congratulations! You won a wafer-thin mint!"
+
+else:
+ result = "Congratulations! You won a penguin!"
+
+print(result)
+
+
+# Quiz: Guess My Number
+
+# You decide you want to play a game where you are hiding
+# a number from someone. Store this number in a variable
+# called 'answer'. Another user provides a number called
+# 'guess'. By comparing guess to answer, you inform the user
+# if their guess is too high or too low.
+
+answer = 10 # provide answer
+guess = 5 # provide guess
+
+if guess < answer:
+ result = "Oops! Your guess was too low."
+elif guess > answer:
+ result = "Oops! Your guess was too high."
+elif guess == answer:
+ result = "Nice! Your guess matched the answer!"
+
+print(result)
+
+
+# Quiz: Tax Purchase
+
+# Depending on where an individual is from we need to tax them
+# appropriately. The states of CA, MN, and
+# NY have taxes of 7.5%, 9.5%, and 8.9% respectively.
+# Use this information to take the amount of a purchase and
+# the corresponding state to assure that they are taxed by the right
+# amount.
+
+state = 'CA' # Either CA, MN, or NY
+purchase_amount = 21 # amount of purchase
+
+if state == 'CA':
+ tax_amount = .075
+ total_cost = purchase_amount*(1+tax_amount)
+ result = "Since you're from {}, your total cost is {}.".format(state, total_cost)
+
+elif state == 'MN':
+ tax_amount = .095
+ total_cost = purchase_amount*(1+tax_amount)
+ result = "Since you're from {}, your total cost is {}.".format(state, total_cost)
+
+elif state == 'NY':
+ tax_amount = .089
+ total_cost = purchase_amount*(1+tax_amount)
+ result = "Since you're from {}, your total cost is {}.".format(state, total_cost)
+
+print(result)
+
+
+# Quiz: Boolean Expressions for Conditions
+
+#You will use a new variable prize to store a prize name if one was won, and
+#then use the truth value of this variable to compose the result message. This
+#will involve two if statements.
+
+#1st conditional statement: update prize to the correct prize name based
+#on points.
+#2nd conditional statement: set result to the correct phrase based on whether
+#prize is evaluated as True or False.
+
+
+points = 174
+
+# establish the default prize value to None
+prize = None
+
+# use the points value to assign prizes to the correct prize names
+if points <= 50:
+ prize = "wooden rabbit"
+elif 151 <= points <= 180:
+ prize = "wafer-thin mint"
+elif 181 <= points <= 200:
+ prize = "penguin"
+
+# use the truth value of prize to assign result to the correct prize
+if prize:
+ result = "Congratulations! You won a {}!".format(prize)
+else:
+ result = "Oh dear, no prize this time."
+
+print(result)
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow_quizzes.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow_quizzes.py
new file mode 100644
index 0000000..11b557a
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/control_flow_quizzes.py
@@ -0,0 +1,45 @@
+# Conditional Statements
+
+# First Example - try changing the value of phone_balance
+phone_balance = 1
+bank_balance = 50
+
+if phone_balance < 10:
+ phone_balance += 10
+ bank_balance -= 10
+
+print(phone_balance)
+print(bank_balance)
+
+# Second Example - try changing the value of number
+
+number = 140
+if number % 2 == 0:
+ print("Number " + str(number) + " is even.")
+else:
+ print("Number " + str(number) + " is odd.")
+
+# Third Example - try to change the value of age
+age = 3
+
+# Here are the age limits for bus fares
+free_up_to_age = 4
+child_up_to_age = 18
+senior_from_age = 65
+
+# These lines determine the bus fare prices
+concession_ticket = 1.25
+adult_ticket = 2.50
+
+# Here is the logic for bus fare prices
+if age <= free_up_to_age:
+ ticket_price = 0
+elif age <= child_up_to_age:
+ ticket_price = concession_ticket
+elif age >= senior_from_age:
+ ticket_price = concession_ticket
+else:
+ ticket_price = adult_ticket
+
+message = "Somebody who is {} years old will pay ${} to ride the bus.".format(age, ticket_price)
+print(message)
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/list_comprehensions.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/list_comprehensions.py
new file mode 100644
index 0000000..1869679
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/list_comprehensions.py
@@ -0,0 +1,48 @@
+# Quiz: Extract First Names
+#
+# Use a list comprehension to create a new list first_names containing just
+# the first names in names in lowercase.
+
+names = ["Rick Sanchez", "Morty Smith", "Summer Smith", "Jerry Smith", "Beth Smith"]
+
+first_names = [name.lower().split()[0] for name in names]
+
+print(first_names)
+
+
+# Quiz: Multiples of Three
+# Use a list comprehension to create a list multiples_3 containing the first
+# 20 multiples of 3.
+
+multiples_3 = [ x for x in range(3, 60+1) if x % 3 == 0]
+print(multiples_3)
+
+# Second solution:
+
+multiples_3 = [x * 3 for x in range(1, 21)]
+print(multiples_3)
+
+
+# Quiz: Filter Names by Scores
+# Use a list comprehension to create a list of names passed that only include
+# those that scored at least 65.
+#
+
+
+scores = {
+ "Rick Sanchez": 70,
+ "Morty Smith": 35,
+ "Summer Smith": 82,
+ "Jerry Smith": 23,
+ "Beth Smith": 98
+ }
+
+
+passed = [key for key, value in scores.items() if value >= 65]
+print(passed)
+
+
+# Udacity solution:
+
+passed = [name for name, score in scores.items() if score >= 65]
+print(passed)
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/loops.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/loops.md
new file mode 100644
index 0000000..d6e3209
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/loops.md
@@ -0,0 +1,246 @@
+## Loops
+
+There are two types of loops in Python: `for` and `while`.
+
+A for loop is used to "iterate", or do something repeatedly, over an **iterable**.
+
+An **iterable** is an object that can return one of its elements at a time. This can include **sequence types**, such as strings, lists, and tuples, as well as **non-sequence types**, such as dictionaries and files.
+
+Example:
+```
+cities = ['new york city', 'mountain view', 'chicago', 'los angeles']
+for city in cities:
+ print(city)
+print("Done!")
+```
+Output:
+```
+new york city
+mountain view
+chicago
+los angeles
+Done!
+```
+
+## Built-in function **range()**
+
+The built-in function range() is the function to iterate over a sequence of numbers. It generates an iterator of arithmetic progressions.
+
+Example:
+```
+# Prints out the numbers 0,1,2,3,4
+for x in range(5):
+ print(x)
+```
+
+`range()` is a built-in function used to create an iterable sequence of numbers. You will frequently use `range()` with a `for` loop to repeat an action a certain number of times, as in this example:
+```
+for i in range(3):
+ print("Hello!")
+```
+**range(start=0, stop, step=1)**
+The `range()` function takes three integer arguments, the first and third of which are optional:
+
+* The 'start' argument is the first number of the sequence. If unspecified, 'start' defaults to 0.
+* The 'stop' argument is 1 more than the last number of the sequence. This argument must be specified.
+* The 'step' argument is the difference between each number in the sequence. If unspecified, 'step' defaults to 1.
+
+Notes on using `range()`:
+
+If you specify one integer inside the parentheses withrange(), it's used as the value for 'stop,' and the defaults are used for the other two.
+* e.g. - `range(4)` returns 0, 1, 2, 3
+ If you specify two integers inside the parentheses withrange(), they're used for 'start' and 'stop,' and the default is used for 'step.'
+* e.g. - `range(2, 6)` returns 2, 3, 4, 5
+ Or you can specify all three integers for 'start', 'stop', and 'step.'
+* e.g. - `range(1, 10, 2)` returns 1, 3, 5, 7, 9
+
+* e.g. - `range(0, -5)` returns []
+
+## Creating and Modifying Lists
+You can create a list by appending to a new list at each iteration of the for loop like this:
+
+Creating a new list:
+```
+cities = ['new york city', 'mountain view', 'chicago', 'los angeles']
+capitalized_cities = []
+
+for city in cities:
+ capitalized_cities.append(city.title())
+```
+
+**Modifying** a list is a bit more involved, and requires the use of the range() function.
+
+We can use the range() function to generate the indices for each value in the cities list. This lets us access the elements of the list with cities[index] so that we can modify the values in the cities list in place.
+```
+cities = ['new york city', 'mountain view', 'chicago', 'los angeles']
+
+for index in range(len(cities)):
+ cities[index] = cities[index].title()
+```
+
+## Iterating Through Dictionaries with For Loops
+
+When you iterate through a dictionary using a for loop, doing it the normal way (for n in some_dict) will only give you access to the keys in the dictionary - which is what you'd want in some situations. In other cases, you'd want to iterate through both the keys and values in the dictionary. Let's see how this is done in an example. Consider this dictionary that uses names of actors as keys and their characters as values.
+
+```
+cast = {
+ "Jerry Seinfeld": "Jerry Seinfeld",
+ "Julia Louis-Dreyfus": "Elaine Benes",
+ "Jason Alexander": "George Costanza",
+ "Michael Richards": "Cosmo Kramer"
+ }
+for key in cast:
+ print(key)
+```
+The output:
+```
+Jerry Seinfeld
+Julia Louis-Dreyfus
+Jason Alexander
+Michael Richards
+```
+
+The method ***items()** returns a list of dict's (key, value) tuple pairs.
+```
+cast = {
+ "Jerry Seinfeld": "Jerry Seinfeld",
+ "Julia Louis-Dreyfus": "Elaine Benes",
+ "Jason Alexander": "George Costanza",
+ "Michael Richards": "Cosmo Kramer"
+ }
+
+for key, value in cast.items():
+ print("Actor: {} Role: {}".format(key, value))
+```
+
+The output:
+```
+Actor: Jerry Seinfeld Role: Jerry Seinfeld
+Actor: Julia Louis-Dreyfus Role: Elaine Benes
+Actor: Jason Alexander Role: George Costanza
+Actor: Michael Richards Role: Cosmo Kramer
+```
+Example:
+```
+cast = {
+ "Jerry Seinfeld": "Jerry Seinfeld",
+ "Julia Louis-Dreyfus": "Elaine Benes",
+ "Jason Alexander": "George Costanza",
+ "Michael Richards": "Cosmo Kramer"
+ }
+
+print("Iterating through keys:")
+for key in cast:
+ print(key)
+
+print("\nIterating through keys and values:")
+for key, value in cast.items():
+ print("Actor: {} Role: {}".format(key, value))
+```
+The output:
+```
+Iterating through keys:
+Jason Alexander
+Michael Richards
+Jerry Seinfeld
+Julia Louis-Dreyfus
+
+Iterating through keys and values:
+Actor: Jason Alexander Role: George Costanza
+Actor: Michael Richards Role: Cosmo Kramer
+Actor: Jerry Seinfeld Role: Jerry Seinfeld
+Actor: Julia Louis-Dreyfus Role: Elaine Benes
+```
+
+## **zip** and **enumerate**
+
+`zip` is a built-in function, returns an iterator that combines multiple iterables into one sequence of tuples. A tuple is a sequence of values. The values can be any type and they're indexed by integers. Tuples are immutable.
+For example:
+
+`list(zip(['a', 'b', 'c'], [1, 2, 3]))` would output: `[('a', 1), ('b', 2), ('c', 3)]`
+
+Like we did for range() we need to convert it to a list or iterate through it with a loop to see the elements.
+
+You could unpack each tuple in a for loop like this.
+```
+letters = ['a', 'b', 'c']
+nums = [1, 2, 3]
+
+for letter, num in zip(letters, nums):
+ print("{}: {}".format(letter, num))
+```
+
+To unzip a list into tuples using an asterisk:
+```
+some_list = [('a', 1), ('b', 2), ('c', 3)]
+letters, nums = zip(*some_list)
+```
+
+# enumerate
+
+`enumerate()` a built-in function, returns a list of pairs or enumerate object. The first element of each pair is an index and the second is the sequence's value at that index.
+
+Example:
+
+```
+letters = ['a', 'b', 'c', 'd', 'e']
+for i, letter in enumerate(letters):
+ print(i, letter)
+```
+
+Output:
+
+```
+0 a
+1 b
+2 c
+3 d
+4 e
+```
+
+## List comprehensions
+
+List comprehension is an easy way to define and create lists based on existing lists.
+
+List comprehensions can identify when it receives a string or a tuple and work on it like a list.
+
+You want to separate the letters of the word hand and add the letters as items of a list.
+Example with for loop:
+
+```
+h_letters = []
+
+for letter in 'hand':
+ h_letters.append(letter)
+
+print(h_letters)
+```
+
+List comprehensions:
+
+```
+h_letters = [ letter for letter in 'hand' ]
+print( h_letters)
+```
+**Syntax of List Comprehension**
+`[expression for item in list]` => `letter for letter in 'human'`
+
+
+### Conditionals in List Comprehension
+
+We will create list that uses mathematical operators, integers, and range().
+
+```
+number_list = [ x for x in range(20) if x % 2 == 0]
+print(number_list)
+```
+Output:
+`[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]`
+The list ,number_list, will be populated by the items in range from 0-19 if the item's value is divisible by 2.
+
+`squares = [x**2 for x in range(9) if x % 2 == 0]`
+The code above sets squares equal to the list [0, 4, 16, 36, 64], as x to the power of 2 is only evaluated if x is even.
+
+If you would like to add else, you have to move the conditionals to the beginning of the listcomp, right after the expression, like this.
+`squares = [x**2 if x % 2 == 0 else x + 3 for x in range(9)]`
+List comprehensions are not found in other languages, but are very common in python.
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/loops_quizzes.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/loops_quizzes.py
new file mode 100644
index 0000000..32e82c2
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/loops_quizzes.py
@@ -0,0 +1,325 @@
+# Quiz 1: Create Usernames
+
+#Write a for loop that iterates over the names list to create a usernames list.
+#To create a username for each name, make everything lowercase and replace
+#spaces with underscores. Running your for loop over the list.
+
+
+names = ["Joey Tribbiani", "Monica Geller", "Chandler Bing", "Phoebe Buffay"]
+usernames = []
+
+for name in names:
+ name = name.lower()
+ name = name.replace(' ', '_')
+ usernames.append(name)
+
+ # or shorter variant:
+ # usernames.append(name.lower().replace(' ', '_'))
+
+print(usernames)
+
+
+# Quiz 2: Modify Usernames with Range
+# Write a for loop that uses range() to iterate over the positions in usernames
+# to modify the list. Like you did in the previous quiz, change each name to be
+# lowercase and replace spaces with underscores.
+
+usernames = ["Joey Tribbiani", "Monica Geller", "Chandler Bing",
+ "Phoebe Buffay"]
+
+for index in range(len(usernames)):
+ usernames[index] = usernames[index].lower().replace(' ', '_')
+print(usernames)
+
+
+# Quiz 3: Tag Counter
+# Write a for loop that iterates over a list of strings, tokens, and counts how
+# many of them are XML tags. XML is a data language similar to HTML. You can
+# tell if a string is an XML tag if it begins with a left angle bracket "<" and
+# ends with a right angle bracket ">". Keep track of the number of tags using
+# the variable count.
+
+tokens = ['', 'Hello World!', '']
+count = 0
+
+for token in tokens:
+ if token[0] == '<' and token[-1] == '>':
+ count = count + 1
+
+print(count)
+
+
+# Quiz 4: Create an HTML List
+# Write some code, including a for loop, that iterates over a list of strings
+# and creates a single string, html_str, which is an HTML list. For example,
+# should output:
+#
\n" # "\ n" is the character that marks the end of the line,
+ # it does the characters that are after it in html_str
+ # are on the next line
+
+for item in items:
+ html_str = html_str + "
" + str(item) + "
" "\n"
+
+html_str = html_str + "
"
+
+print(html_str)
+
+
+# Quiz 5: Lower
+# If you want to create a new list called lower_colors, where each color
+# in colors is lower cased, which code would do this?
+
+colors = ['Red', 'Blue', 'Green', 'Purple']
+lower_colors = []
+
+for color in colors:
+ lower_colors.append(color.lower())
+
+print(lower_colors)
+
+
+# Quizzes: Iterating Through Dictionaries
+
+# Quiz 1: Fruit Basket - Task 1
+"""
+You would like to count the number of fruits in your basket. In order to do
+this, you have the following dictionary and list of fruits. Use the dictionary
+and list to count the total number of fruits, but you do not want to count the
+other items in your basket.
+"""
+
+result = 0
+basket_items = {'apples': 4, 'oranges': 19, 'kites': 3, 'sandwiches': 8}
+fruits = ['apples', 'oranges', 'pears', 'peaches', 'grapes', 'bananas']
+
+#Iterate through the dictionary
+for key, value in basket_items.items():
+ for item in fruits:
+ #if the key is in the list of fruits, add the value (number of fruits)
+ #to result
+ if item == key:
+ result = result + value
+
+print(result)
+
+
+# Quiz: Fruit Basket - Task 2
+"""
+If your solution is robust, you should be able to use it with any dictionary of
+items to count the number of fruits in the basket. Try the loop for each of
+the dictionaries below to make sure it always works.
+"""
+
+#Example 1
+
+result = 0
+basket_items = {'pears': 5, 'grapes': 19, 'kites': 3, 'sandwiches': 8, 'bananas': 4}
+fruits = ['apples', 'oranges', 'pears', 'peaches', 'grapes', 'bananas']
+
+# Your previous solution here
+
+for key, value in basket_items.items():
+ for item in fruits:
+
+ #if the key is in the list of fruits, add the value (number of fruits)
+ #to result
+ if item == key:
+ result = result + value
+
+print(result)
+
+#Example 2
+
+result = 0
+basket_items = {'peaches': 5, 'lettuce': 2, 'kites': 3, 'sandwiches': 8, 'pears': 4}
+fruits = ['apples', 'oranges', 'pears', 'peaches', 'grapes', 'bananas']
+
+# Your previous solution here
+
+for key, value in basket_items.items():
+ for item in fruits:
+
+ #if the key is in the list of fruits, add the value (number of fruits)
+ #to result
+ if item == key:
+ result = result + value
+
+print(result)
+
+#Example 3
+
+result = 0
+basket_items = {'lettuce': 2, 'kites': 3, 'sandwiches': 8, 'pears': 4, 'bears': 10}
+fruits = ['apples', 'oranges', 'pears', 'peaches', 'grapes', 'bananas']
+
+# Your previous solution here
+
+for key, value in basket_items.items():
+ for item in fruits:
+ #if the key is in the list of fruits, add the value (number of fruits)
+ #to result
+ if item == key:
+ result = result + value
+
+print("I count {} fruits in the busket".format(result)
+
+
+# Quiz: Fruit Basket - Task 3
+
+# You would like to count the number of fruits in your basket.
+# In order to do this, you have the following dictionary and list of
+# fruits. Use the dictionary and list to count the total number
+# of fruits and not_fruits.
+
+fruit_count, not_fruit_count = 0, 0
+basket_items = {'apples': 4, 'oranges': 19, 'kites': 3, 'sandwiches': 8}
+fruits = ['apples', 'oranges', 'pears', 'peaches', 'grapes', 'bananas']
+
+#Iterate through the dictionary
+for key, value in basket_items.items():
+
+ #if the key is in the list of fruits, add to fruit_count.
+ if key in fruits:
+ fruit_count = fruit_count + value
+
+ #if the key is not in the list, then add to the not_fruit_count
+ else:
+ not_fruit_count = not_fruit_count + value
+
+print("There are {} fruits and {} not fruits".format(fruit_count, not_fruit_count))
+
+# Quiz: Break the String
+#
+# Write a loop with a break statement to create a string, news_ticker, that
+# is exactly 140 characters long. You should create the news ticker by adding
+# headlines from the headlines list, inserting a space in between each headline.
+
+headlines = ["Local Bear Eaten by Man",
+ "Legislature Announces New Laws",
+ "Peasant Discovers Violence Inherent in System",
+ "Cat Rescues Fireman Stuck in Tree",
+ "Brave Knight Runs Away",
+ "Papperbok Review: Totally Triffic"]
+
+news_ticker = ""
+
+headlines = " ".join(headlines)
+
+for letter in headlines:
+ news_ticker = news_ticker + letter
+ if len(news_ticker) == 140:
+ break
+
+print(news_ticker)
+
+# Udacity solution
+
+headlines = ["Local Bear Eaten by Man",
+ "Legislature Announces New Laws",
+ "Peasant Discovers Violence Inherent in System",
+ "Cat Rescues Fireman Stuck in Tree",
+ "Brave Knight Runs Away",
+ "Papperbok Review: Totally Triffic"]
+
+news_ticker = ""
+for headline in headlines:
+ news_ticker += headline + " "
+ if len(news_ticker) >= 140:
+ news_ticker = news_ticker[:140]
+ break
+
+print(news_ticker)
+
+
+# Quiz 1: zip() and enumerate()
+#
+# Zip Coordinates
+
+
+x_coord = [23, 53, 2, -12, 95, 103, 14, -5]
+y_coord = [677, 233, 405, 433, 905, 376, 432, 445]
+z_coord = [4, 16, -6, -42, 3, -6, 23, -1]
+labels = ["F", "J", "A", "Q", "Y", "B", "W", "X"]
+
+points = []
+
+for num_x, num_y, num_z, letter in zip(x_coord, y_coord, z_coord, labels):
+ points.append("{}: {}, {}, {}".format(letter, num_x, num_y, num_z))
+
+print(points)
+
+
+# Udacity solution:
+x_coord = [23, 53, 2, -12, 95, 103, 14, -5]
+y_coord = [677, 233, 405, 433, 905, 376, 432, 445]
+z_coord = [4, 16, -6, -42, 3, -6, 23, -1]
+labels = ["F", "J", "A", "Q", "Y", "B", "W", "X"]
+
+points = []
+for point in zip(labels, x_coord, y_coord, z_coord):
+ points.append("{}: {}, {}, {}".format(*point))
+
+for point in points:
+ print(point)
+
+
+# Quiz 2: zip() and enumerate()
+#
+# Zip Lists to a Dictionary
+
+cast_names = ["Barney", "Robin", "Ted", "Lily", "Marshall"]
+cast_heights = [72, 68, 72, 66, 76]
+
+cast = dict(zip(cast_names, cast_heights))
+
+print(cast)
+
+
+# Quiz 3: unzip
+#
+# Unzip the cast tuple into two names and heights tuples.
+
+
+cast = (("Barney", 72), ("Robin", 68), ("Ted", 72), ("Lily", 66), ("Marshall", 76))
+
+# define names and heights here
+
+names, heights = zip(*cast)
+
+print(names)
+print(heights)
+
+
+# Quiz 4: zip() and enumerate()
+#
+# Quiz: Transpose with Zip
+# Use zip to transpose data from a 4-by-3 matrix to a 3-by-4 matrix
+
+data = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11))
+
+data_transpose = tuple(zip(*data))
+
+print(data_transpose)
+
+
+# Quiz 5: Quiz: Enumerate
+#
+# Use enumerate to modify the cast list so that each element contains the name
+# followed by the character's corresponding height. For example, the first
+# element of cast should change from "Barney Stinson" to "Barney Stinson 72".
+
+cast = ["Barney Stinson", "Robin Scherbatsky", "Ted Mosby", "Lily Aldrin", "Marshall Eriksen"]
+heights = [72, 68, 72, 66, 76]
+
+for index, height in enumerate(heights):
+ s = "{} {}".format(cast[index], height)
+ cast[index] = s
+
+print(cast)
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/while_loops.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/while_loops.md
new file mode 100644
index 0000000..a2dd53a
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/while_loops.md
@@ -0,0 +1,22 @@
+## while Loops
+
+`for` useful if you know how many iterations of the loop you need or "definite iteration". There are situations where it's impossible to know in advance
+how many times will want the loop body executed ("definite iteration"). That's what a `while` loop is used for.
+
+`while` loops sometimes called **conditional** loops because they iterate as long as some conditions is true or end.
+Example:
+```
+card_deck = [4, 11, 8, 5, 13, 2, 8, 10]
+hand = []
+
+# adds the last element of the card_deck list to the hand list
+# until the values in hand add up to 17 or more
+while sum(hand) < 17:
+ hand.append(card_deck.pop())
+```
+
+## sum() and pop()
+
+`sum()`returns the sum of the elements in a list.
+
+`pop()` is the opposite (or inverse) of the append method, it removes the last elemet from a list nd returns it.
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/while_loops.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/while_loops.py
new file mode 100644
index 0000000..c04be54
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/control_flow_lesson_25/while_loops.py
@@ -0,0 +1,169 @@
+# while Loops
+
+# 1.Practice: Water Falls
+
+# Print string vertical.
+
+print_str = "Water falls"
+
+# initialize a counting variable "i" to 0
+i = 0
+
+# write your while header line, comparing "i" to the length of the string
+while i < len(print_str):
+ #print out the current character from the string
+ print(print_str[i])
+
+ #increment counter variable in the body of the loop
+ i = i + 1
+
+#print(print_str)
+
+
+# 2.Practice: Factorials with While Loops
+
+"""
+Find the Factorial of a Number, using While Loop.
+
+A factorial of a whole number is that number multiplied by every whole number
+between itself and 1. For example, 6 factorial (written "6!")
+equals 6 x 5 x 4 x 3 x 2 x 1 = 720. So 6! = 720.
+
+We can write a while loop to take any given number, and figure out what its
+factorial is.
+
+Example: If number is 6, your code should compute and print the product of 720:
+"""
+
+number = 6
+product = number
+
+while number > 1:
+ number = number - 1
+ product = product * number
+
+print(product)
+
+
+
+
+# 3.Practice: Factorials with For Loops
+# Now use a For Loop to Find the Factorial!
+
+number = 6
+# We'll start with the product equal to the number
+product = number
+
+# Write a for loop that calculates the factorial of our number
+for num in range(1, number):
+ if num > 1:
+ number = number - 1
+ product = product * number
+
+print(product)
+
+# another solution without if statement
+for num in range(1, number):
+ product *= num
+
+print(product)
+
+
+# Quiz: Count by
+#
+# 1. Suppose you want to count from some number start_num by another number
+# count_by until you hit a final number end_num. Use break_num as the variable
+# that you'll change each time through the loop.
+
+start_num = 2 # start number
+end_num = 66 # end number that you stop when you hit
+count_by = 3 # some number to count by
+
+break_num = start_num
+while break_num < end_num:
+ break_num = break_num + count_by
+
+print(break_num)
+
+
+# 2. Now in addition, address what would happen if someone gives a start_num
+# that is greater than end_num. If this is the case, set result to "Oops! Looks
+# like your start value is greater than the end value. Please try again."
+# Otherwise, set result to the value of break_num.
+
+start_num = 2 # some start number
+end_num = 22 # some end number that you stop when you hit
+count_by = 3 # some number to count by
+
+# condition to check that end_num is larger than start_num before looping
+
+if start_num > end_num:
+ result = "Oops! Looks like your start value is greater than the end value. Please try again."
+
+else:
+ break_num = start_num
+ while break_num < end_num:
+ break_num += count_by
+ result = break_num
+
+print(result)
+
+
+# 3. Write a while loop that finds the largest square number less than an
+# integerlimit and stores it in a variable nearest_square
+
+limit = 40
+
+count = 1
+nearest_square = 1
+
+while (count + 1) ** 2 < limit:
+ count = count + 1
+ nearest_square = count ** 2
+ #print(nearest_square) # to print all possible nearest square
+
+print(nearest_square)
+
+# Break and Continue
+
+manifest = [("bananas", 15), ("mattresses", 24), ("dog kennels", 42), ("machine", 120), ("cheeses", 5)]
+
+# the code breaks the loop when weight exceeds or reaches the limit
+print("METHOD 1")
+weight = 0
+items = []
+for cargo_name, cargo_weight in manifest:
+ print("current weight: {}".format(weight))
+ if weight >= 100:
+ print(" breaking loop now!")
+ break
+ else:
+ print(" adding {} ({})".format(cargo_name, cargo_weight))
+ items.append(cargo_name)
+ weight += cargo_weight
+
+print("\nFinal Weight: {}".format(weight))
+print("Final Items: {}".format(items))
+
+# skips an iteration when adding an item would exceed the limit
+# breaks the loop if weight is exactly the value of the limit
+print("\nMETHOD 2")
+weight = 0
+items = []
+for cargo_name, cargo_weight in manifest:
+ print("current weight: {}".format(weight))
+ if weight >= 100:
+ print(" breaking from the loop now!")
+ break
+ elif weight + cargo_weight > 100:
+ print(" skipping {} ({})".format(cargo_name, cargo_weight))
+ continue
+ else:
+ print(" adding {} ({})".format(cargo_name, cargo_weight))
+ items.append(cargo_name)
+ weight += cargo_weight
+
+print("\nFinal Weight: {}".format(weight))
+print("Final Items: {}".format(items))
+
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/dictionaries.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/dictionaries.md
new file mode 100644
index 0000000..88f5a41
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/dictionaries.md
@@ -0,0 +1,54 @@
+# Dictionary.
+
+A dictionary is a mutable data type. In a list, the indices have to be integers; in a dictionary they can be (almost) any type.
+
+A dictionary stores pairs of elements **keys** and **values**.
+We can check whether a value is in a dictionary the same way we check whether a value is in a list or set with the `in` keyword.
+`get`is a related method, `get`looks up values in a dictionary and returns `None` if the key is not found or dafault value.
+```python
+food_bill = {"milk": 2, "bread": 1.23, "apples": 4}
+
+food_bill ["cucumber"] = 1.25 # add element
+
+print(food_bill)
+print("tomatoes" in food_bill)
+print(food_bill.get("pear")) # return None
+
+# use is not to check if a key return None
+vegetables = food_bill.get("carrots")
+is_null = vegetables is None # or use: vegetables is not None
+print(is_null)
+```
+
+
+
+```python
+elements.get('dilithium')
+None
+
+elements['dilithium']
+KeyError: 'dilithium'
+
+elements.get('kryptonite', 'There\'s no such element!')
+"There's no such element!"
+```
+
+# Compound Data Structure.
+
+We can include containers in other containers to create compound data structures.
+Nested dictionary:
+```python
+elements = {"hydrogen": {"number": 1,
+ "weight": 1.00794,
+ "symbol": "H"},
+ "helium": {"number": 2,
+ "weight": 4.002602,
+ "symbol": "He"}}
+print(elements['hydrogen'])
+print(elements['hydrogen']['number'])
+print(elements.get('zink', 'There is no such element!'))
+
+```
+Python practice links:
+[More practice](https://www.hackerrank.com/domains/python/py-introduction)
+[Python practice](https://www.codewars.com/users/sign_in)
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/identity_operators.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/identity_operators.png
new file mode 100644
index 0000000..b2fea54
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/identity_operators.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/list_methods_tuples_sets.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/list_methods_tuples_sets.md
new file mode 100644
index 0000000..e37c176
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/list_methods_tuples_sets.md
@@ -0,0 +1,86 @@
+# List Methods.
+
+Python provide methods that operate on list, all this methods modify lists instead of creating a new list.
+
+**Useful** functions for list:
+
+1. `l.append(v)` appends value v to the end of list l.
+2. `l.insert(i, v)` inserts value v at index i in list l.
+3. `l.reverse()` reverses the order of the values in list l.
+4. `len()` returns how many elements are in a list.
+5. `max()` returns the greatest element of the list.
+6. `sorted()` returns a copy of a list in order from smallest to largest, leaving the list unchanged.
+
+
+# Join Method.
+
+`join` takes a list as an argument and returns a string consisting of the list elements joined by a separator string. `\n` is a separator for a new line between elements.
+```python
+new_str = "\n".join(["ann", "get", "an", "umbrella"])
+print(new_str)
+
+Output:
+
+ann
+get
+an
+umbrella
+```
+It is important to remember to separate each of the items in the list you are joining with a comma (,). Forgetting to do so will not trigger an error, but will also give you unexpected results.
+
+# Tuples.
+
+Tuple is a sequence of values, this values can be any type and they are indexed by integers and can be accessed by indicis. Tuples are immutable. you can't add and remove items from tuples, or sort them in place.
+
+They are often used to store related pieces of information (for example: latitude and longitude coordinates). Tuples also used to assign multiple variables in a compact way.
+
+Tuple unpacking used for signing information from a tuple into multiple variables without having to access them one by one and make multiple assignments statement.
+```python
+dimensions = 52, 40, 100
+length, width, height = dimensions # tuple unpacking
+print("The dimensions are {} x {} x {}".format(length, width, height))
+```
+
+```python
+tuple_a = 1, 2
+tuple_b = (1, 2)
+
+print(tuple_a == tuple_b)
+print(tuple_a[1])
+
+Output:
+True #Perenthesis are optional when making tuple.
+2
+```
+
+# Sets.
+
+A set is an unordered collection of unique elements; any elements appears in a set at most once, there are no **duplicates**. Unordered means that elements are not sorted in any order.
+We can create a set from a list:
+```python
+apples_set = set(apples)
+print(len(apples_set))
+```
+
+Sets support the `in` operator the same as lists do.
+Set operations:
+`add` adds element to a `set`.
+`pop` remove a random element.
+
+```python
+fruit = {"apple", "banana", "orange", "grapefruit"} # define a set
+
+print("watermelon" in fruit) # check for element
+
+fruit.add("watermelon") # add an element
+print(fruit)
+
+print(fruit.pop()) # remove a random element
+print(fruit)
+
+Output:
+False
+{'grapefruit', 'orange', 'watermelon', 'banana', 'apple'}
+grapefruit
+{'orange', 'watermelon', 'banana', 'apple'}
+```
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/membership_operators.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/membership_operators.png
new file mode 100644
index 0000000..226e46f
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/membership_operators.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/quizzes_lesson_24.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/quizzes_lesson_24.py
new file mode 100644
index 0000000..b64cda5
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/quizzes_lesson_24.py
@@ -0,0 +1,42 @@
+# 22. Quiz: Slicing Lists
+
+eclipse_dates = ['June 21, 2001', 'December 4, 2002', 'November 23, 2003',
+ 'March 29, 2006', 'August 1, 2008', 'July 22, 2009',
+ 'July 11, 2010', 'November 13, 2012', 'March 20, 2015',
+ 'March 9, 2016']
+# TODO: Modify this line so it prints the last three elements of the list
+print(eclipse_dates[-3:])
+
+# 24. Quiz: List Methods
+
+names = ["Carol", "Albert", "Ben", "Donna"]
+names.append("Eugenia")
+print(sorted(names))
+
+['Albert', 'Ben', 'Carol', 'Donna', 'Eugenia']
+
+# 30. Quiz: Dictionaries
+
+a = [1, 2, 3]
+b = a
+c = [1, 2, 3]
+
+print(a == b) # True
+print(a is b) # True
+print(a == c) # True
+print(a is c) # False
+
+# 34. Quiz: Compound Data Structures
+
+elements = {'hydrogen': {'number': 1, 'weight': 1.00794, 'symbol': 'H'},
+ 'helium': {'number': 2, 'weight': 4.002602, 'symbol': 'He'}}
+
+# todo: Add an 'is_noble_gas' entry to the hydrogen and helium dictionaries
+# hint: helium is a noble gas, hydrogen isn't
+
+elements['hydrogen']['is_noble_gas'] = False
+elements['helium']['is_noble_gas'] = True
+
+print(elements['hydrogen']['is_noble_gas'])
+print(elements['helium']['is_noble_gas'])
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/slicing.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/slicing.png
new file mode 100644
index 0000000..bbbd961
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/slicing.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/slicing_start.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/slicing_start.png
new file mode 100644
index 0000000..da9f556
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/slicing_start.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/string_methods_lists.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/string_methods_lists.md
new file mode 100644
index 0000000..a106197
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/data_types_and_operators_lesson_24/string_methods_lists.md
@@ -0,0 +1,39 @@
+# String Methods.
+
+* String is a sequences of letters.
+* Using methods is almost the same as using function: it takes arguments and returns a value.
+* To call method use dot notation. For example `sample_string.lower()`, methods could receive additional arguments, which are passed inside the parentheses.
+* Methods are specific to the data type for a particular variable. So there are some built-in methods that are available for all strings, different methods that are available for all integers, etc.
+
+Links:
+
+* [String Methods Documentation](https://docs.python.org/3/library/stdtypes.html#string-methods)
+
+# Lists!
+
+A list is a sequence of values. The values in a list are called **elements** (sometimes **items**) and elements can be any type of data. For example:
+
+`random_list = ['Gauda is a cheese?', 32, True]`
+
+`random_list[-1]` # True
+
+`random_list[0]` # Gauda is a cheese?
+
+A list within another list is **nested** list. A list that contains no elements inside is called an **empty** list, for example: []
+Lists are mutable (their content can be modified).
+
+# Slicing, in or not in.
+
+Slicing is used to create new lists that have the same values or parts of the values of the originals.
+
+When using slicing, it is important to remember that the lower index is `inclusive` and the upper index is
+`exclusive`.
+
+
+
+
+
+
+# Mutability and oder.
+
+While lists are mutable and can be modified but strings (strings is an immutable data type) don't. Both strings and lists are ordered.
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/functions.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/functions.md
new file mode 100644
index 0000000..18a47c7
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/functions.md
@@ -0,0 +1,182 @@
+# Functions
+
+**Functions** are useful chunks of code that allow you to encapsulate a task.
+**Encapsulation** is a way to carrry out a whole series of steps with one command.
+
+Functions are used to help organize and optimize code.
+
+# Defining function
+
+When you define a function you specify the name and the sequence of statements.
+
+this function calculates the volume of a cylinder. The formula for this is the cylender's height, multiplied by the square of it's radius multiplied by pi.
+```
+def cylinder_volume(height, radius): # function header # (height, radius) are arguments
+ pi = 3.14159 # body of the function
+ return height * pi * radius ** 2
+
+cylinder_volume(10, 3) # function call statement
+```
+
+**Function Header**
+The function header, which is the first line of a function definition.
+
+1. The function header always starts with the `def` keyword, which indicates that this is a function definition.
+2.Then comes the function name (here, `cylinder_volume`), which follows the same naming conventions as variables. You can revisit the naming conventions below.
+3. Immediately after the name are parentheses that may include arguments separated by commas (here, height and radius). Arguments, or parameters, are values that are passed in as inputs when the function is called, and are used in the function body. If a function doesn't take arguments, these parentheses are left empty.
+4. The header always end with a colon `:`.
+
+
+**Function Body**
+The rest of the function is contained in the body, which is where the function does its work.
+
+1. The body of a function is the code indented after the header line. Here, it's the two lines that define `pi` and `return` the volume.
+2. Within this body, we can refer to the argument variables and define new variables, which can only be used within these indented lines.
+3. The body will often include a return statement, which is used to send back an output value from the function to the statement that called the function. A return statement consists of the return keyword followed by an expression that is evaluated to get the output value for the function. If there is no return statement, the function simply returns `None`.
+
+`Print` provides output o the console while `Return` provides the value hat you can store and work with and code later.
+
+
+## Default Arguments
+
+Default arguments allow functions to use default values when those arguments are omitted.
+
+We can add default arguments in a function to have default values for parameters that are unspecified in a function call.
+
+```
+def cylinder_volume(height, radius=5):
+ pi = 3.14159
+ return height * pi * radius ** 2
+
+cylinder_volume(10) # radius is default avlue in argument
+cylinder_volume(10, 7) # pass in arguments by position, overwrite the default value of 5.
+cylinder_volume(height=10, radius=7) # pass in arguments by name
+```
+
+## Variable scope
+
+**Variable scope** the parts of a program that a variable can be referenced, or used, from.
+If variable is created inside a function, it can only be used within that function. Accessing it outside that function is not possible.
+
+```
+# This will result in an error
+def some_function():
+ word = "hello"
+
+print(word)
+```
+
+`word` is said to have scope that is only local to each function. This means you can use the same name for different variables that are used in different functions.
+```
+# This works fine
+def some_function():
+ word = "hello"
+
+def another_function():
+ word = "goodbye"
+```
+
+We can define a variable outside the function and it can still be accessed within a function.
+
+```
+word = "hello"
+
+def some_function():
+ print(word)
+
+some_function()
+```
+
+**Scope** is essential to understand how info is passed throughout programms in any languges.
+
+## Documentation
+
+**Docstring** a type of comment used to explain the purpose of a function and how it should be used.
+Docstring are sussounded by triple quotes.
+ [PEP 257 -- Docstring Conventions](https://www.python.org/dev/peps/pep-0257/)
+
+
+## Lambda Expressions
+
+In Python, you can use **lambda expressions** to create anonymous functions. That's a function that don't have a name. They're helpful to create quick functions that aren't really needed later in your code.
+sIf you want to specify multiple arguments in a **lambda function**, include them before the colomn, separate by commas.
+
+```
+def multiply(x, y):
+ return x * y
+```
+With a lambda expression:
+
+```
+multiply = lambda x, y: x * y
+```
+
+Both of these functions are used in the same way. In either case, we can call multiply like this:
+`multiply(4, 7)`
+
+**Components of a Lambda Function*
+1. The `lambda` keyword is used to indicate that this is a lambda expression.
+2. Following lambda are one or more arguments for the anonymous function separated by commas, followed by a colon :. Similar to functions, the way the arguments are named in a lambda expression is arbitrary.
+3. Last is an expression that is evaluated and returned in this function.
+
+With this structure, lambda expressions aren’t ideal for complex functions, but can be very useful for short, simple functions.
+
+#### Quiz: Lambda with Map
+`map()` is a higher-order built-in function that takes a function and iterable as inputs, and returns an iterator that applies the function to each element of the iterable. The code below uses map() to find the mean of each list in numbers to create the list averages. Test run it to see what happens.
+
+Rewrite this code to be more concise by replacing the mean function with a lambda expression defined within the call to `map()`.
+
+```
+numbers = [
+ [34, 63, 88, 71, 29],
+ [90, 78, 51, 27, 45],
+ [63, 37, 85, 46, 22],
+ [51, 22, 34, 11, 18]
+ ]
+
+def mean(num_list):
+ return sum(num_list) / len(num_list)
+
+averages = list(map(mean, numbers))
+print(averages)
+```
+
+#### Lambda with Filter
+`filter()` is a higher-order built-in function that takes a function and iterable as inputs and returns an iterator with the elements from the iterable for which the function returns True.
+
+[More about map(), filter()](https://www.programiz.com/python-programming/anonymous-function)
+
+
+## Iterators and Generators
+
+**Iterables** are objects that can return one of it's elements at a time. List is one of the common iterables. Many of the built-in functions we’ve used so far, like 'enumerate,' return an iterator.
+
+**An iterator** is an object that represents a stream of data. This is different from a list, which is also an iterable, but not an iterator because it is not a stream of data.
+
+**Generators** are a simple way to create iterators using functions. It's not only way to create iterator. You can also define iterators using classes, which you can read more about [here](https://docs.python.org/3/tutorial/classes.html#iterators)
+
+Here is an example of a generator function called my_range, which produces an iterator that is a stream of numbers from 0 to (x - 1).
+```
+def my_range(x):
+ i = 0
+ while i < x:
+ yield i
+ i += 1
+
+# since this returns an iterator, we can convert it to a list or iterate through it in a loop to view
+# its contents. For example, this code:
+
+for x in my_range(5):
+ print(x)
+```
+Output:
+```
+0
+1
+2
+3
+4
+```
+
+Notice that instead of using the return keyword, it uses `yield`. This allows the function to return values one at a time, and start where it left off each time it’s called. This `yield` keyword is what differentiates a generator from a typical function.
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/functions.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/functions.py
new file mode 100644
index 0000000..319846a
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/functions.py
@@ -0,0 +1,120 @@
+# Print vs. Return in Functions
+
+
+# this prints something, but does not return anything
+def show_plus_ten(num):
+ print(num + 10)
+
+
+# this returns something
+def add_ten(num):
+ return(num + 10)
+
+print('Calling show_plus_ten...')
+return_value_1 = show_plus_ten(5)
+print('Done calling')
+print('This function returned: {}'.format(return_value_1))
+
+
+print('\nCalling add_ten...')
+return_value_2 = add_ten(10)
+print('Done calling')
+print('This function returned: {}'.format(return_value_2))
+
+
+# Quiz: Population Density Function
+
+def population_density(population, land_area):
+ return population / land_area
+
+# test cases for your function
+test1 = population_density(10, 1)
+expected_result1 = 10
+print("expected result: {}, actual result: {}".format(expected_result1, test1))
+
+test2 = population_density(864816, 121.4)
+expected_result2 = 7123.6902801
+print("expected result: {}, actual result: {}".format(expected_result2, test2))
+
+
+# Quiz: readable_timedelta
+
+def readable_timedelta(days):
+ """
+ Return a string of the number of weeks and days included in days.
+
+ Parameters:
+ days -- number of days to convert (int)
+
+ Returns:
+ string of the number of weeks and days included in days
+ """
+
+ week = days // 7
+ # % to get the number of days that remain
+ day = days % 7
+ return "{} week(s) and {} day(s).".format(week, day)
+
+print(readable_timedelta(6))
+
+# Variable scope
+
+egg_count = 0
+
+def buy_eggs(count):
+ return count + 12 # purchase a dozen eggs
+
+egg_count = buy_eggs(egg_count)
+
+
+# Quiz: Lambda with Map
+# Rewrite this code to be more concise by replacing the mean function with a
+# lambda expression defined within the call to map().
+
+numbers = [
+ [34, 63, 88, 71, 29],
+ [90, 78, 51, 27, 45],
+ [63, 37, 85, 46, 22],
+ [51, 22, 34, 11, 18]
+ ]
+
+
+def mean(num_list):
+ return sum(num_list) / len(num_list)
+
+averages = list(map(mean, numbers))
+print(averages)
+
+# With lambda:
+
+numbers = [
+ [34, 63, 88, 71, 29],
+ [90, 78, 51, 27, 45],
+ [63, 37, 85, 46, 22],
+ [51, 22, 34, 11, 18]
+ ]
+
+averages = list(map(lambda x: sum(x) / len(x), numbers))
+
+print(averages)
+
+
+# Quiz: Lambda with Filter
+# Rewrite this code to be more concise by replacing the is_short function with
+# a lambda expression defined within the call to filter()
+
+cities = ["New York City", "Los Angeles", "Chicago", "Mountain View", "Denver", "Boston"]
+
+def is_short(name):
+ return len(name) < 10
+
+short_cities = list(filter(is_short, cities))
+print(short_cities)
+
+
+# With lambda
+cities = ["New York City", "Los Angeles", "Chicago", "Mountain View", "Denver", "Boston"]
+
+short_cities = list(filter(lambda city: len(city) < 10, cities))
+
+print(short_cities)
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/generator.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/generator.py
new file mode 100644
index 0000000..f6c1533
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/generator.py
@@ -0,0 +1,56 @@
+# square_number function returns a list of squared numbers
+
+def square_numbers(nums):
+ result = []
+ for i in nums:
+ result.append(i * i)
+ return result
+
+
+my_nums = square_numbers([1, 2, 3, 4, 5])
+
+print(my_nums)
+
+print('\n')
+
+# generator
+
+"""
+generator don't hold the entire result in memory it yields one result
+at a time
+"""
+
+def square_numbers(nums):
+ for i in nums:
+ yield (i * i)
+
+my_nums = square_numbers([1, 2, 3, 4, 5]) # my_ nums is generator
+
+for num in my_nums:
+ print(num)
+
+print('\n')
+
+# next(my_nums) the output is 1, the first value in a list and first
+# squared number
+#print next(my_nums) # 1
+#print next(my_nums) # 4
+#print next(my_nums) # 9
+#print next(my_nums) # 16
+#print next(my_nums) 25
+
+
+# generator with list coprehension
+
+my_nums = (x*x for x in [1, 2, 3, 4, 5])
+
+for num in my_nums:
+ print(num)
+
+print('\n')
+
+# generator, convert data in a list
+
+my_nums = (x*x for x in [1, 2, 3, 4, 5])
+
+print list(my_nums)
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/generator_quizzes.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/generator_quizzes.py
new file mode 100644
index 0000000..8252261
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/functions_lesson_26/generator_quizzes.py
@@ -0,0 +1,101 @@
+# Quiz: Implement my_enumerate
+"""
+Write your own generator function that works like the built-in function enumerate.
+
+Calling the function like this:
+
+lessons = ["Why Python Programming", "Data Types and Operators", "Control Flow",
+ "Functions", "Scripting"]
+
+for i, lesson in my_enumerate(lessons, 1):
+ print("Lesson {}: {}".format(i, lesson))
+
+should output:
+
+Lesson 1: Why Python Programming
+Lesson 2: Data Types and Operators
+Lesson 3: Control Flow
+Lesson 4: Functions
+Lesson 5: Scripting
+"""
+
+
+lessons = ["Why Python Programming", "Data Types and Operators", "Control Flow", "Functions", "Scripting"]
+
+
+def my_enumerate(iterable, start=0):
+ # Implement your generator function here
+ for i in range(start, len(iterable) + start):
+ yield(i, iterable[i-start])
+
+for i, lesson in my_enumerate(lessons, 1):
+ print("Lesson {}: {}".format(i, lesson))
+
+
+# print 5 lessons
+
+lessons = ["Why Python Programming", "Data Types and Operators", "Control Flow", "Functions", "Scripting"]
+
+
+def my_enumerate(iterable, start=0):
+ i = start
+ for num in iterable:
+ yield i, num
+ i += 1
+
+for i, lesson in my_enumerate(lessons, 1):
+ print("Lesson {}: {}".format(i, lesson))
+
+
+# Quiz: Chunker
+
+"""
+If you have an iterable that is too large to fit in memory in full (e.g.,
+when dealing with large files), being able to take and use chunks of it at a
+time can be very valuable.
+
+Implement a generator function, chunker, that takes in an iterable and yields
+a chunk of a specified size at a time.
+
+should output:
+
+[0, 1, 2, 3]
+[4, 5, 6, 7]
+[8, 9, 10, 11]
+[12, 13, 14, 15]
+[16, 17, 18, 19]
+[20, 21, 22, 23]
+[24]
+"""
+
+
+def chunker(iterable, size):
+ for i in range(0, len(iterable), size):
+ index = i + size
+ lst = iterable[i:index]
+ yield lst
+
+
+for chunk in chunker(range(25), 4):
+ print(list(chunk))
+
+
+# Udacity solution
+
+def chunker(iterable, size):
+ """Yield successive chunks from iterable of length size."""
+ for i in range(0, len(iterable), size):
+ yield iterable[i:i + size]
+
+for chunk in chunker(range(25), 4):
+ print(list(chunk))
+
+
+# Generator Expressions
+
+
+sq_list = [x**2 for x in range(10)] # this produces a list of squares
+
+sq_iterator = (x**2 for x in range(10)) # this produces an iterator of squares
+
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/population_sample.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/population_sample.png
new file mode 100644
index 0000000..9529151
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/population_sample.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/sampling_error.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/sampling_error.png
new file mode 100644
index 0000000..68e6b15
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/sampling_error.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/terminology_intro_to_research_methods.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/terminology_intro_to_research_methods.md
new file mode 100644
index 0000000..1e8fbd3
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/intro_to_research_methods_lessons_1_5/terminology_intro_to_research_methods.md
@@ -0,0 +1,75 @@
+# Constructs, Variables, Operational definition.
+
+**Construct** is a variable that is not directly observable or measurable. But once a construct has been operationally
+defined, variables are created. Examples of Construct: effort, itchiness, hunger, maturity, wisdom...
+
+
+|Construct | Operational definition |
+| :---: | :---: |
+|`Stress` | Level of cortisol (stress hormone) |
+|`Hunger` | Gramms of food consumed |
+|`Effort` | Minutes spent studying for an exam |
+
+**Operational definition** describes how researcher decide to measure the variables (in our case construct) in a study. It also
+ helps you to measure constructs in the real world by turning them into measurable variables
+
+**Hypothesis** is a statementabout the relationship between the variables.
+
+All experiments/researches examine some kind of variable(s). A variable is not only something that we measure, but also something that we can manipulate and something we can control for.
+
+1. Dependent Variable or Outcome, or y-variable.
+ - Is a variable that is dependent on an independent variable(s).
+
+2. Independent Variable sometimes called Experimental Variable or Manipulated Variable, or Predicted, or x-variable.
+ - Is a variable that is being manipulated in an experiment in order to observe the effect on a Dependent Variable, sometimes called an Outcome Variable.
+
+3. Lurking Variables or Extraneous factors are variables/factors that can impact the Outcome/Dependent Variable.
+
+
+# Sample, population.
+
+**Population (or mu)** are values that describe the entire population.
+A `parameter` is any numerical quantity that characterizes a given population or some aspect of it. This means the parameter tells us something about the whole population. Example of parameters: standard deviation, population mean (average)
+`N` is a population size.
+`mu` is an average (or a mean) of the entire population.
+
+**Sample (or X-bar)** are portions of a population selected for the study. A measurable characteristic of a sample is called a `statistic`.
+`n` is a number of a sample.
+X-bar is an sample average (or a mean) of the population.
+
+
+
+# Sampling designs.
+
+**Random sample** means that each element in the population has an equal chance of being included to the sample.
+
+**Random selection (or sampling)** is a randomly choosing a sample from a population.
+
+**Convenience selection (or sampling)** selections is based on easy availability/accessibility of elements; doesn't represent entire population
+
+
+# Sampling error.
+
+**Samplig error** the difference between a population parameter and a sample statistic used to estimate it. Sampling error occurs because a portion, and not the entire population, is surveyed.
+
+Sampling error formula:
+- `mu - X-bar` or `X-bar - mu` where `mu` is a population average and `X-bar` is a sample average
+
+
+
+
+# Bias.
+
+Bias - any systematic failure of a sample to represent its population.
+The most common is called a **simple random bias**. The best way to avoid random bias is to select elements for the sample at random.
+**Non-response bias** occurs when individuals randomly sampled for a survey fail to respond, cannot respond or decline to participate.
+
+
+Links:
+- [Samplig error][1]
+- [Estimation of a population][2]
+- [OpenIntro Statistics Second Edition by Christopher D. Barr, David M. Diez, and Mine Çetinkaya-Rundel][3]
+
+[1]: https://www.britannica.com/science/sampling-error
+[2]: https://www.britannica.com/science/statistics/Estimation-of-a-population-mean#ref367452
+[3]: https://www.openintro.org/stat/textbook.php?stat_book=os
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/first_script.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/first_script.py
new file mode 100644
index 0000000..7cfbc4e
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/first_script.py
@@ -0,0 +1,19 @@
+
+
+how_many_snakes = 1
+snake_string = """
+Welcome to Python3!
+
+ ____
+ / . .\\
+ \ ---<
+ \ /
+ __________/ /
+-=:___________/
+
+<3, Juno
+"""
+
+
+print(snake_string * how_many_snakes)
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/handling_errors.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/handling_errors.py
new file mode 100644
index 0000000..ebd44e9
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/handling_errors.py
@@ -0,0 +1,12 @@
+def party_planner(cookies, people):
+ leftovers = None
+ num_each = None
+
+ try:
+ num_each = cookies // people
+ leftovers = cookies % people
+ except ZeroDivisionError:
+ print("Oops, you entered 0 people will be attending.")
+ print("Please enter a good number of people for a party.")
+
+ return(num_each, leftovers)
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/message.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/message.py
new file mode 100644
index 0000000..c519d94
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/message.py
@@ -0,0 +1,11 @@
+
+names = input("Enter names separated by commas: ").title().split(",")
+assignments = input("Enter assignment counts separated by commas: ").split(",")
+grades = input("Enter grades separated by commas: ").split(",")
+
+message = "Hi {},\n\nThis is a reminder that you have {} assignments left to \
+submit before you can graduate. You're current grade is {} and can increase \
+to {} if you submit all assignments before the due date.\n\n"
+
+for name, assignment, grade in zip(names, assignments, grades):
+ print(message.format(name, assignment, grade, int(grade) + int(assignment)*2))
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/raw_input.py b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/raw_input.py
new file mode 100644
index 0000000..e69de29
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/scripting.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/scripting.md
new file mode 100644
index 0000000..20f7913
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/scripting_lesson_27/scripting.md
@@ -0,0 +1,81 @@
+## SCRIPTING
+
+* Python Installation and Environment Setup
+* Running and Editing Python Scripts
+* Interacting with User Input
+* Handling Exceptions
+* Reading and Writing Files
+* Importing Local, Standard, and Third-Party Modules
+* Experimenting with an Interpreter
+
+
+## Scripting With Raw Input
+We can get raw input from the user with the built-in function input, which takes in an optional string argument that you can use to specify a message to show to the user when asking for input.
+
+```
+name = input("Enter your name: ")
+print("Hello there, {}!".format(name.title()))
+```
+
+This prompts the user to enter a name and then uses the input in a greeting. The input function takes in whatever the user types and stores it as a string. If you want to interpret their input as something other than a string, like an integer, as in the example below, you need to wrap the result with the new type to convert it from a string.
+
+```
+num = int(input("Enter an integer"))
+print("hello" * num)
+```
+
+We can also interpret user input as a Python expression using the built-in function eval. This function evaluates a string as a line of Python.
+
+```
+result = eval(input("Enter an expression: "))
+print(result)
+```
+
+Float:
+
+```
+num = int(float(input("Enter an integer")))
+print("hello" * num)
+```
+
+
+## Errors And Exceptions
+Syntax errors occur when Python can’t interpret our code, since we didn’t follow the correct syntax for Python. These are errors you’re likely to get when you make a typo, or you’re first starting to learn Python.
+
+Exceptions occur when unexpected things happen during execution of a program, even if the code is syntactically correct. There are different types of built-in exceptions in Python, and you can see which exception is thrown in the error message.
+
+
+## Try Statement
+We can use try statements to handle exceptions. There are four clauses you can use (one more in addition to those shown in the video).
+
+try: This is the only mandatory clause in a try statement. The code in this block is the first thing that Python runs in a try statement.
+except: If Python runs into an exception while running the try block, it will jump to the except block that handles that exception.
+else: If Python runs into no exceptions while running the try block, it will run the code in this block after running the try block.
+finally: Before Python leaves this try statement, it will run the code in this finally block under any conditions, even if it's ending the program. E.g., if Python ran into an error while running code in the except or else block, this finally block will still be executed before stopping the program.
+
+#### Specifying Exceptions
+We can actually specify which error we want to handle in an except block like this:
+```
+try:
+ # some code
+except ValueError:
+ # some code
+```
+Now, it catches the ValueError exception, but not other exceptions. If we want this handler to address more than one type of exception, we can include a tuple after the except with the exceptions.
+
+```
+try:
+ # some code
+except ValueError, KeyboardInterrupt:
+ # some code
+```
+Or, if we want to execute different blocks of code depending on the exception, you can have multiple except blocks.
+
+```
+try:
+ # some code
+except ValueError:
+ # some code
+except KeyboardInterrupt:
+ # some code
+```
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_data_cleaning_lesson32/data_cleaning.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_data_cleaning_lesson32/data_cleaning.sql
new file mode 100644
index 0000000..a4d48e3
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_data_cleaning_lesson32/data_cleaning.sql
@@ -0,0 +1,55 @@
+# LEFT and RIGHT QUIZZES.
+
+# 1. In the accounts table, there is a column holding the website for each company.
+# The last three digits specify what type of web address they are using.
+# Pull these extensions and provide how many of each website type exist in the
+# accounts table.
+
+
+SELECT RIGHT(website, 3) AS web_address, COUNT(*) num_companies
+FROM accounts
+GROUP BY 1
+ORDER BY 2 DESC;
+
+
+# 2.
+/*
+There is much debate about how much the name (or even the first letter of a company name)
+matters. Use the accounts table to pull the first letter of each company name to see the
+distribution of company names that begin with each letter (or number).
+*/
+
+SELECT LEFT(UPPER(name), 1) AS first_char, COUNT(*) num_companies
+FROM accounts
+GROUP BY 1
+ORDER BY 2 DESC;
+
+# 3. Use the accounts table and a CASE statement to create two groups: one group
+# of company names that start with a number and a second group of those company names that
+# start with a letter. What proportion of company names start with a letter?
+
+SELECT SUM(num) nums, SUM(letter) letters
+FROM (SELECT name, CASE WHEN LEFT(UPPER(name), 1) IN ('0','1','2','3','4','5','6','7','8','9')
+ THEN 1 ELSE 0 END AS num,
+ CASE WHEN LEFT(UPPER(name), 1) IN ('0','1','2','3','4','5','6','7','8','9')
+ THEN 0 ELSE 1 END AS letter
+ FROM accounts) t1;
+
+# or
+
+SELECT SUM(CASE WHEN LEFT(name, 1) LIKE '^[0-9]' THEN 1 ELSE 0 END) AS num,
+ SUM(CASE WHEN LEFT(name, 1) LIKE '^[0-9]' THEN 0 ELSE 1 END) AS letter
+ FROM accounts;
+
+
+# 4. Consider vowels as a, e, i, o, and u. What proportion of company names start with a vowel,
+# and what percent start with anything else?
+
+#There are 80 company names that start with a vowel and 271 that start with other characters.
+#Therefore 80/351 are vowels or 22.8%. Therefore, 77.2% of company names do not start with vowels.
+SELECT SUM(vowels) vowels, SUM(other) other
+FROM (SELECT name, CASE WHEN LEFT(UPPER(name), 1) IN ('A','E','I','O','U')
+ THEN 1 ELSE 0 END AS vowels,
+ CASE WHEN LEFT(UPPER(name), 1) IN ('A','E','I','O','U')
+ THEN 0 ELSE 1 END AS other
+ FROM accounts) t1;
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_data_cleaning_lesson32/sql_data_cleaning_lesson32.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_data_cleaning_lesson32/sql_data_cleaning_lesson32.md
new file mode 100644
index 0000000..723ef2c
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_data_cleaning_lesson32/sql_data_cleaning_lesson32.md
@@ -0,0 +1,9 @@
+## LEFT and RIGHT
+
+LEFT pulls a specified number of characters for each row in a specified column starting at the beginning (or from the left). As you saw here, you can pull the first three digits of a phone number using LEFT(phone_number, 3).
+
+
+RIGHT pulls a specified number of characters for each row in a specified column starting at the end (or from the right). As you saw here, you can pull the last eight digits of a phone number using RIGHT(phone_number, 8).
+
+
+LENGTH provides the number of characters for each row of a specified column. Here, you saw that we could use this to get the length of each phone number as LENGTH(phone_number).
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/entity_relationship_diagram.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/entity_relationship_diagram.png
new file mode 100644
index 0000000..71f2ea0
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/entity_relationship_diagram.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/interchangeable_result.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/interchangeable_result.png
new file mode 100644
index 0000000..b1bd6c7
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/interchangeable_result.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/join_quizzes.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/join_quizzes.sql
new file mode 100644
index 0000000..a04a8d9
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/join_quizzes.sql
@@ -0,0 +1,150 @@
+# JOIN practice
+
+/*Try pulling all the data from the accounts table, and all the data from the orders table.*/
+SELECT accounts.*, orders.*
+FROM accounts
+JOIN orders
+ON accounts.id = orders.id;
+
+/*Try pulling standard_qty, gloss_qty, and poster_qty from the orders table, and the website and the primary_poc from the accounts table.*/
+
+SELECT orders.standard_qty, orders.gloss_qty, orders.poster_qty,
+ accounts.website, accounts.primary_poc
+FROM orders
+JOIN accounts
+ON orders.id = accounts.id;
+
+# JOIN QUESTIONS PART 1
+
+/*1.Provide a table for all web_events associated with account name of Walmart. There should be three columns. Be sure to include the primary_poc,
+time of the event, and the channel for each event. Additionally, you might choose to add a fourth column to assure only Walmart events were chosen. */
+
+SELECT web_events.occurred_at, accounts.primary_poc, web_events.channel
+FROM web_events
+JOIN accounts
+ON web_events.account_id = accounts.id
+WHERE accounts.name LIKE '%Walmart%';
+
+/*2.Provide a table that provides the region for each sales_rep along with their associated accounts. Your final table should include three
+columns: the region name, the sales rep name, and the account name. Sort the accounts alphabetically (A-Z) according to account name.*/
+
+SELECT region, sales_reps, accounts AS f_table
+FROM accounts
+JOIN sales_reps
+ON accounts.sales_rep_id = sales_reps.id
+JOIN region
+ON sales_reps.region_id = region.id;
+
+/*3.Provide the name for each region for every order, as well as the account name and the unit price they paid (total_amt_usd/total) for the order. Your
+final table should have 3 columns: region name, account name, and unit price. A few accounts have 0 for total, so I divided by (total + 0.01) to assure
+not dividing by zero.*/
+
+SELECT region.name AS region_name, accounts.name AS account_name, orders.total_amt_usd/(orders.total + 0.01) AS unit_price
+FROM orders
+JOIN accounts ON orders.account_id = accounts.id
+JOIN sales_reps ON accounts.sales_rep_id = sales_reps.id
+JOIN region ON sales_reps.region_id = region.id;
+
+## JOINs and Filtering. Quiz: Last Check
+
+/*1.Provide a table that provides the region for each sales_rep along with their associated accounts. This time only for the Midwest region.
+Your final table should include three columns: the region name, the sales rep name, and the account name. Sort the accounts alphabetically
+(A-Z) according to account name.*/
+
+SELECT region.name AS Region, sales_reps.name AS SalesRepName, accounts.name AS AcountName
+FROM accounts
+JOIN sales_reps
+ON accounts.sales_rep_id = sales_reps.id
+JOIN region ON sales_reps.region_id = region.id
+WHERE region.name = 'Midwest'
+ORDER BY AcountName;
+
+/*2.Provide a table that provides the region for each sales_rep along with their associated accounts. This time only for accounts where the sales rep has a first
+name starting with S and in the Midwest region. Your final table should include three columns: the region name, the sales rep name, and the account name. Sort the
+accounts alphabetically (A-Z) according to account name.*/
+
+SELECT region.name, sales_reps.name AS SalesRepName, accounts.name AS AcountName
+FROM accounts
+JOIN sales_reps
+ON accounts.sales_rep_id = sales_reps.id
+JOIN region
+ON sales_reps.region_id = region.id
+WHERE region.name = 'Midwest' and sales_reps.name LIKE 'S%'
+ORDER BY AcountName;
+
+/*3.Provide a table that provides the region for each sales_rep along with their associated accounts. This time only for accounts where the sales rep has a last name
+starting with K and in the Midwest region. Your final table should include three columns: the region name, the sales rep name, and the account name. Sort the accounts
+alphabetically (A-Z) according to account name.*/
+
+SELECT region.name, sales_reps.name AS SalesRepName, accounts.name AS AcountName
+FROM accounts
+JOIN sales_reps
+ON accounts.sales_rep_id = sales_reps.id
+JOIN region
+ON sales_reps.region_id = region.id
+WHERE region.name = 'Midwest' AND sales_reps.name LIKE '% K%'
+ORDER BY AcountName;
+
+/*4.Provide the name for each region for every order, as well as the account name and the unit price they paid (total_amt_usd/total) for the order. However, you should
+only provide the results if the standard order quantity exceeds 100. Your final table should have 3 columns: region name, account name, and unit price. In order to avoid a
+division by zero error, adding .01 to the denominator here is helpful total_amt_usd/(total+0.01).*/
+
+SELECT region.name, accounts.name AS AcountName, orders.total_amt_usd/(orders.total + 0.01) AS unit_price
+FROM orders
+JOIN accounts
+ON orders.account_id = accounts.id
+JOIN sales_reps
+ON accounts.sales_rep_id = sales_reps.id
+JOIN region
+ON sales_reps.region_id = region.id
+WHERE orders.standard_qty > 100;
+
+/*5.Provide the name for each region for every order, as well as the account name and the unit price they paid (total_amt_usd/total) for the order. However, you should only provide
+the results if the standard order quantity exceeds 100 and the poster order quantity exceeds 50. Your final table should have 3 columns: region name, account name, and unit price.
+Sort for the smallest unit price first. In order to avoid a division by zero error, adding .01 to the denominator here is helpful (total_amt_usd/(total+0.01).*/
+
+SELECT region.name, accounts.name AS AcountName, orders.total_amt_usd/(orders.total + 0.01) AS unit_price
+FROM orders
+JOIN accounts
+ON orders.account_id = accounts.id
+JOIN sales_reps
+ON accounts.sales_rep_id = sales_reps.id
+JOIN region
+ON sales_reps.region_id = region.id
+WHERE orders.standard_qty > 100 AND poster_qty > 50
+ORDER BY unit_price ASC;
+
+/*6.Provide the name for each region for every order, as well as the account name and the unit price they paid (total_amt_usd/total) for the order. However, you should only provide
+the results if the standard order quantity exceeds 100 and the poster order quantity exceeds 50. Your final table should have 3 columns: region name, account name, and unit price.
+Sort for the largest unit price first. In order to avoid a division by zero error, adding .01 to the denominator here is helpful (total_amt_usd/(total+0.01). */
+
+SELECT region.name, accounts.name AS AcountName, orders.total_amt_usd/(orders.total + 0.01) AS unit_price
+FROM orders
+JOIN accounts
+ON orders.account_id = accounts.id
+JOIN sales_reps
+ON accounts.sales_rep_id = sales_reps.id
+JOIN region
+ON sales_reps.region_id = region.id
+WHERE orders.standard_qty > 100 AND poster_qty > 50
+ORDER BY unit_price DESC;
+
+/*7.What are the different channels used by account id 1001? Your final table should have only 2 columns: account name and the different channels. You can try SELECT DISTINCT to narrow
+down the results to only the unique values.*/
+
+SELECT DISTINCT web_events.channel, accounts.name
+FROM web_events
+JOIN accounts
+ON accounts.id = web_events.account_id
+WHERE accounts.id = '1001';
+
+/*8.Find all the orders that occurred in 2015. Your final table should have 4 columns: occurred_at, account name, order total, and order total_amt_usd.*/
+
+SELECT orders.occurred_at, accounts.name, orders.total,
+orders.total_amt_usd
+FROM orders
+JOIN accounts
+ON accounts.id = orders.account_id
+WHERE orders.occurred_at BETWEEN '01-01-2015' AND '01-01-2016'
+ORDER BY orders.occurred_at DESC;
+
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/join_sql.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/join_sql.png
new file mode 100644
index 0000000..017b4df
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/join_sql.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/primary_foreign_key.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/primary_foreign_key.png
new file mode 100644
index 0000000..8739d41
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/primary_foreign_key.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/recap_joins.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/recap_joins.md
new file mode 100644
index 0000000..9d95d56
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/recap_joins.md
@@ -0,0 +1,17 @@
+Primary and Foreign Keys
+You learned a key element for JOINing tables in a database has to do with primary and foreign keys:
+
+* primary keys - are unique for every row in a table. These are generally the first column in our database (like you saw with the id column for every table in the Parch & Posey database).
+
+* foreign keys - are the primary key appearing in another table, which allows the rows to be non-unique.
+
+Choosing the set up of data in our database is very important, but not usually the job of a data analyst. This process is known as Database Normalization.
+
+JOINs
+In this lesson, you learned how to combine data from multiple tables using JOINs. The three JOIN statements you are most likely to use are:
+
+1. JOIN - an INNER JOIN that only pulls data that exists in both tables.
+
+2. LEFT JOIN - a way to pull all of the rows from the table in the FROM even if they do not exist in the JOIN statement.
+
+3. RIGHT JOIN - a way to pull all of the rows from the table in the JOIN even if they do not exist in the FROM statement.
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/sql_joins_lesson_29.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/sql_joins_lesson_29.md
new file mode 100644
index 0000000..c348dfb
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/sql_joins_lesson_29.md
@@ -0,0 +1,147 @@
+## Relational DB
+
+The term **relational database** refers to the fact that tables within it relate to one another. They contain common identidiers that allow information from
+multiple tables to be easily combined.
+
+When you write a query it's execution speed depends on the amount of data you're asking the db to read and the number and type of calculation you're
+asking it to make.
+
+## DB normailization.
+
+When creating a db, it's really important to think about how data will be stored. This is known as **normalization**.
+There are essentially three ideas that are aimed at database normalization:
+
+1. Are the tables storing logical groupings of the data?
+2. Can I make changes in a single location, rather than in many tables for the same information?
+3. Can I access and manipulate data quickly and efficiently?
+
+[Why You Need Database Normalization link](http://www.itprotoday.com/microsoft-sql-server/sql-design-why-you-need-database-normalization)
+
+Example:
+Here we are only pulling data from the orders table since in the SELECT statement we only reference columns from the orders table.
+The ON statement holds the two columns that get linked across the two tables.
+
+
+
+To specify tables and columns in the SELECT statement:
+
+1. The table name is always before the period.
+2. The column you want from that table is always after the period.
+
+For example, if we want to pull only the account name:
+
+```
+SELECT accounts.name, orders.occurred_at
+FROM orders
+JOIN accounts
+ON orders.account_id = accounts.id;
+```
+This query only pulls two columns, not all the information in these two tables.
+
+## ERD reminder.
+
+ERD or entity relationship diagram is a common way to view data in a database.
+
+
+The PK here stands for primary key. A primary key exists in every table, and it is a column that has a unique value for every row.
+If you look at the first few rows of any of the tables in our database, you will notice that this first, PK, column is always unique. For this database it is always called id, but that is not true of all databases.
+
+## Primary and Foreign Keys.
+
+`Primary Key (PK)`
+A primary key is a unique column in a particular table. This is the first column in each of **our tables**. Here, those columns are all called id, but that doesn't necessarily have to be the name. It is common that the primary key is the first column in our tables in most databases.
+
+The primary key is a single column that must exist in each table of a database. Again, these rules are true for most major databases, but some databases may not enforce these rules.
+
+`Foreign Key (FK)`
+A foreign key is when we see a primary key in another table.
+
+Foreign keys are always associated with a primary key, and they are associated with the crow-foot notation above to show they can appear multiple times in a particular table.
+
+
+
+## JOIN more than two tables.
+
+```
+SELECT *
+FROM web_events
+JOIN accounts
+ON web_events.account_id = accounts.id
+JOIN orders
+ON accounts.id = orders.account_id;
+```
+
+## ALIAS
+
+When we `JOIN` tables together it's easiest to give your table names **aliases**. The `ALIAS` for a table will be created in the `FROM` or `JOIN` clauses.
+Best practice: to use all lower case letters and underscores instead of spaces.
+Example:
+```
+FROM tablename AS t1
+JOIN tablename2 AS t2
+```
+Or without the AS statement:
+```
+FROM tablename t1
+JOIN tablename2 t2
+```
+
+We can simply write our alias directly after the column name (in the SELECT) or table name (in the FROM or JOIN) by writing the alias directly following the column or table we would like to alias.
+```
+SELECT col1 + col2 total, col3
+```
+
+```
+Select t1.column1 aliasname, t2.column2 aliasname2
+FROM tablename AS t1
+JOIN tablename2 AS t2
+```
+
+## Many-to-many relationships
+
+[Why no many-to-many relationships?](https://stackoverflow.com/questions/7339143/why-no-many-to-many-relationships)
+
+## LEFT and RIGHT JOIN
+
+INNER JOIN will return only rows that appear in **both tables**.
+
+This Inner Join will return only rows at the intersection of these two circles.
+If want to show accounts that don't appear in the orders table we need to use OUTER Join.
+```
+SELECT accounts.id, accounts.name, order.total
+FROM orders
+JOIN accounts
+ON orders.account_id = accounts.id
+```
+
+Venn Diagram is a common way to visualize JOINs. Each circle in the diagram represents a table. The left circle includes all rows of data in the table in **FROM** clause. The right circle represents all raws of data in the table in **JOIN** clause. The overlapping middle section represents all rows for which the ON clause is **true**.
+
+
+There are three types of joins we might use if we want to include data that doesn't exist in both tables (only in one of the two tables): LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN.
+
+LEFT JOIN produces a complete set of records from the left table regardless if any of those records have match in the right table. It will also return any results that are in the left table that didn't match.
+
+RIGHT JOIN will return all of the records in the right table regardless if any of those records have a match in the left table.
+Left and Right joins are somewhat interchangeable:
+
+
+If there is not matching information in the JOINed table, then you will have columns with empty cells. These empty cells introduce a new data type called NULL.
+
+## OUTER JOIN
+
+OUTER JOIN will return the inner join result set, as well as any unmatched rows from either of the two tables being joined.
+
+Again this returns rows that do not match one another from the two tables. The use cases for a full outer join are very rare.
+[When is a good situation to use a full outer join?](https://stackoverflow.com/questions/2094793/when-is-a-good-situation-to-use-a-full-outer-join)
+
+FULL OUTER JOIN, which is the same as OUTER JOIN. LEFT OUTER JOIN and RIGHT OUTER JOIN the same as LEFT JOIN and RIGHT JOIN.
+
+## JOINs and Filtering
+
+`ON` logic in the on clause reduces the rows **before combining the tables**.
+
+`WHERE` logic in the where clause occurs **after the join occurs**.
+
+ When the database executes the query, it executes the join and everything in the **ON clause first**. Think of this as building the new result set. That result set is then filtered using the WHERE clause.
+
+ INNER JOINs only return the rows for which the two tables match, moving this filter to the ON clause of an inner join will produce the same result as keeping it in the WHERE clause.
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/venn_diagram.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/venn_diagram.png
new file mode 100644
index 0000000..bfc8092
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_joins_lesson_29/venn_diagram.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/subqueries_tasks.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/subqueries_tasks.sql
new file mode 100644
index 0000000..33081af
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/subqueries_tasks.sql
@@ -0,0 +1,149 @@
+# 1. Quiz
+# Find the number f events that occur for each day or each channel
+
+SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as events_count
+FROM web_events
+GROUP BY day, channel
+ORDER BY events_count DESC;
+
+
+# 2. Quiz
+# Create a subquery that provides all of the data rom your first query.
+
+SELECT *
+FROM
+(SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as events_count
+FROM web_events
+GROUP BY day, channel
+ORDER BY events_count DESC) sub;
+
+
+# 3. Quiz
+# Find the average number of events or each channel.
+
+SELECT channel,
+ AVG(events_count) as avg_events_count
+FROM
+(SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as events_count
+FROM web_events
+GROUP BY day, channel) sub
+GROUP BY channel
+ORDER BY avg_events_count DESC;
+
+# More on subqueries:
+
+# pull the first month/year combo from the orders table
+
+SELECT DATE_TRUNC('month', MIN(occurred_at)) AS min_month
+FROM web_events;
+
+# pull the average for each. Total result
+
+SELECT SUM(total_amt_usd)
+FROM orders
+WHERE DATE_TRUNC('month', occurred_at) =
+ (SELECT DATE_TRUNC('month', MIN(occurred_at)) FROM orders);
+
+# Result per each kind of a peper
+
+SELECT AVG(standard_qty) as avg_standard,
+ AVG(gloss_qty) as avg_gloss,
+ AVG(poster_qty) as avg_poster
+FROM orders
+WHERE DATE_TRUNC('month', occurred_at) =
+(SELECT DATE_TRUNC('month', MIN(occurred_at)) AS min
+FROM orders);
+
+
+# QUIZ: Subquery Mania
+# 1. Provide the name of the sales_rep in each region with the largest amount of total_amt_usd sales.
+
+SELECT s.name, s.region_id, MAX(o.total_amt_usd) as max_total
+FROM sales_reps s
+JOIN accounts a ON s.id = a.sales_rep_id
+JOIN orders o ON a.id = o.account_id
+GROUP BY s.name, s.region_id
+ORDER BY max_total DESC;
+
+# 2. For the region with the largest (sum) of sales total_amt_usd, how many total (count) orders were placed?
+
+SELECT s.name, r.name, SUM(o.total_amt_usd) as total_amt_usd, COUNT(total) total_orders
+FROM region r
+JOIN sales_reps s ON r.id = s.region_id
+JOIN accounts a ON s.id = a.sales_rep_id
+JOIN orders o ON a.id = o.account_id
+GROUP BY s.name, r.name
+ORDER BY total_amt_usd DESC;
+
+# 3. For the name of the account that purchased the most (in total over their lifetime as a customer)
+# standard_qty paper, how many accounts still had more in total purchases?
+
+SELECT a.name, w.channel, COUNT(w.id)
+FROM accounts a
+JOIN web_events w ON a.id = w.account_id
+GROUP BY 1, 2
+HAVING a.name = (SELECT customer
+FROM (SELECT a.name AS customer, SUM(o.total_amt_usd) AS total_usd
+FROM accounts a
+JOIN orders o ON a.id = o.account_id
+GROUP BY 1
+ORDER BY 2 DESC
+LIMIT 1) t1)
+ORDER BY 3 DESC;
+
+# 4. For the customer that spent the most (in total over their lifetime as
+# a customer) total_amt_usd, how many web_events did they have for each channel?
+
+SELECT *
+FROM (SELECT a.name, w.channel, COUNT(w.channel)
+ FROM web_events w
+ JOIN accounts a ON a.id = w.account_id
+ GROUP BY a.name, w.channel) t1
+JOIN (SELECT a.name, sum(o.total_amt_usd) total_usd
+ FROM accounts a
+ JOIN orders o ON a.id = o.account_id
+ GROUP BY a.name
+ ORDER BY total_usd DESC
+ LIMIT 1) t2
+ ON t1.name = t2.name
+
+
+# 5. What is the lifetime average amount spent in terms
+# of total_amt_usd for the top 10 total spending accounts?
+
+SELECT a.id, a.name, SUM(o.total_amt_usd) total_spent
+FROM orders o
+JOIN accounts a
+ON a.id = o.account_id
+GROUP BY a.id, a.name
+ORDER BY 3 DESC
+LIMIT 10;
+
+# average of 10 amounts
+
+SELECT AVG(total_spent)
+FROM (SELECT a.id, a.name, SUM(o.total_amt_usd) total_spent
+ FROM orders o
+ JOIN accounts a
+ ON a.id = o.account_id
+ GROUP BY a.id, a.name
+ ORDER BY 3 DESC
+ LIMIT 10) temp;
+
+# 6. What is the lifetime average amount spent in terms
+# of total_amt_usd for only the companies that spent more
+# than the average of all orders.
+
+SELECT AVG(avg_amt_usd)
+FROM (SELECT o.account_id, AVG(o.total_amt_usd) as avg_amt_usd
+FROM orders o
+GROUP BY 1
+HAVING AVG(o.total_amt_usd) >
+(SELECT AVG(total_amt_usd)
+FROM orders)) temp_table;
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/subqueries_temporary_tables.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/subqueries_temporary_tables.md
new file mode 100644
index 0000000..48520f2
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/subqueries_temporary_tables.md
@@ -0,0 +1,208 @@
+## Intro to subqueries
+
+Both **subqueries** and table expressions are methods for being able to write a query that creates a table, and then write a query that interacts with this newly created table. Sometimes the question you are trying to answer doesn't have an answer when working directly with existing tables in database.
+
+However, if we were able to create new tables from the existing tables, we know we could query these new tables to answer our question
+
+Whenever we need to use existing tables to create a new table that we then want to query again, this is an indication that we will need to use some sort of subquery.
+
+**Subqueries** also known as **inner queries** and **nested queries** - allow you to answer more complex questions than you can with a single DB table.
+
+## Write your first subquery
+We want to find the average number of events for each day for each channel. The first table will provide us the number of events for each day and channel, and then we will need to average these values together using a second query.
+
+1. Start by querying table to check the data.
+
+```
+SELECT *
+FROM web_events;
+```
+
+2. Count up all the events in each channel, in each day.
+
+```
+SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as event_count
+FROM web_events
+GROUP BY 1, 2
+ORDER BY 1;
+```
+
+3. Average across the events column we've created. In order to do this, we quering the result of previous query. We can do it by wrapping the query in parantheses and using it in the FROM clause of the next query that you write above.
+
+Query within a query also known as a subquery:
+```
+SELECT *
+FROM
+(SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as event_count
+FROM web_events
+GROUP BY 1, 2
+ORDER BY 1) sub
+```
+**Subqueries** are requaired to have aliases, which added after the parantheses `()sub`.
+
+4. Average events for each channel. Subquery acts like one table in the FORM clause put GROUP BY clause after he subquery.
+Since reordering based on this new aggregation, you don't need ORDER BY statement in the subquery.
+```
+SELECT channel,
+ AVG(event_count) AS avg_event_count
+FROM
+(SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as event_count
+FROM web_events
+GROUP BY 1, 2) sub
+ GROUP BY channel
+ ORDER BY 2 DESC;
+```
+
+####How this query runs:
+
+1. Inner query will run. DB will treat it as an independent query
+```
+SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as event_count
+FROM web_events
+GROUP BY 1, 2
+```
+2. The outer query will run accross he result set created by he inner query:
+```
+SELECT channel,
+ AVG(event_count) AS avg_event_count
+FROM
+(SELECT DATE_TRUNC('day', occurred_at) as day,
+ channel,
+ COUNT(*) as event_count
+FROM web_events
+GROUP BY 1, 2) sub
+ GROUP BY channel
+ ORDER BY 2 DESC;
+```
+
+## Subquery Formatting
+
+#### Badly formatted queries
+
+```
+SELECT * FROM (SELECT DATE_TRUNC('day',occurred_at) AS day, channel, COUNT(*) as events FROM web_events GROUP BY 1,2 ORDER BY 3 DESC) sub;
+```
+
+This second version, which includes some helpful line breaks, is easier to read than that previous version, but it is still not as easy to read as the queries in the Well Formatted Query section.
+
+```
+SELECT *
+FROM (
+SELECT DATE_TRUNC('day',occurred_at) AS day,
+channel, COUNT(*) as events
+FROM web_events
+GROUP BY 1,2
+ORDER BY 3 DESC) sub;
+```
+
+#### Well Formatted Query
+
+If we have a GROUP BY, ORDER BY, WHERE, HAVING, or any other statement following our subquery, we would then indent it at the same level as our outer query.
+
+```
+SELECT *
+FROM (SELECT DATE_TRUNC('day',occurred_at) AS day,
+ channel, COUNT(*) as events
+ FROM web_events
+ GROUP BY 1,2
+ ORDER BY 3 DESC) sub;
+```
+
+The inner query GROUP BY and ORDER BY statements are indented to match the inner table.
+```
+SELECT *
+FROM (SELECT DATE_TRUNC('day',occurred_at) AS day,
+ channel, COUNT(*) as events
+ FROM web_events
+ GROUP BY 1,2
+ ORDER BY 3 DESC) sub
+GROUP BY channel
+ORDER BY 2 DESC;
+```
+
+## More on Subqueries
+
+If you are only returning a single value, you might use that value in a logical statement like WHERE, HAVING, or even SELECT - the value could be nested within a CASE statement. Most conditional logic will work with subqueries containing **one-cell results**. BUT `IN` is the only type of conditional logic that will work when the inner query ontains multiple results.
+
+
+
+**Expert Tip**
+
+Note that you should not include an alias when you write a subquery in a conditional statement. This is because the subquery is treated as an individual value (or set of values in the IN case) rather than as a table.
+
+Also, notice the query here compared a single value. If we returned an entire column IN would need to be used to perform a logical argument. If we are returning an entire table, then we must use an ALIAS for the table, and perform additional logic on the entire table.
+
+### MORE on sub queries
+
+1. Subquery table
+```
+SELECT a.id, a.name, we.channel, COUNT(*) as ct
+FROM accounts a
+JOIN web_events we
+ON a.id = we.account_id
+GROUP BY a.id, a.name, channel
+ORDER BY a.id;
+```
+
+2. Find the max from all data:
+```
+SELECT MAX(ct)
+
+FROM (SELECT a.id, a.name, we.channel, COUNT(*) as ct
+ FROM accounts a
+ JOIN web_events we
+ ON a.id = we.account_id
+ GROUP BY a.id, a.name, channel
+ ORDER BY a.id) table1
+```
+
+3. Max for every accounts:
+
+```
+SELECT t1.id, t1.name, MAX(ct)
+FROM (SELECT a.id, a.name, we.channel, COUNT(*) as ct
+ FROM accounts a
+ JOIN web_events we
+ ON a.id = we.account_id
+ GROUP BY a.id, a.name, channel) t1
+GROUP BY t1.id, t1.name
+ORDER BY t1.id;
+```
+
+4. Final table:
+
+```
+SELECT t3.id, t3.name, t3.channel, t3.ct
+FROM (SELECT a.id, a.name, we.channel, COUNT(*) as ct
+ FROM accounts a
+ JOIN web_events we
+ ON a.id = we.account_id
+ GROUP BY a.id, a.name, channel) t3
+
+JOIN (SELECT t1.id, t1.name, MAX(ct) max_chan
+FROM (SELECT a.id, a.name, we.channel, COUNT(*) as ct
+ FROM accounts a
+ JOIN web_events we
+ ON a.id = we.account_id
+ GROUP BY a.id, a.name, channel) t1
+GROUP BY t1.id, t1.name) t2
+ON t2.id = t3.id AND t2.max_chan = t3.ct
+ORDER BY t3.id, t3.ct;
+```
+
+## WITH
+
+The `WITH` statement is often called a Common Table Expression or CTE. Though these expressions serve the exact same purpose as subqueries, they are more common in practice, as they tend to be cleaner for a future reader to follow the logic.
+
+Subqueries they make queries lengthy and difficult to read. Common Table Expressions or CTEs can help break your query into separate components and the logic will be more easily to read.
+
+* When creating multiple ables using `WITH` add a comma after every table except the last table leading to final query.
+* The new table name always aliased using `table_name AS`, which is followed by your nasted between parentheses.
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/with_vs_subquery.sql b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/with_vs_subquery.sql
new file mode 100644
index 0000000..cae77aa
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/sql_subqueries_temporary_table_lesson31/with_vs_subquery.sql
@@ -0,0 +1,199 @@
+# You need to find the average number of events for each channel per day.
+
+
+SELECT channel, AVG(events) AS average_events
+FROM (SELECT DATE_TRUNC('day',occurred_at) AS day,
+ channel, COUNT(*) as events
+ FROM web_events
+ GROUP BY 1,2) sub
+GROUP BY channel
+ORDER BY 2 DESC;
+
+
+# Using with
+
+# Notice, you can pull the inner query:
+
+SELECT DATE_TRUNC('day',occurred_at) AS day,
+ channel, COUNT(*) as events
+FROM web_events
+GROUP BY 1,2
+
+# This is the part we put in the WITH statement.
+# Notice, we are aliasing the table as events below:
+
+WITH events AS (
+ SELECT DATE_TRUNC('day',occurred_at) AS day,
+ channel, COUNT(*) as events
+ FROM web_events
+ GROUP BY 1,2)
+
+# Now, we can use this newly created events table as if it is any
+# other table in our database:
+
+WITH events AS (
+ SELECT DATE_TRUNC('day',occurred_at) AS day,
+ channel, COUNT(*) as events
+ FROM web_events
+ GROUP BY 1,2)
+
+SELECT channel, AVG(events) AS average_events
+FROM events
+GROUP BY channel
+ORDER BY 2 DESC;
+
+
+# For the above example, we don't need anymore than the one additional table,
+# but imagine we needed to create a second table to pull from. We can create
+# an additional table to pull from in the following way:
+
+WITH table1 AS (
+ SELECT *
+ FROM web_events),
+
+ table2 AS (
+ SELECT *
+ FROM accounts)
+
+
+SELECT *
+FROM table1
+JOIN table2
+ON table1.account_id = table2.id;
+
+
+# QUIZ: WITH
+
+# Provide the name of the sales_rep in each region with the largest amount of
+# total_amt_usd sales.
+
+WITH t1 AS (
+ SELECT s.name rep_name, r.name region_name, SUM(o.total_amt_usd) total_amt
+ FROM sales_reps s
+ JOIN accounts a
+ ON a.sales_rep_id = s.id
+ JOIN orders o
+ ON o.account_id = a.id
+ JOIN region r
+ ON r.id = s.region_id
+ GROUP BY 1,2
+ ORDER BY 3 DESC),
+t2 AS (
+ SELECT region_name, MAX(total_amt) total_amt
+ FROM t1
+ GROUP BY 1)
+SELECT t1.rep_name, t1.region_name, t1.total_amt
+FROM t1
+JOIN t2
+ON t1.region_name = t2.region_name AND t1.total_amt = t2.total_amt;
+
+# For the region with the largest sales total_amt_usd, how many total orders were placed?
+
+WITH t1 AS (
+ SELECT r.name region_name, SUM(o.total_amt_usd) total_amt
+ FROM sales_reps s
+ JOIN accounts a
+ ON a.sales_rep_id = s.id
+ JOIN orders o
+ ON o.account_id = a.id
+ JOIN region r
+ ON r.id = s.region_id
+ GROUP BY r.name),
+t2 AS (
+ SELECT MAX(total_amt)
+ FROM t1)
+SELECT r.name, COUNT(o.total) total_orders
+FROM sales_reps s
+JOIN accounts a
+ON a.sales_rep_id = s.id
+JOIN orders o
+ON o.account_id = a.id
+JOIN region r
+ON r.id = s.region_id
+GROUP BY r.name
+HAVING SUM(o.total_amt_usd) = (SELECT * FROM t2);
+
+# For the account that purchased the most (in total over their lifetime as a
+# customer) standard_qty paper, how many accounts still had more in total
+# purchases?
+
+WITH t1 AS (
+ SELECT a.name account_name, SUM(o.standard_qty) total_std, SUM(o.total) total
+ FROM accounts a
+ JOIN orders o
+ ON o.account_id = a.id
+ GROUP BY 1
+ ORDER BY 2 DESC
+ LIMIT 1),
+t2 AS (
+ SELECT a.name
+ FROM orders o
+ JOIN accounts a
+ ON a.id = o.account_id
+ GROUP BY 1
+ HAVING SUM(o.total) > (SELECT total FROM t1))
+SELECT COUNT(*)
+FROM t2;
+
+
+#For the customer that spent the most (in total over their lifetime as a
+#customer) total_amt_usd, how many web_events did they have for each channel?
+
+WITH t1 AS (
+ SELECT a.id, a.name, SUM(o.total_amt_usd) tot_spent
+ FROM orders o
+ JOIN accounts a
+ ON a.id = o.account_id
+ GROUP BY a.id, a.name
+ ORDER BY 3 DESC
+ LIMIT 1)
+SELECT a.name, w.channel, COUNT(*)
+FROM accounts a
+JOIN web_events w
+ON a.id = w.account_id AND a.id = (SELECT id FROM t1)
+GROUP BY 1, 2
+ORDER BY 3 DESC;
+
+# What is the lifetime average amount spent in terms of total_amt_usd for the
+# top 10 total spending accounts?
+
+WITH t1 AS (
+ SELECT a.id, a.name, SUM(o.total_amt_usd) tot_spent
+ FROM orders o
+ JOIN accounts a
+ ON a.id = o.account_id
+ GROUP BY a.id, a.name
+ ORDER BY 3 DESC
+ LIMIT 10)
+SELECT AVG(tot_spent)
+FROM t1;
+
+
+# 6. What is the lifetime average amount spent in terms of total_amt_usd for
+# only the companies that spent more than the average of all accounts.
+
+# query avg(total_amt_usd) for all accounts
+SELECT AVG(o.total_amt_usd) avg_all
+ FROM orders o
+ JOIN accounts a
+ ON a.id = o.account_id;
+
+# AVG() of all orders
+SELECT o.account_id, AVG(o.total_amt_usd) avg_amt
+ FROM orders o
+ GROUP BY 1
+ HAVING AVG(o.total_amt_usd) > (SELECT AVG(o.total_amt_usd) avg_all
+ FROM orders o
+ JOIN accounts a
+ ON a.id = o.account_id);
+
+# lifetime avg
+
+SELECT AVG(avg_amt)
+FROM (SELECT o.account_id, AVG(o.total_amt_usd)avg_amt
+ FROM orders o
+ GROUP BY 1
+ HAVING AVG(o.total_amt_usd) > (SELECT AVG(o.total_amt_usd) avg_all
+ FROM orders o
+ JOIN accounts a
+ ON a.id = o.account_id)) t1;
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/avg_abs_dev_formula.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/avg_abs_dev_formula.png
new file mode 100644
index 0000000..a4b848e
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/avg_abs_dev_formula.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/avg_squared_deviation.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/avg_squared_deviation.png
new file mode 100644
index 0000000..9c8cbb4
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/avg_squared_deviation.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/quizzes_lesson13.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/quizzes_lesson13.md
new file mode 100644
index 0000000..a06131d
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/quizzes_lesson13.md
@@ -0,0 +1,26 @@
+### 24. Which formula describes Average Absolute Deviations:
+
+
+
+### 26. Sum of Squres
+
+Another way to get rid of negative values is to squared each one. It means, to multiply each value by itself.
+
+
+The last correct formula is called **SS - sum of squares**.
+
+### 27. Average Squared Deviation
+
+
+
+The average score diviation is 291,622,740. There's a special name for this number, it's called the **variance**.
+
+How can we put **variance** in words?
+* Mean of squared deviations. (add all squared deviations and dedvide by n)
+* Sum of squared deviations divided ba n.
+
+### 33. Quiz: Standard Deviation in Words.
+
+What is a way to put the Standard Deviation in words?
+
+* Square root of average quared deviation
\ No newline at end of file
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/sum_squared_deviation_formula.png b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/sum_squared_deviation_formula.png
new file mode 100644
index 0000000..ca484bc
Binary files /dev/null and b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/sum_squared_deviation_formula.png differ
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/variability.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/variability_lesson_13/variability.md
new file mode 100644
index 0000000..e69de29
diff --git a/udacity-bertelsmann-data-science-challenge-scholarship-2018/visualizing_data_lesson_6/visualizing_data.md b/udacity-bertelsmann-data-science-challenge-scholarship-2018/visualizing_data_lesson_6/visualizing_data.md
new file mode 100644
index 0000000..89ff5a8
--- /dev/null
+++ b/udacity-bertelsmann-data-science-challenge-scholarship-2018/visualizing_data_lesson_6/visualizing_data.md
@@ -0,0 +1,24 @@
+# Frequency table.
+
+The number of times a certain value appears in a row/set of data is called the **frequency**. Frequency is a better word for number.
+For example, in the following list of numbers, the frequency of the number 3 is 6 (because it occurs 6 times):
+ `1, 4, 3, 9, 11, 3, 3, 5, 77, 3, 88, 3, 3`
+
+A frequency table is a simple way to display the number of occurrences of a particular value or characteristic.
+
+A frequency distribution is a table showing each distinct value of some variable and the number of times it occurs in some dataset.
+
+Frequency distribution helps us:
+* to analyze the data
+* to estimate the frequencies of the population on the basis of the ample
+* to facilitate the computation of various statistical measures
+
+A **relative frequency distribution**s is a distribution in which relative frequencies are recorded against each class interval.
+
+# Tables.
+
+Tables can show either **categorical variables** (sometimes called qualitative variables) or **quantitative variables** (sometimes called numeric variables). You
+can think of categorical variables as being categories (like eye color or brand of dog food) and quantitative variables as being numbers.
+
+# Histogram and Bar graph.
+
diff --git a/udacity-data-foundations-nd/README.md b/udacity-data-foundations-nd/README.md
new file mode 100644
index 0000000..c259df5
--- /dev/null
+++ b/udacity-data-foundations-nd/README.md
@@ -0,0 +1,3 @@
+Udacity Data Foundations Nanodegree Program
+
+Projects and Notes:
diff --git a/udacity-data-foundations-nd/box_plot.png b/udacity-data-foundations-nd/box_plot.png
new file mode 100644
index 0000000..91db3e0
Binary files /dev/null and b/udacity-data-foundations-nd/box_plot.png differ
diff --git a/udacity-data-foundations-nd/box_plot_quiz.png b/udacity-data-foundations-nd/box_plot_quiz.png
new file mode 100644
index 0000000..f766b9b
Binary files /dev/null and b/udacity-data-foundations-nd/box_plot_quiz.png differ
diff --git a/udacity-data-foundations-nd/histogram.png b/udacity-data-foundations-nd/histogram.png
new file mode 100644
index 0000000..d8b8dfe
Binary files /dev/null and b/udacity-data-foundations-nd/histogram.png differ
diff --git a/udacity-data-foundations-nd/lesson_1.md b/udacity-data-foundations-nd/lesson_1.md
new file mode 100644
index 0000000..a687653
--- /dev/null
+++ b/udacity-data-foundations-nd/lesson_1.md
@@ -0,0 +1,6 @@
+## Data Foundations Road Map
+
+1. Descriptive Statistics
+2. Spreadsheets using Exel
+3. Using Databases and SQL
+4. Dashboards using Tableau
\ No newline at end of file
diff --git a/udacity-data-foundations-nd/lesson_2.md b/udacity-data-foundations-nd/lesson_2.md
new file mode 100644
index 0000000..5db1ce3
--- /dev/null
+++ b/udacity-data-foundations-nd/lesson_2.md
@@ -0,0 +1,104 @@
+## Descriptive Statistics Part 1
+
+The world "data" is defined as disctinct piece of information. Dtata can come in many forms: text, video, spreadsheets, images, audio and other forms.
+
+#### Data Types
+
+**Quantitative** data takes on numeric values that allow us to perform mathematical operations (age, height, income, number of pages in a book).
+
+**Quantitative** data types can be devided into: Continuous data type and Discrete data type.
+**Continuous** quantitative values that can be split into smaller values. For example: the age, we can split age into smaller units, like years, month, days, hours, min, sec but there are still smaller units that could be associated with the age. Continuous data can take any numeric value including decimal values and sometimes even negative numbers.
+**Discrete** data only takes on countable values.
+
+**Categorical** data types are used to label a group or set of items (zip code, marital status, letter grades, rating on a survey( Poor, Og, Great), gender, breakfast type).
+
+**Categorical** data types can be devided further into: Ordinal data type and Nominal data type.
+**Ordinal** categorical values that are ranked (like scale from Very positive to Very negative).
+**Nominal** categorical values that do not have ranked order (like the breeds of the dog).
+
+##### Continuous vs. Discrete
+
+To consider if we have continuous or discrete data, we should see if we can split our data into smaller and smaller units. Consider time - we could measure an event in years, months, days, min, sec and there're still smaller units we could measure time in. Therefore, we know this data type is continuous. And number of pages in a book or roses in a garden are discrete type.
+
+##### Ordinal vs. Nominal
+
+Nominal data like Gender, Zip code, Martial status don't have order ranking associated with this type of data.
+Alternatively, the Letter grade (A, B, C; D)) or Surveq Ratings (Good, Ok) have a rank ordering associated with it, as Ordinal date.
+
+
+
+## Measures of Center (Mean)
+
+Analyzing **discrete** and **continuous** quantitative data, generally discuss four main aspects:
+- Measures of Center
+- Measures of Spread
+- The Shape of the data
+- Outliers
+
+**Categorical** data is analyzed usually be looking at the counts or proportion of individuals that fall into each group. For example if we were looking at the breeds of the dogs, we would care about how many dogs are of each breed, or what proportion of dogs are of each breed type.
+
+##### Measures of Center
+
+There're three measures of center:
+1. Mean
+2. Median
+3. Mode
+
+**Mean** or **average** or the **expected value** sum of all values divided by the number of values in our dataset.
+
+**Median** it is the middle value of a data set. The median splits our data so that 50% of our values are lower and 50% are higher. To calculate the median depends on if the middle value is an even number or an odd number. In order to compute the median we MUST sort our values first.
+
+Median for Odd Values
+If we have an odd number of observations, the median is simply the number in the direct middle.
+
+Median for Even Values
+If we have an even number of observations, the median is the average of the two values in the middle.
+
+**Mode** the most frequent number in a data set. There might be multiple modes for a particular dataset, or no mode at all.
+
+## Random Variable
+
+**Random Variable** is a placeholder for the possible values of some process. Random variables represented by capital letters (X, Y, or Z are common ways to represent a random variable).
+
+## Capital vs. Lower
+
+**Random variables** are represented by capital letters.
+For example:
+
+`X = amount of time on website` where X is an entire set of possible values. Think about X as a placeholder for any of these possible values. Once we observe an outcome of these random variables, we notate it as a lower case of the same letter. Often the lower case letter has a subscript xn, that helps attach notation to each specific value in dataset. X is the amount of time an individual spends on the website.
+
+Example:
+What is the probability someone spends more than 20 minutes in our website?
+
+In notation, we would write:
+
+P(X > 20)?
+
+Here P stands for probability, while the parentheses encompass the statement for which we would like to find the probability. Since X represents the amount of time spent on the website, this notation represents the probability the amount of time on the website is greater than 20.
+
+We could find this in the above example by noticing that only one of the 5 observations exceeds 20. So, we would say there is a 1 (the 45) in 5 or 20% chance that an individual spends more than 20 minutes on our website (based on this dataset).
+
+## Summation
+
+An **aggregation** is a way to turn multiple numbers into fewer numbers (commonly one number).
+
+**Summation** is a common aggregation. The notation used to sum our values is a greek symbol called **sigma**
+ or Σ. Instead of writing multiüle x values, each with a different subscript, you can write sigma x with a sibscript i: `Σxi` where i is a placeholder that tells which x values we'll be summing up.
+
+Example:
+`i = 1` start point
+number 2 is an ending point
+In orifinal notation this example looks like: Σ = x1 + x2
+
+
+
+**n** above the Σ - means the total number of values in dataset. We can use this notation both at the top of our summation, as well as for the value that we divide by when calculating the mean.
+
+**Mean** calculating formula:
+
+Sum all of the values in the data set and then devided by the number of values in the data set 1/n.
+
+
+
+### Summary on Notation
+
diff --git a/udacity-data-foundations-nd/lesson_2_descriptive_statistics_1.md b/udacity-data-foundations-nd/lesson_2_descriptive_statistics_1.md
new file mode 100644
index 0000000..394c713
--- /dev/null
+++ b/udacity-data-foundations-nd/lesson_2_descriptive_statistics_1.md
@@ -0,0 +1,104 @@
+## Descriptive Statistics 1
+
+The world "data" is defined as disctinct piece of information. Dtata can come in many forms: text, video, spreadsheets, images, audio and other forms.
+
+#### Data Types
+
+**Quantitative** data takes on numeric values that allow us to perform mathematical operations (age, height, income, number of pages in a book).
+
+**Quantitative** data types can be devided into: Continuous data type and Discrete data type.
+**Continuous** quantitative values that can be split into smaller values. For example: the age, we can split age into smaller units, like years, month, days, hours, min, sec but there are still smaller units that could be associated with the age. Continuous data can take any numeric value including decimal values and sometimes even negative numbers.
+**Discrete** data only takes on countable values.
+
+**Categorical** data types are used to label a group or set of items (zip code, marital status, letter grades, rating on a survey( Poor, Og, Great), gender, breakfast type).
+
+**Categorical** data types can be devided further into: Ordinal data type and Nominal data type.
+**Ordinal** categorical values that are ranked (like scale from Very positive to Very negative).
+**Nominal** categorical values that do not have ranked order (like the breeds of the dog).
+
+##### Continuous vs. Discrete
+
+To consider if we have continuous or discrete data, we should see if we can split our data into smaller and smaller units. Consider time - we could measure an event in years, months, days, min, sec and there're still smaller units we could measure time in. Therefore, we know this data type is continuous. And number of pages in a book or roses in a garden are discrete type.
+
+##### Ordinal vs. Nominal
+
+Nominal data like Gender, Zip code, Martial status don't have order ranking associated with this type of data.
+Alternatively, the Letter grade (A, B, C; D)) or Surveq Ratings (Good, Ok) have a rank ordering associated with it, as Ordinal date.
+
+
+
+## Measures of Center (Mean)
+
+Analyzing **discrete** and **continuous** quantitative data, generally discuss four main aspects:
+- Measures of Center
+- Measures of Spread
+- The Shape of the data
+- Outliers
+
+**Categorical** data is analyzed usually be looking at the counts or proportion of individuals that fall into each group. For example if we were looking at the breeds of the dogs, we would care about how many dogs are of each breed, or what proportion of dogs are of each breed type.
+
+##### Measures of Center
+
+There're three measures of center:
+1. Mean
+2. Median
+3. Mode
+
+**Mean** or **average** or the **expected value** sum of all values divided by the number of values in our dataset.
+
+**Median** it is the middle value of a data set. The median splits our data so that 50% of our values are lower and 50% are higher. To calculate the median depends on if the middle value is an even number or an odd number. In order to compute the median we MUST sort our values first.
+
+Median for Odd Values
+If we have an odd number of observations, the median is simply the number in the direct middle.
+
+Median for Even Values
+If we have an even number of observations, the median is the average of the two values in the middle.
+
+**Mode** the most frequent number in a data set. There might be multiple modes for a particular dataset, or no mode at all.
+
+## Random Variable
+
+**Random Variable** is a placeholder for the possible values of some process. Random variables represented by capital letters (X, Y, or Z are common ways to represent a random variable).
+
+## Capital vs. Lower
+
+**Random variables** are represented by capital letters.
+For example:
+
+`X = amount of time on website` where X is an entire set of possible values. Think about X as a placeholder for any of these possible values. Once we observe an outcome of these random variables, we notate it as a lower case of the same letter. Often the lower case letter has a subscript xn, that helps attach notation to each specific value in dataset. X is the amount of time an individual spends on the website.
+
+Example:
+What is the probability someone spends more than 20 minutes in our website?
+
+In notation, we would write:
+
+P(X > 20)?
+
+Here P stands for probability, while the parentheses encompass the statement for which we would like to find the probability. Since X represents the amount of time spent on the website, this notation represents the probability the amount of time on the website is greater than 20.
+
+We could find this in the above example by noticing that only one of the 5 observations exceeds 20. So, we would say there is a 1 (the 45) in 5 or 20% chance that an individual spends more than 20 minutes on our website (based on this dataset).
+
+## Summation
+
+An **aggregation** is a way to turn multiple numbers into fewer numbers (commonly one number).
+
+**Summation** is a common aggregation. The notation used to sum our values is a greek symbol called **sigma**
+ or Σ. Instead of writing multiüle x values, each with a different subscript, you can write sigma x with a sibscript i: `Σxi` where i is a placeholder that tells which x values we'll be summing up.
+
+Example:
+`i = 1` start point
+number 2 is an ending point
+In orifinal notation this example looks like: Σ = x1 + x2
+
+
+
+**n** above the Σ - means the total number of values in dataset. We can use this notation both at the top of our summation, as well as for the value that we divide by when calculating the mean.
+
+**Mean** calculating formula:
+
+Sum all of the values in the data set and then devided by the number of values in the data set 1/n.
+
+
+
+### Summary on Notation
+
diff --git a/udacity-data-foundations-nd/lesson_2_descriptive_statistics_2.md b/udacity-data-foundations-nd/lesson_2_descriptive_statistics_2.md
new file mode 100644
index 0000000..c32fe3f
--- /dev/null
+++ b/udacity-data-foundations-nd/lesson_2_descriptive_statistics_2.md
@@ -0,0 +1,209 @@
+## Descriptive Statistics Part 2
+
+#### Measures of Spread
+
+**Measures of Spread** mean how far are points from one another or how spread out our data are from one another. Common measures of spread include:
+
+1. Range
+2. Interquartile Range (IQR)
+3. Standard Deviation
+4. Variance
+
+#### Histogram
+
+Histogram the most common visual for quantitative data.
+
+Histogram and bins:
+
+
+
+#### Introduction to Five Number Summary
+
+Five Number Summary consist of:
+
+1. **Minimum**: The smallest number in the dataset.
+2. **Q1**: The value such that 25% of the data fall below.
+3. **Q2** or MEDIAN: The value such that 50% of the data fall below.
+4. **Q4**: The value such that 75% of the data fall below.
+5. **Maximum**: The largest value in the dataset.
+
+Example:
+
+1, 2, 3, 3, 5, 8, 10
+
+Min = 1
+Q1 = 2
+Q2(Median) = 3
+Q3 = 8
+Max = 10
+Range = Max - Min = 9
+IQR = Q3 - Q1 = 6
+
+Example an even set of values:
+
+1, 2, 3, 3, 5, 8, 10, 105
+In order to find Q1 and Q3, we divide our dataset between the two values we use to find the median:
+
+`1, 2, 3, 3` Q1 = 2, 3 = 2.5
+`5, 8, 10, 105` Q3 = 8, 10 = 9
+
+min = 1
+Q1 = 2.5
+Q2(Median) = (3+5)/2 = 4
+Q3 = 9
+max = 105
+Range = 104
+
+**Range**
+The **range** is then calculated as the difference between the maximum and the minimum.
+
+**IQR**
+The interquartile range is calculated as the difference between **Q3** and **Q1**.
+
+#### Box Plot
+
+Box Plot can be useful for quickly comparing the spread of two data sets across some keq metrics like quartiles, max and min.
+
+For datasets that are **not symmetric**, the five number summary and a corresponding box-plot are a great way to get started with understanding the spread of your data.
+
+#### Standard Deviation and Variance
+
+**Standard Deviation** defined as the average distance of each observation from the mean.
+
+#### Standard Deviation Calculation
+
+
+1. Take an average of the sample or x-bar.
+2. Deviation from the mean: xi -x-bar
+3. Square each deviation
+4. Variance is the average squared deviations
+5. Standard deviations is simply the square root of the variance.
+
+Two additional measures of spread that are used all the time are the variance and standard deviation.
+
+#### Recap Standard Deviation and Variance
+
+- Standard Deviations is used to compare spread of different groups to determine which is more spread out.
+
+- When data pertains to money or the economy, having higher standerd deviation is associated with having higher risk.
+
+- In comparing stock prices, a stock price that changes with higher standard deviation over time is considered more risky than a stock price that fluctuates with lower standard deviation.
+
+- Fair comparisons requaire the same units.
+
+- Variance has squared units of the original dataset. The variance is used to compare the spread of two different groups. A set of data with higher variance is more spread out than a dataset with lower variance. Be careful though, there might just be an outlier (or outliers) that is increasing the variance, when most of the data are actually very close.
+
+
+- Standard Deviation is the square root of the variance and shares units with the original dataset.
+
+- If standard Deviation is a zero value, that is mean all of data points are the same value.
+
+
+
+#### Shape
+
+From a histogram we can quickly identify the shape of our data:
+
+1. Right-skewed has median < mean
+2. Left-skewed has mean < median
+3. Symmetric (or Normal Disctribution or Bell Shape Curve) has a mean = madian = mode
+The **mode** of a distribution is essentially the tallest bar in a histogram. There may be multiple modes depending on the number of peaks in our histogram.
+
+Left Skewed is when the graphs starts with a low frequency and then slopes up. Right Skewed is when the graph starts with a high frequency and slopes down.
+
+#### Shape and Outliers
+
+**Outliers** are data points that fall very far from the rest of the values in our dataset.
+
+#### Working with Outliers
+
+Common Techniques
+When outliers are present we should consider the following points.
+
+1. Noting they exist and the impact on summary statistics.
+
+2. If typo - remove or fix
+
+3. Understanding why they exist, and the impact on questions we are trying to answer about our data.
+
+4. Reporting the 5 number summary values is often a better indication than measures like the mean and standard deviation when we have outliers.
+
+5. Be careful in reporting. Know how to ask the right questions.
+
+#### Outliers Advice
+
+ 1. Plot your data to identify if you have outliers.
+ 2. Determine how to handle them. (Fix, remove, keep)
+ 3. If no outliers and your data follow a normal distribution - use the mean and standard deviation to describe your dataset, and report that the data are normally distributed.
+
+**Side note**
+
+If you aren't sure if your data are normally distributed, there are plots called [normal quantile plots](https://data.library.virginia.edu/understanding-q-q-plots/) and statistical methods like the [Kolmogorov-Smirnov test](https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test) that are aimed to help you understand whether or not your data are normally distributed.
+
+4. With Skewed Data the Five Number Summery provides much more info for these data sets than the mean and the standard deviation can provide.
+
+#### More on center and spread
+
+When analyzing skewed data, it is common to report numeric summaries like the median and 5 number summary, as the mean and standard deviation may be misleading.
+
+However, with symmetric data, the mean and standard deviation are commonly used, as we can understand what proportion of points might fall 1, 2, or 3 standard deviations away based on the empirical rule associated with normal distributions.
+
+
+
+Standard Deviation and Skewed Distributions
+Standard Deviations can be calculated for any data set, whether it is normally distributed or skewed.
+
+### Recap
+
+**Quantitative Variables**
+Then we learned there are four main aspects used to describe quantitative variables:
+
+1. Measures of Center
+2. Measures of Spread
+3. Shape of the Distribution
+4. Outliers
+
+**Measures of Center**
+We looked at calculating measures of Center
+
+1. Means
+2. Medians
+3. Modes
+
+**Measures of Spread**
+We also looked at calculating measures of Spread
+
+1. Range
+2. Interquartile Range
+3. Standard Deviation
+4. Variance
+
+**Shape**
+We learned that the distribution of our data is frequently associated with one of the three shapes:
+
+1. Right-skewed
+
+2. Left-skewed
+
+3. Symmetric (frequently normally distributed)
+
+Depending on the shape associated with our dataset, certain measures of center or spread may be better for summarizing our dataset.
+
+When we have data that follows a normal distribution, we can completely understand our dataset using the mean and standard deviation.
+
+However, if our dataset is skewed, the 5 number summary (and measures of center associated with it) might be better to summarize our dataset.
+
+## Descriptive vs. Inferential Statistics
+
+**Discriptive Statistics** is about describing collected data.
+
+**Inferential Statistics** is about using collected data to draw conclusions to a larger population based on data collected from a **sample of individuals from that population**.
+
+1. Population - our entire group of interest. (100.000 students)
+2. Parameter - numeric summary about a population (Proportion of all 100.00 students that drink coffe)
+3. Sample - subset of the population (5000 students)
+4. Statistic numeric summary about a sample (73%)
+5. Inference drawing conclusions regarding a population using information from a sample.
+
+A common way to collect data is via a survey. However, surveys may be extremely biased depending on the types of questions that are asked, and the way the questions are asked.
+
diff --git a/udacity-data-foundations-nd/lesson_4_spreadsheets.md b/udacity-data-foundations-nd/lesson_4_spreadsheets.md
new file mode 100644
index 0000000..127d8f9
--- /dev/null
+++ b/udacity-data-foundations-nd/lesson_4_spreadsheets.md
@@ -0,0 +1,89 @@
+## Basic Terms in Excel
+
+1. **Formulas**
+In Excel, a formula is an expression that operates on values in a range of cells or a cell.
+
+2. **Functions**
+Functions are predefined formulas in Excel.
+
+Example:
+
+=SUM(B1:C1) – A simple selection that sums the values of a row.
+
+=SUM(A1:A10) – A simple selection that sums the values of a column.
+
+=SUM(A3:A7, A9, A12:A15) – A sophisticated collection that sums values from range A2 to A7, skips A8, adds A9, jumps A10 and A11, then finally adds from A12 to A15.
+
+=SUM(A1:A10)/20 – Shows you can also turn your function into a formula.
+
+
+#### Functions:
+
+**TRIM**
+
+The TRIM function makes sure your functions do not return errors due to unruly spaces. It ensures that all empty spaces are eliminated.
+
+**MAX & MIN**
+The MAX and MIN functions help in finding the maximum number and the minimum number in a pull of values.
+
+**LEN**
+If you want to count the number of characters in a single cell, including white spaces.
+
+**CONCATENATE**
+
+Concatenate gives a way to combine a list of text items from multiple cells.
+
+Example:
+=CONCATEBATE(B2, "", A1, "lives in", C2 ".")
+Output==> Name Surname lives in City.
+
+To avoid extra empty spaces use TRIM with CONCATENATE:
+=trim(CONCATEBATE(B2, "", A1, "lives in", C2 "."))
+
+**PROPER**
+
+To ensure that names and places are properly capitylized.
+
+**UPPER**
+
+UPPER makes all letters upper case.
+
+**LOWER**
+
+Makes all letters lower case.
+
+#### Math Functions:
+
+There are two kinds of arithmetic operations in spreadsheets those done with arithmetic operators and those that use functions.
+
+Arithmetic operators:
+- addition: =add()
+- substraction: =substruct()
+- multiplication: =multiply()
+- division: =divide()
+
+**Statistical Functions**:
+
+A couple of very useful statistical functions:
+=sum()
+=average()
+
+#### Duplicate Rows
+
+Tabel level data operations are useful for cleaning manipulating lists of data.
+When clean data, we're trying to rid it of corrupt and inaccurate data items.
+
+**Google Sheets Instructions**
+
+If you are using Google Sheets as your spreadsheet application, there is an add-on named [Remove Duplicates](https://chrome.google.com/webstore/detail/remove-duplicates/bckmhokpcdnhhjldhhfpebhdfipmlbog?hl=en) that makes this a very easy operation. Once you install the add-on, remove duplicates by highlighting the columns and selecting.
+`Add-ons->Remove Duplicates`
+
+#### Split Columns
+To split column se text to columns tool.
+
+If work with larger data sets, its can be helpful to "freeze" the header row or far left column as you scroll through data. To do this, use the View->Freeze Panes operation in Excel or View->Freeze in Google Sheets to select the rows or columns you want to always be visible.
+
+
+#### Filter Data
+
+Fiktering data is a way to group data by selecting characteristics from our data columns and not looking at the other data.
\ No newline at end of file
diff --git a/udacity-data-foundations-nd/lesson_5_analyze_data_sdpreadsheets.md b/udacity-data-foundations-nd/lesson_5_analyze_data_sdpreadsheets.md
new file mode 100644
index 0000000..d85588f
--- /dev/null
+++ b/udacity-data-foundations-nd/lesson_5_analyze_data_sdpreadsheets.md
@@ -0,0 +1,75 @@
+#### Aggregation Functions
+
+=sum() is an aggregetion function that operates across a group of data resulting in a single value.
+
+More aggregation functions:
+
+average(), max(), min(), median(), stdev() or standard deviation, median() or middle value.
+
+#### Logical Functions: **IF**
+
+Conditional functions and spreadsheets are part of the logical functions group.
+
+Exxample:
+
+`=if(condition, value if TRUE, [value if FALSE])` parameters can be constans or call references or other functions.
+
+Comparison operators (<, >, =, >=, <=, <> or not equal) are used in logic statements to compare two values. Any of these comparison operators can be used to create a True or False condition.
+
+
+#### Logical Functions: AND, OR, NOT.
+
+AND like IF is a function not an operator.
+`(AND(condition1, condition2, ...)` AND is TRUE if all of its conditions are TRUE.
+
+To use AND with an IF statement, nest it inside the IF function:
+`=IF(AND(condition1, condition2, ...),
+ value if TRUE,[value if FALSE])`
+
+`OR` TRUE if any conditions is TRUE.
+
+`NOT` reverses TRUE and FALSE logic.
+
+Example: `=IF(OR(MAX(B2:D2)>10,E2>20),"Special Order","No")`
+
+#### Conditional Aggregation Function
+
+Function that operates across a group of data with logical contitions.
+
+`=countif(range, criteria)`
+=countif(D2:D20,"=Pitcher")
+=countif(C2:C20,">200000")
+
+`=sumif()` works similarly but adds values if the criteria is True rather than counting:
+=sumif(C2:C20,">200000") => returns a sum of all numbers greater than 200000.
+
+#### Pivot Tables
+
+Pivot Tables summarize an aggregate all in one step.
+
+Pivot Tables useful for quickly analyzing data in different ways without worry about selecting the right columns, ranges,
+
+#### Named Ranges
+
+The simplest way to name a cell or range is to select the cell or range and then go to the formula meny and click define name. We can identify some single values by name range or cell that we going to use in formulas.
+
+#### Lookup Function
+
+Lookup functions is a function that uses a keyword and index to "look up" a value in a table.
+Use named range for lookup tables to reduce errors!
+
+There are horizontal and vertical lookup functions:
+`=vlookup(lookup_value, data range)`
+Example:
+=vlookup(A2,Airports!A:B,2,false)
+
+#### **Calc VLOOKUP**
+
+Syntax:
+VLOOKUP(lookupvalue; datatable; columnindex; mode)
+
+lookupvalue is a value (number, text or logical value) to look up in the left column of the range/array datatable. When a value is matched in the left column, VLOOKUP returns the corresponding value (in the same row) in the columnindexth column of datatable, where columnindex = 1 is the left column.
+
+If mode is 0 or FALSE, the left column of datatable may be unordered, and the first exact match is found (searching from the top).
+
+If mode is 1 or TRUE, or is omitted, the left column of datatable must be sorted, with numbers in ascending order appearing before text values in alphabetic order. VLOOKUP decides where in the left column lookupvalue would appear. If there is an exact match, that is the row found; if there is more than one exact match, the row found is not necessarily nearest the top. If there is no exact match, the row above where value would appear in the left column is found; the #N/A error results if that row is not in the table.
diff --git a/udacity-data-foundations-nd/lesson_6_visualize_data_spreadsheets.md b/udacity-data-foundations-nd/lesson_6_visualize_data_spreadsheets.md
new file mode 100644
index 0000000..62a84f6
--- /dev/null
+++ b/udacity-data-foundations-nd/lesson_6_visualize_data_spreadsheets.md
@@ -0,0 +1,94 @@
+When looking at the date as a picture, it's easier to notice patterns, like spot trends to examine more closely.
+
+#### Pie Charts
+
+A pie charts is used to illustrate proportionality. Think of it as slicing the pie into pieces, where each piece matches a percentage of the whole list.
+
+To create a pie chart in spreadsheets we need is a list of the categories and matching values such as sums or counts.
+
+Use a pie chart to show proportionality of categories.
+
+#### Bar Charts
+
+Use a bar or column charts to compare category values with each other.
+
+#### Scatter and Line Plots
+
+Use **pie** and **bar sharts** to visualize **categorical data**.
+
+**Line charts** visualize numerical data, such as the list of stock prices over time, a line chart gives a better picture of the data set.
+
+**Scatter plots** are useful for displaying **bivariate numerical data**. This means a data set with two variables, such as height and weight measurements for a list of human beings.
+
+If the data of both variables moves up together, they have a positive **correlation**.
+
+The "trend line", which can be added in Excel by selecting the scatter chart, then Design->Add Chart Element->Trendline->Linear.
+
+If one variable increases as the other decreases, the two variables have a **negative correlation**.
+
+Quizz: Chart Types
+
+- What are the relative percentages of different fruits sold this month? ==> Pie Chart
+
+- How do the number of apples, oranges and pears sold this month compare to each other? ==> Bar Chart
+
+- How has the price for AAPL stock changed over time? ==> Line Chart
+
+- Is there a relationship I can see between weight and age in a population? ==> Scatter
+
+- What is the frequency of salaries by millions across all major league baseball players? ==> Histigram
+
+- What is the distribution of my numerical dataset from minimum to maximum, including the 1st, 2nd, and 3rd quartiles? ==> Box Plot
+
+#### Histogram
+
+Histogram a column chart thet measures the frequency of data in a data set and specifically groups numerical values into bins.
+
+Use Analysis ToolPak Add-in on Mac.
+
+**Histograms** and **Bar (or Column) charts** are easily confused. **Histograms** plot distributions of **quantitative (numerical) data**. Numerical ranges of the data are grouped into bins and charted. **Bar* or **column* charts plot counts of **categorical data**.
+
+#### Box Plot
+
+Box plot is the visualization of statistical spread in a data set of values. A traditional box plot is built using the **five numbers summary**. The five number summery consists of five values:
+1. Minimum becomes the tip of lower whisker.
+2. Maximum becomes the tip of upper whisker.
+3. First Quartile
+4. Median or Second Quartile
+5. Third Quartile
+The box represents the miiddle half of the data with a line where the median is.
+
+
+Exel has six number in the summary: mean or average value of the set.
+
+A box plot represents statistics for a single list of numbers. Each list you select will be represented by its own box plot. The box plot gives visual sense of the spread of the value list.
+
+[Create a box and whisker chart
+](https://support.office.com/en-us/article/Create-a-box-and-whisker-chart-62f4219f-db4b-4754-aca8-4743f6190f0d#OfficeVersion=Mac)
+
+Box Plot Quiz:
+
+Box and Whisker Plots give us a visualization of statistical spread using the "5 Number Summary". Excel even provides a 6th number visualization as a bonus.
+
+
+
+Min => F
+Max => C
+Median => E
+Mean => B
+1st Quartile => A
+2d Quartile => E
+3d Quartile => D
+
+#### Professional Presentations
+
+When presenting data think about:
+- What questions are you answering?
+- What patterns trying to show?
+- Who is the audience?
+- Overview or in-depth? Is this a quick overview on a slide with the data backup elsewhere or is it a written technical review where more in-depth data should be presented?
+
+If there are more than one data series you need to add **Legend**. But if the labels are already showing up in the data as in the pie chart, then an extra legend no necessary.
+
+For graph: do you need or want grid lines? In a detailed technical presentation, it is easier to see the values if there are grid lines. For quick ovewiews that are just emphasizing the trend those extra lines look busy.
+
diff --git a/udacity-data-foundations-nd/mean.png b/udacity-data-foundations-nd/mean.png
new file mode 100644
index 0000000..f49b869
Binary files /dev/null and b/udacity-data-foundations-nd/mean.png differ
diff --git a/udacity-data-foundations-nd/normal_distribution.png b/udacity-data-foundations-nd/normal_distribution.png
new file mode 100644
index 0000000..6d633d3
Binary files /dev/null and b/udacity-data-foundations-nd/normal_distribution.png differ
diff --git a/udacity-data-foundations-nd/notation_sum.png b/udacity-data-foundations-nd/notation_sum.png
new file mode 100644
index 0000000..1634924
Binary files /dev/null and b/udacity-data-foundations-nd/notation_sum.png differ
diff --git a/udacity-data-foundations-nd/sd.png b/udacity-data-foundations-nd/sd.png
new file mode 100644
index 0000000..0414860
Binary files /dev/null and b/udacity-data-foundations-nd/sd.png differ
diff --git a/udacity-data-foundations-nd/sum.png b/udacity-data-foundations-nd/sum.png
new file mode 100644
index 0000000..a7b6a3d
Binary files /dev/null and b/udacity-data-foundations-nd/sum.png differ
diff --git a/url.txt b/url.txt
deleted file mode 100644
index 1a12824..0000000
--- a/url.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-https://stackoverflow.com/questions/31804799/how-to-get-pdf-filename-with-python-requests
-https://github.com/requests/requests
-https://docs.python.org/3/howto/regex.html
\ No newline at end of file
diff --git a/url_input.py b/url_input.py
deleted file mode 100644
index e8a6e10..0000000
--- a/url_input.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import requests
-
-
-def fetch_save_url(url, file_name):
- '''
- Takes an url as an input, downloads a page and stores it in the file.
- '''
-
- try:
- response = requests.get(url, timeout=1)
-
- except Exception as e:
-
- print('Error!', e)
- return
-
- if response.status_code == 200:
-
- with open(file_name, 'w') as file:
- file.write(response.text)
- print('ok!')
- else:
- print('Error, status code =', response.status_code)
-
-if __name__ == '__main__':
-
-
- # Test cases
-
- # Successful
- fetch_save_url('https://github.com/requests/requests', 'request.html')
-
- # Non URL
- fetch_save_url('lll', 'request.html')
-
- # Wrong URL
- fetch_save_url('https://github.co/requests/requests', 'request.html')
-
- # Non existing page
- fetch_save_url('https://github.com/aj3,o', 'request.html')
-