# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
import seaborn as sns

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
data = pd.read_csv('/kaggle/input/global-co2-emissions/CO2Emission_LifeExp.csv')
data.head()
"""

Country: Unique Identifier

Code: Country Code

CO2Emissions: CO2 Emission by country (tons, 2016)

YearlyChange: Yearly CO2 Emission Change in Percentage

Percapita: CO2 Emission Per Capita

Population: Population of the Country (2016)

LifeExpectancy: Life Expectancy of the Country (2016)


"""
"""
# Python Tool Box
"""
def tuple_a(): # define tuple
    t = (3,6,9)
    return t

a,b,c = tuple_a() # a = 3, b = 6, c = 9
print(a,b,c)
"""
**SCOPE**

global: defined main body in script

local: defined in a function
"""
x = 12 # global
def f():
    x = 13
    return x # local

print(x) # x = 12

print(f()) # x = 13
x = 20
def f():
    y = 2*x  # there is no local scope x
    return y
print(f()) # it uses global scope x  
import builtins # built in scope
dir(builtins)
"""
**NESTED FUNCTION**


function inside function.
"""
#nested function

def square():
    
    def add():
        
        x = 6      # local
        y = 8      # local
        z = x + y
        return z   # retrun z
    return add()**3
print(square())
"""
**DEFAULT and FLEXIBLE ARGUMENTS**

Default argument example:

def f(a, b=1):     --> b = 1 is default argument

Flexible argument example:

def f(*args):     --> *args can be one or more

def f(** kwargs):    --> kwargs is a dictionary




"""
def f(a, b=3, c=5):
    y = a+b+c
    return y
print(f(8))

# 8 + 3 + 5
# flexible args-1
def f(*args):
    for i in args:
        print(i)
        
f(100)
# flexible args-2,  for lists
def f(*args):
    for i in args:
        print(i)
        
f(50,100,150,200)
def f(**kwargs):
    for key, value in kwargs.items():              
        print(key, " ", value)
f(war_plane = 'f22', feature = 'raptor', speed = '2414')
"""
**LAMBDA FUNCTION**
"""
#LAMBDA FUNCTION

square = lambda x : x ** 3
print(square(4))

tot = lambda  x,y,z : x*y*z
print(tot(1,2,3))
"""
**ANONYMOUS FUNCTİON**
"""
number_list = [5,10,15]
y = map(lambda x:x**3, number_list)
print(list(y))
"""
**ITERATORS**
"""
# iteration example
name = "blue"
it = iter(name)
print(next(it))    # print next iteration
print(*it) 
list_1 = [1,2,3,4]
list_2 = [5,6,7,8]
z = zip(list_1, list_2)
print(z)
z_list = list(z)
print(z_list)
"""
**LIST COMPREHENSİON**
"""
# Example of list comprehension
num1 = [20,40,60]
num2 = [i + 1 for i in num1 ]
print(num2)
# Conditionals on iterable
num1 = [100,191,200]
num2 = [i**2 if i == 100 else i-5 if i > 100 else i+5 for i in num1]
print(num2)
num1 = np.random.randint(0,100,5)
num2 = [i*0 if i% 2 == 0 else i**3 for i in num1]
num2
treshold = sum(data.CO2Emissions)/ len(data.CO2Emissions)
print("treshold",treshold)
data["co2_value"] = ["high" if i > treshold else "low" for i in data.CO2Emissions]
data.loc[:10,["co2_value", "CO2Emissions"]]

life = sum(data.LifeExpectancy)/ len(data.LifeExpectancy)
print("av_life : ",life)
data["av_life"] = ["high" if i > life else "low" for i in data.LifeExpectancy]
data.loc[:20,["av_life", "LifeExpectancy", "Country"]]