print (type(3), 3) # integer
print (type(2.5), 2.5) # float
print (type('apples'), 'apples') # string
print (type(True), True) # boolean
print (type('3'), '3') # string
print (type('2.5'), '2.5') # string

"""
Explanation: DataTypes
Primitive Types

Numbers
int - integers which are whole numbers such as 3
float - floats which are numbers that have a decimal place such as -3.4
Logical
bool - booleans are either True or False
Text Sequence
str - strings are a sequence of characters such as 'bananas'

More complex Types (These are discussed later in the course)

Sequence Types
list
tuple
range
...
Sets
Dictionaries
Functions
Classes/User Defined Types
...

python
print (type(3), 3) # integer
print (type(2.5), 2.5) # float
print (type('apples'), 'apples') # string
print (type(True), True) # boolean
print (type('3'), '3') # string
print (type('2.5'), '2.5') # string
End of explanation
"""


print ('1 + 2 = ', 1 + 2) # Addition
print ('2 - 1 = ', 2 - 1) # Subtraction
print ('2 * 5 = ', 2 * 5) # Multiplication
print ('6 / 2 = ', 6 / 2) # Division
print ('7 // 3.5 = ', 7 // 2) # Floor/Integer division
print ('2 ** 3 = ', 2 ** 3) # Exponent
print ('16 % 3 = ', 16 % 3) # Division
print ('(1 + 3) * (4 + 5) = ', (1 + 3) * (4 + 5)) # parenthesis
print ('1 + 3 * 4 + 5 = ', 1 + 3 * 4 + 5) # PEMDAS
print("there are {} apples".format(5 + 6 // 2))

"""
Explanation: Pound sign (#) Hash to some, number sign to others
The # symbol allows you to write notes in your program. These are called comments.
python
print (3) # this is a comment

Operations
Each datatype has a number of operations that are valid.
Here are some commmon operators, more will be covered as we progress in the course.
Mathematical Operators ( for numeric types)

() - Parenthesis are used to define the order of operation
** - Exponent : x<sup>n</sup> = x**n 
* - Multiplacation : 5 * 3
/ - Division : 15 / 3
// - Floor/Integer Division (rounds down to the nearest int) : 7 // 3 = 2
+ - Addition : 5 + 3
- - Subtraction : 3 - 5
% - Modulus (returns the remainder of a division) : 16 % 3

```python
print ('1 + 2 = ', 1 + 2) # Addition
print ('2 - 1 = ', 2 - 1) # Subtraction
print ('2 * 5 = ', 2 * 5) # Multiplication
print ('6 / 2 = ', 6 / 2) # Division
print ('7 // 2 = ', 7 // 2) # Floor/Integer division
print ('2  3 = ', 2  3) # Exponent
print ('16 % 3 = ', 16 % 3) # Division
print ('(1 + 3) * (4 + 5) = ', (1 + 3) * (4 + 5)) # parenthesis
print ('1 + 3 * 4 + 5 = ', 1 + 3 * 4 + 5) # PEMDAS
```
Parenthesis can help make statements less ambigous, this is a good thing
End of explanation
"""


print("'Ban' + 'ana' = ", 'Ban' + 'ana')
print("'Ba' * 5 = ", 'Ba' * 5)

"""
Explanation: String Operators

+ - Addition : 'ban' + 'ana' = 'banana'
* - Multiplacation : 'ba' * 5 = 'bababababa'
[x:y:z] - Slicing : 'banana'[0:2] = 'ba'

python
print("'Ban' + 'ana' = ", 'Ban' + 'ana')
print("'Ba' * 5 = ", 'Ba' * 5)
Nesting quotation marks
'"' or "'" will treat the quote inside the other quote as being a character
End of explanation
"""


print("'Banana'.upper() = ", 'Banana'.upper())
print("'banana'.isupper() = ", 'banana'.isupper())
print("'BANANA'.isupper() = ", 'BANANA'.isupper())
print("'124'.isdigit() = ", '124'.isdigit()) # note that this is a string
print("'Banana'.swapcase() = ", 'Banana'.swapcase())

"""
Explanation: String Operations
Everything in Python is an Object (More on this later)

Objects generally have attributes and methods ( more on these later).
Methods are just operations that can be applied to the object
These methods which are accessed using a '.' character

The following code demonstrates a couple of string operators
python
print("'Banana'.upper() = ", 'Banana'.upper())
print("'banana'.isupper() = ", 'banana'.isupper())
print("'BANANA'.isupper() = ", 'BANANA'.isupper())
print("'124'.isdigit() = ", '124'.isdigit()) # note that this is a string
print("'Banana'.swapcase() = ", 'Banana'.swapcase())
End of explanation
"""


help ('banana'.upper)

"""
Explanation: Python Documentation on methods - explain documentation - how to read help
python
help ('banana'.upper)
End of explanation
"""


int_one = 5
int_two = 10
result = int_one + int_two
print (result)

"""
Explanation: Variables
What are they?
Variables allow programs to store data and manipulate it later
python
int_one = 5
int_two = 10
result = int_one + int_two
print (result)
End of explanation
"""


num1 = "5"
if num1.is_digit():
    num1 = int(num1)

print("5" + 5)

"""
Explanation: Be aware
Assignment happens from right to left
python
number = 5 + 1
fruit = 'banana'
variable must be assigned before being used
python
print (unknown_variable)
End of explanation
"""


number = 1   # correct
_number = 1  # correct
!number = 1  # incorrect
number 1 = 1 # incorrect
# 1number = 1  # incorrect

"""
Explanation: Valid Variable Names
Variables can start with a character or underscore
+ variable   &#10003;
+ Variable &#10003;
+ _variable   &#10003;
Variables cannot start with a number or special character
+ 1variable   &#10007;
+ !variable   &#10007;
python
number = 1   # correct
_number = 1  # correct
!number = 1  # incorrect
number 1 = 1 # incorrect
1number = 1  # incorrect
End of explanation
"""


lambda = 5

"""
Explanation: Naming Convensions

b (single lowercase letter)
B (single uppercase letter)
lowercase
UPPERCASE
lowercase_with_underscores (this is the prefered method for python)
UPPERCASE_WITH_UNDERSCORES
CapitalizedWords (also known as CamelCase)
mixedCase (differs from CapitilizedWords as they always starts with a lowercase character)
Capitalized_Words_With_Underscores

Be aware
capital i (I), lowercase l (L) and the number 1 look the same in some fonts,
capital O and 0 also look the same in some fonts
PEP8
This is a style guide which dictates how your code should look.
This helps programs to look similar, which makes them easier to understand for anyone who also uses the styleguide
Here is the link to the PEP8 style guide : https://www.python.org/dev/peps/pep-0008/
Reserved Words
These are words that are used by python and cannot be used as variable names
|Reserved|Words|
|---|---|---|---|---|
|and|del|from|not|while|
|as|elif|global|or|with|
|assert|else|if|pass|yield|
|break|except|import|print|class|
|exec|in|raise|continue|finally|
|is|return|def|for|lambda|
|try|
This will cause an error
python
lambda = 5
End of explanation
"""


numbers = [1,2,3] # this is a list ( more on this later)
print (id(numbers), numbers)
numbers.append(4)
print (id(numbers), numbers) #numbers object is the same

"""
Explanation: Mutability
Some types are immutable.
some functions change the original object, some return a new object
Immutable types
+ str
+ int
+ float
mutable types (more on these later)
+ list
+ dictionary
Immutable example
python
animal = "dog"
print (id(animal), animal)
animal = "cat"
print (id(animal), animal) #animal is a new object, previous one is deleted
Mutable example
python
numbers = [1,2,3] # this is a list ( more on this later)
print (id(numbers), numbers)
numbers.append(4)
print (id(numbers), numbers) #numbers object is the same
End of explanation
"""


x = 5
y = x + 4
print(x, y)

"""
Explanation: String methods do not change the original value. Instead a new string is created by the method
python
fruit = 'banana'
fruit.upper()
print (fruit) # fruit is still lowercase
The return type of a method is shown by the help function.
python
help (fruit.upper)
End of explanation
"""


x = 5
y = 10
print (x,'==',y,'\t:', x == y)
print (x,'!=',y,'\t:', x != y)
print (x,'<',y,' \t:', x < y)
print (x,'>',y,' \t:', x > y)
print (x,'<=',y,'\t:', x <= y)
print (x,'>=',y,'\t:', x >= y)
print (x,'is',y,'\t:', x is y)
print ('type(x == y) : \t', type(x==y))

"""
Explanation: In order to use the result of the string operation we need to store it in a variable
python
fruit = 'banana'
fruit.upper()
print (fruit) # fruit is still lowercase
Variables can be reused, simply assign the result of the operation to the original variable
python
fruit = 'banana'
fruit = fruit.upper() # assign fruit to the result of the upper() method
print ('fruit is now', fruit)

Compound Statements
Control Flow Statements

if else statements - branching operation
repeated execution (covered later)

Conditional Execution
Boolean expressions
A boolean expressions is an expression that will either evaluate to True or False.
|Operator|Expression|Comparison|
|---|---|---|
|==|x == y|is x equal to y?|
|!=|x != y|is x not equal to y?|
|<|x < y|is x less than y?|
|>|x > y|is x greater than y?|
|<=|x <= y|is x less than or equal to y?|
|>=|x >= y|is x greater than or equal to y?|
|is|x is y|is x, y?|
python
x = 5
y = 10
print (x,'==',y,'\t:', x == y)
print (x,'!=',y,'\t:', x != y)
print (x,'&lt;',y,' \t:', x &lt; y)
print (x,'&gt;',y,' \t:', x &gt; y)
print (x,'&lt;=',y,'\t:', x &lt;= y)
print (x,'&gt;=',y,'\t:', x &gt;= y)
print (x,'is',y,'\t:', x is y)
print ('type(x == y) : \t', type(x==y))
End of explanation
"""


num = -6

print ('positive_even :', num)
print ('\tBoolean Expressions')
print ('\t\t', num, '% 2 == 0 \t\t\t:', num%2 == 0)
print ('\t\t', num, '> 0 \t\t\t\t:', num > 0)
print ('\tLogical Expressions')
print ('\t\t', num, '% 2 == 0 and',num,'> 0 \t\t:', num%2 == 0 and num > 0)
print ('\t\t', num, '% 2 == 0 or',num,'> 0 \t\t:', num%2 == 0 or num > 0)

"""
Explanation: Logical Operators
There are three logical operators and, or and not.

and Operator

|x|y|x and y|
|---|---|---|
|False|False|False|
|False|True|False|
|True|False|False|
|True|True|True|

or Operator

|x|y|x or y|
|---|---|---|
|False|False|False|
|False|True|True|
|True|False|True|
|True|True|True|

not Operator

|x|not x|
|---|---|
|False|True|
|True|False|
Example
The following code evaluates 2 boolean expressions

whether the number is even
n%2 == 0
whether the number is positive
n > 0

Using the 2 boolean expressions 2 logical expressions are evaluated

whether the number is even and positive
n%2 == 0 and n > 0
whether the number is even or positive
n%2 == 0 or n > 0

```python
num = 5
print ('positive_even :', num)
print ('\tBoolean Expressions')
print ('\t\t', num, '% 2 == 0 \t\t\t:', num%2 == 0)
print ('\t\t', num, '> 0 \t\t\t\t:', num > 0)
print ('\tLogical Expressions')
print ('\t\t', num, '% 2 == 0 and',num,'> 0 \t\t:', num%2 == 0 and num > 0)
print ('\t\t', num, '% 2 == 0 or',num,'> 0 \t\t:', num%2 == 0 or num > 0)
```
End of explanation
"""


if True:
    print ('Hello') # 4 spaces
    print ('Hello') # 5 spaces

"""
Explanation: Conditional Execution
In order to write usefull programs you need to be able to control which statements are executed. This is achieved using ~if~ statements.
if statements have the following format
python
if &lt;expression&gt;:
    &lt;statement block&gt;

Note that the statement block is indented. This is how Python seperates code that should be executed by the if statement and code that is executed regardless of the statement.
In the following code statement1 and statement2 are only executed if the expressin is true. statement3 will be executed regardless of the if statement.
python
if &lt;expression&gt;:
    statement1
    statement2
statement3
A few word on indentation. Python does not mind how your code is indented as long as it is consistant.
The accepted convention is to use a single tab or 4 whitespaces. But anything will work as long as you are consistant.
python
if True:
    print ('Hello') # 4 spaces
    print ('Hello') # 1 tab (this is bad. Use one of the other)
The following code will result in an error as the spaces are inconsistant
python
if True:
    print ('Hello') # 4 spaces
     print ('Hello') # 5 spaces
End of explanation
"""


disease = True
x = -1
if disease == True:
    if x > 0 and x <= 4:
        print('give drug A')
    elif x > 7 and x <= 10:
        print('give drug B')
    else:
        print('no drug')

"""
Explanation: Alternate execution/Branching
python
if &lt;expression&gt;:
    &lt;statement_1&gt;
else:
    &lt;statement_2&gt;

Multiple tests (chaining)
python
if x &lt; y:
    STATEMENTS_A
elif x &gt; y:
    STATEMENTS_B
else:
    STATEMENTS_C

Nested conditionals
python
if x &lt; y:
    STATEMENTS_A
else:
    if x &gt; y:
        STATEMENTS_B
    else:
        STATEMENTS_C

Example:
python
disease = True
x = 3
if disease == True:
    if x &gt; 0 and x &lt;= 4:
        print 'give drug A'
    elif x &gt; 7 and x &lt;= 10:
        print 'give drug B'
    else:
        print 'no drug'
End of explanation
"""


variable_to_hold_input = input('message to show user : ')
print (type(variable_to_hold_input))

"""
Explanation: User Input
Allows your programs to be dynamic.
Methods
+ input()
+ command line arguments (covered later)
+ reading from files (covered later)
+ ...
input()

This method will create a prompt in the console.
The user can then input their data

Usage
python
variable_to_hold_input = input('message to show user')
print (variable_to_hold_input)
End of explanation
"""


