x = 1
type(x)

"""
Explanation: Built-In Types: Simple Values

Now we will briefly go through the simple built-in Python types
built-in means that these objects are available in Python straight away, no need to import other packages

<center>Python Scalar Types</center>
| Type        | Example        | Description                                                  |
|-------------|----------------|--------------------------------------------------------------|
| int     | x = 1      | integers (i.e., whole numbers)                               |
| float   | x = 1.0    | floating-point numbers (i.e., real numbers)                  |
| complex | x = 1 + 2j | Complex numbers (i.e., numbers with real and imaginary part) |
| bool    | x = True   | Boolean: True/False values                                   |
| str     | x = 'abc'  | String: characters or text                                   |
| NoneType| x = None   | Special object indicating nulls                              |
We'll take a quick look at each of these in turn.
Integers
The most basic numerical type is the integer.
Any number without a decimal point is an integer:
End of explanation
"""


5 / 2

"""
Explanation: Another convenient feature of Python integers is that by default, division up-casts to floating-point type:
End of explanation
"""


x = 0.000005
y = 5e-6
print(x == y)

x = 1400000.00
y = 1.4e6
print(x == y)

"""
Explanation: Floating-Point Numbers
The floating-point type can store fractional numbers.
They can be defined either in standard decimal notation, or in exponential notation:
End of explanation
"""


float(1)

"""
Explanation: In the exponential notation, the e or E can be read "...times ten to the...",
so that 1.4e6 is interpreted as $~1.4 \times 10^6$.
An integer can be explicitly converted to a float with the float constructor:
End of explanation
"""


complex(1, 2)

"""
Explanation: Complex Numbers
Complex numbers are numbers with real and imaginary (floating-point) parts.
We've seen integers and real numbers before; we can use these to construct a complex number:
End of explanation
"""


1 + 2j

"""
Explanation: Alternatively, we can use the "j" suffix in expressions to indicate the imaginary part:
End of explanation
"""


c = 3 + 4j

c.real  # real part

c.imag  # imaginary part

c.conjugate()  # complex conjugate

abs(c)  # magnitude, i.e. sqrt(c.real ** 2 + c.imag ** 2)

"""
Explanation: Complex numbers have a variety of interesting attributes and methods, which we'll briefly demonstrate here:
End of explanation
"""


message = "what do you like?"
response = 'spam'

"""
Explanation: String Type
Strings in Python are created with single or double quotes:
End of explanation
"""


# length of string
len(response)

# Make upper-case. See also str.lower()
response.upper()

# Capitalize. See also str.title()
message.capitalize()

# multiplication is multiple concatenation
5 * response

# concatenation with +
message + response

"""
Explanation: Python has many extremely useful string functions and methods; here are a few of them:
End of explanation
"""


message.split()

"""
Explanation: Q: What does split() method do? What is the result?
End of explanation
"""


notebook_name = '05-Built-in-Scalar-Types.ipynb'

notebook_name.split()

"""
Explanation: Q: Now try to split this notebook's name into words. What argument you have to pass to split()?
End of explanation
"""


l = notebook_name.split('-')
' '.join(l)

"""
Explanation: Q: When you have a sequence of string, you can use join() method:
End of explanation
"""


# Access individual characters (zero-based indexing)
message[0:5]

message[5:11]

message[11:17] # note that spaces count as a character

"""
Explanation: You will know more about lists in Python in the next notebook.
Indexing
End of explanation
"""


# s = "0123456789"
# s[0] = 1

"""
Explanation: Strings are immutable. See for your self:
End of explanation
"""


e = 2.71828182845904590
'{:.4f} is a {}'.format(e, 'float')

"""
Explanation: String formatting

by order
End of explanation
"""


'{a:4.2f} blah-blah {b:05d}'.format(a=3.141516, b=123)

"""
Explanation: by keys
End of explanation
"""


type(None)

"""
Explanation: None Type
Python includes a special type, the NoneType, which has only a single possible value: None. For example:
End of explanation
"""


return_value = print('abc')

print(return_value)

"""
Explanation: You'll see None used in many places, but perhaps most commonly it is used as the default return value of a function.
For example, the print() function in Python 3 does not return anything, but we can still catch its value:
End of explanation
"""


result = (4 < 5)
result

type(result)

"""
Explanation: Boolean Type
The Boolean type is a simple type with two possible values: True and False, and is returned by comparison operators discussed previously:
End of explanation
"""


print(True, False)

"""
Explanation: Keep in mind that the Boolean values are case-sensitive: unlike some other languages, True and False must be capitalized!
End of explanation
"""


