<jupyter_start><jupyter_text>Introduction to Python   [Python Built-in Data Types](https://docs.python.org/3/library/stdtypes.html)![](../Data/Figs/datatypes.png)  What are types?  [Everything in Python is an "Object"](https://towardsdatascience.com/the-most-important-python-concept-that-you-need-to-understand-985b98bbb84). And each type of Object has its own properties.   These properties are called "methods" (a kind of "inner functions")  and "attributes"    Python data types+ Text Type: _str_  + Numeric Types: _int_, _float_, _complex_  + Sequence Types: _list_, _tuple_, _range_  + Mapping Type: _dict_  + Set Types: _set_, _frozenset_  + Boolean Type: _bool_  + Binary Types: _bytes_, _bytearray_, _memoryview_   We can inspect the type of an object typing the command:  + _type(object)_  Through this notebook we will use many ["_bultin_" functions](https://docs.python.org/3/library/functions.html):   + _type_+ _dir_+ _print_+ _len_ And also these [Expressions](https://docs.python.org/3/reference/expressions.html) / [Boolean operators](https://docs.python.org/3/reference/expressions.htmlboolean-operations)+ _or_+ _and_ + _in_ + _not_+ _is_ And more.   We will also use the [type creation / conversion primitives](https://www.tutorialspoint.com/data-type-conversion-in-python):    + _int_+ _float_+ _complex_+ _list_+ _str_+ _dict_+ _bool_+ _tuple_+ _set_ + _chr_+ _ord_ + _ord_+ _chr_+ _hex_+ _bin_+ _oct_   Numeric Types:In Python 3.x, the numeric types are divided in three classes: integers (int), floating point numbers (float) and complex numbers (complex).<jupyter_code>a = 12<jupyter_output><empty_output><jupyter_text>Let's use one of the ["_bultin_" functions](https://docs.python.org/3/library/functions.html) to guess a variable type:<jupyter_code>type(a)
dir(a)
b = 2.7
type(b)<jupyter_output><empty_output><jupyter_text>Let's check the methods using instrospection:<jupyter_code>dir(b)
b.hex()
b.is_integer()  #method that returns True or False, depending if the float being integer (in the mathematical sense)
d = 13.0
type(d)
d.is_integer()
c = 3 + 1j
dir(c)
type(c)
c.conjugate()<jupyter_output><empty_output><jupyter_text>Changing basis<jupyter_code>x = 0x32 # Hex
print(x)
print(type(x))
hex(50)
y = 0b111110001 #Binary
print(y)
bin(497)
z = 0o777321  #Octal
print(z)
oct(261841)<jupyter_output><empty_output><jupyter_text>DiChlorod iPHeny lTrichL oroEThaNe Binary operations _and_ (&) and _or_ (|)<jupyter_code>bin(0b111000 & 0b101010)
bin(0b111000 | 0b101010)<jupyter_output><empty_output><jupyter_text>[Numeric Types Operations](https://docs.python.org/3/library/stdtypes.html) OperationResultNotesFull documentationx + ysum of x and yx - ydifference of x and yx * yproduct of x and yx / yquotient of x and yx // yfloored quotient of x andy(1)x % yremainder of x / y(2)-xx negated+xx unchangedabs(x)absolute value or magnitude ofxabs()int(x)x converted to integer(3)(6)int()float(x)x converted to floating point(4)(6)float()complex(re, im)a complex number with real partre, imaginary part im.im defaults to zero.(6)complex()c.conjugate()conjugate of the complex numbercdivmod(x, y)the pair (x // y, x % y)(2)divmod()pow(x, y)x to the power y(5)pow()x ** yx to the power y(5)<jupyter_code>a = 23.
print(type(a))
b = 2 + 3j
print(type(b))
c = a + b
print(type(c))<jupyter_output><class 'complex'><jupyter_text>Logic Operations  OperationMeaning&lt;strictly less than&lt;=less than or equal&gt;strictly greater than&gt;=greater than or equal==equal!=not equalisobject identityis notnegated object identity<jupyter_code>c = 2.5
d = 4

print(c > d)
type(c > d)
c = 2.5
d = 4

print(c <= d)
c = 1 + 3j
d = 2 + 4j

# print(c > d)  # not supported
print(c == d)
print(d != c)<jupyter_output>True<jupyter_text>Type "list"  [x,y,z]+ Lists are ordered sequences of itens, not necessarily of the same type.  + Lists are created with square brackets, and each item is separated by commas.  + Lists are widely used, and are considered to be a mutable type, i.e. you can change their elements.<jupyter_code>my_list = [1,2,2, [2,3,4], 3.9, 4, 2.8, 'a string']
my_list
dir(my_list)
print(my_list)<jupyter_output>[1, 2, 2, [2, 3, 4], 3.9, 4, 2.8, 'a string']<jupyter_text>Acessing list elements (the first elements has index 0)<jupyter_code>my_list[7]
print(my_list[3])
print(my_list[-1])<jupyter_output>a string<jupyter_text>Slicing<jupyter_code>print(my_list[2:6])
print(my_list[5:])[9, 9]
print(my_list[:3])
my_list[3]
print(my_list[3][2])
print(my_list[-1][-3:])<jupyter_output>ing<jupyter_text>Adding new elements<jupyter_code>my_new_list = [2,6,3,8]
my_new_list.append(23)
print(my_new_list)<jupyter_output>[2, 6, 3, 8, 23]<jupyter_text>Removing elements from a list<jupyter_code>my_new_list.pop()
print(my_new_list)
my_new_list.pop()
print(my_new_list)<jupyter_output>[2, 6, 3]<jupyter_text>Inserting elements (append, extend, insert)<jupyter_code>print(my_new_list)
my_new_list.append(4)
print(my_new_list)
my_new_list.extend([0,7,3])
print(my_new_list)
my_new_list.append([9,9])
my_new_list
my_new_list.insert(2,5678)
print(my_new_list)
my_new_list.pop()
my_new_list.sort() #sorting elements permanently
print(my_new_list)
list_from_string = list('my favorite string')
list_from_string
list_from_string.sort()
print(list_from_string)
list_from_string.count('i')
list_from_string.index('g')
len(list_from_string) #len() returns the size of an object
list_from_string.reverse()
print(list_from_string)<jupyter_output>['y', 'v', 't', 't', 's', 'r', 'r', 'o', 'n', 'm', 'i', 'i', 'g', 'f', 'e', 'a', ' ', ' ']<jupyter_text>Type "String":+ Strings are ordered sequences of the same type (characters).  + Strings are created with single quotes, double quotes and even "triple quotes".  + Strings are used everywhere in information processing, and are considered to be a immutable type, i.e. you cannot change their elements after the creation.  ![](../Data/Figs/notmytype.png)<jupyter_code>s1 = 'a new string'
s2 = "another string"
s3 = 'my string"  #error
print(s1)
type(s1)
dir(s1)
print(s2)
s3 = "let's go to the classroom"  #when to use quotes in a smart way
s3
s4 = 'But what if I have simple quotes (\') e and double quotes(")'
print(s4)
s5 = 'let\'s stress'
print(s5)<jupyter_output>let's stress<jupyter_text>Concatenating strings<jupyter_code>s3 = s1 + ', ' + s2  #operator polimorphism
print(s3)
print('The book' + ' ' + 'is on' + ' ' + 'the table')<jupyter_output>The book is on the table<jupyter_text>Multiline strings<jupyter_code>s6 = "The COVID‑19 pandemic, also known as the coronavirus pandemic, is an ongoing global pandemic \
of coronavirus disease 2019 (COVID‑19), caused by severe acute respiratory syndrome coronavirus 2 \
(SARS‑CoV‑2). The outbreak was first identified in December 2019 in Wuhan, China. The World \
Health Organization declared the outbreak a Public Health Emergency of International Concern on 30 \
January 2020 and a pandemic on 11 March. As of 30 July 2020, more than 17 million cases of COVID‑19\
have been reported in more than 188 countries and territories, resulting in more than 667,000 deaths; \
more than 9.96 million people have recovered."
print(s6)
s6
s7 = '''
The COVID‑19 pandemic, also known as the coronavirus pandemic, is an ongoing global pandemic
of coronavirus disease 2019\t(COVID‑19), caused by severe acute respiratory syndrome coronavirus 2
(SARS‑CoV‑2). The outbreak was first identified in December 2019 in Wuhan, China. The World
Health Organization declared the outbreak a Public Health Emergency of International Concern on 30
January 2020 and a pandemic on 11 March. As of 30 July 2020, more than 17 million cases of COVID‑19
have been reported in more than 188 countries and territories, resulting in more than 667,000 deaths;
more than 9.96 million people have recovered.
'''
print(s7)
s7
s8 = 'one line \nanother line'
print(s8)<jupyter_output>one line 
another line<jupyter_text>How many times an element appear?<jupyter_code>s8.count('o')<jupyter_output><empty_output><jupyter_text>Modifying strings (hint: we have to recreate them)<jupyter_code>s9 = s7.replace('a','@')
print(s9)
s7<jupyter_output><empty_output><jupyter_text>Finding substrings<jupyter_code>print(s7.find('virus'))
print(s4.find('bacteria'))<jupyter_output>-1<jupyter_text>Accessing elements and slicing<jupyter_code>s10 = "A brand new string to play"
s10[6]
s10[12:]
s10[s10.find('string'):s10.find('string')+len('string')]<jupyter_output><empty_output><jupyter_text>A little more elegantly...<jupyter_code>begin = s10.find('string')
end = s10.find('play')+len('play')
s10[begin:end]
c = str(12)
d = '12'
c + d
c.isdigit()
'thirty five'.isdigit()<jupyter_output><empty_output><jupyter_text>Checking the ASCII/Unicode representation of characters<jupyter_code>ord('A')
chr(65)<jupyter_output><empty_output><jupyter_text>Printing hints<jupyter_code>my_string = "one small text"
print(my_string) #, end="\n")
print(my_string)
print(my_string, end=" ")
print(my_string)
print(my_string)
print(my_string, my_string, my_string, sep=" separated ")<jupyter_output>one small text
one small text separated one small text separated one small text<jupyter_text>The useful module "string"<jupyter_code>import string
string.punctuation
for punct in ['.','?','!']:
    s9 = s9.replace(punct, '*****')
print(s9)
s9.split('*****')
s11 = 'a string'
s11 += ' added to another'
print(s11)<jupyter_output><empty_output><jupyter_text>Type Boolean (True, False):  + A boolean is used to create logic statements, or appear as a result of logical tests  + Bolean objetcts can be either True or False  + True and False are some of the [Python constants _bultin_](https://docs.python.org/3/library/constants.html)  OperationResultNotesx or yif x is false, then y, elsex(1)x and yif x is false, then x, elsey(2)not xif x is false, then True,else False(3)<jupyter_code>'RENATO'.isupper()
b1 = True
b2 = False
type(b2)
print(b1 == b2)
print(2 == 5)
type(2 == 7)
print(not "something")
print(not [0,2,3])
print(not "")
print(not [])
4 != 5
if (9 > 10) and (2 == (1 + 1)) and (7 <= 8):
    print('Right')
    
if x == 4095:
    print('Nice')
else:
    print('Good')
print('New Block')<jupyter_output>Good
New Block<jupyter_text>Type [Sets](https://medium.com/@rkp0432/set-type-and-frozenset-in-python-3-all-functions-and-examples-a5754e9f2ab6):+ Set objects in Python are sets of unique itens (no repetition).  + Sets are muttable, and _frozensets_ are immutable<jupyter_code>c1 = {1,2,3,3,3,3,3,4}
print(c1)
type(c1)
dir(c1)
c2 = set([1,2,3,4,1,2])
print(c2)
l3 = [1,2,3,'string']
c3 = set(l3)
print(c3)
c4 = c3.union([9,8,7])
print(c4)
print(c4.intersection(c2))
l3 = list(c3)
print(l3)
l5 = 'a nice string with lots of characters'
c5 = set(l5)
print(c5)
print(len(l5))
print(len(set(l5)))
t1 = '''
The Road Not Taken
By <NAME>

Two roads diverged in a yellow wood,
And sorry I could not travel both
And be one traveler, long I stood
And looked down one as far as I could
To where it bent in the undergrowth;

Then took the other, as just as fair,
And having perhaps the better claim,
Because it was grassy and wanted wear;
Though as for that the passing there
Had worn them really about the same,

And both that morning equally lay
In leaves no step had trodden black.
Oh, I kept the first for another day!
Yet knowing how way leads on to way,
I doubted if I should ever come back.

I shall be telling this with a sigh
Somewhere ages and ages hence:
Two roads diverged in a wood, and I—
I took the one less traveled by,
And that has made all the difference.'''
print(t1)
lwords = t1.split()
lwords[0:30]
unique_words = set(lwords)
print(len(lwords))
print(len(unique_words))
'__'.join(lwords)<jupyter_output><empty_output><jupyter_text>Type [Frozen Sets](https://realpython.com/python-sets/frozen-sets):+ A frozenset is in all respects exactly like a set, except that a frozenset is immutable. + You can perform non-modifying operations on a frozenset:<jupyter_code>fs = frozenset([1,3,2])
type(fs)
dir(fs)<jupyter_output><empty_output><jupyter_text>Type Dict:+ Dictionaires are sequences of pairs key:values  + They are created with curly braces, commas and colons e.g.{key1: value1, key2: value2}  + Keys must be immutable types (strings, numbers, tuples), values can be of any type<jupyter_code>d1 = {'key1':[1,2,3],'key2':2,'key3':4,45:26, 'key4':23}
print(d1)
type(d1)
dir(d1)
d1.update({2:3})
print(d1)
record = {'Weight':73, 'Height':183, 'Age':44, 'Name':'Sebastian'}
print(record)
record['Age']
grades = {'Math':{'A1':9.0, 'A2':8.0,'AS':4.0},
          'History':{'A1':9.0, 'A2':8.0,'AS':4.0},
          'Geography':{'A1':9.0, 'A2':8.0,'AS':4.0}}

print(grades)
grades['Math']['A2']
grades.items()
'A2' in grades['Math']
grades['Math'].values()
grades['Math']['AS'] = 10
print(grades)
print(grades['Geography'])
print(sorted(grades['Geography']))
print(sorted(grades['Geography'].items()))
print(sorted(grades['Geography'].items(), key = lambda x:x[1]))
dic1 = {}
print(dic1)
dic1['element1'] = 23
print(dic1)
dic1.update({'one':2})
print(dic1)
dic1['one'] = 1
print(dic1)<jupyter_output>{'element1': 23, 'one': 1}<jupyter_text>Type Tuple:  + Tuples, as lists, are ordered sequences of items.  + The great difference is that tuples are immutable - after created, their elements cannot be modified without re-creation<jupyter_code>t1 = (1,2,3,4,7,4,3,1,'string',{1,2}, [1,2])
type(t1)
dir(t1)
t1[0]
t1[5]
t1[3:6]
l1 = [1,2,3]
t2 = tuple(l1)
print(t2)
l2 = list(t2)
print(l2)
d5 = {(1,2):'tuple as a key'}
d5
t3 = (2,4,7,2,2,2,2)
t3.count(2)
a = [1,2]
t4 = (a,a,a,a,a)
l5 = [a,a,a,a,a]
print(t4)
print(l5)
fake_tuple = (1)
proper_tuple = (1,)
print(type(fake_tuple))
print(type(proper_tuple))<jupyter_output><class 'int'>
<class 'tuple'><jupyter_text>Packing and unpacking tuples<jupyter_code>t6 = 2, 4
print(t6)
x, y = 10, 19 
print(y)
print(x)
t7 = (2,3,4)
x,y,z = t7
print(t7)
print(x)
print(y)
print(z)
x, *y, z = (1,2,3,4)
print(x)
print(y)
print(z)
x, y, *z = (1,2,3,4)
print(x)
print(y)
print(z)
# Swapping values
print(x)
print(y)

x,y = y,x

print(x)
print(y)<jupyter_output>1
2
2
1<jupyter_text>Type Range+ Range generates an immutable sequence of numbers  + Ranges can take 1 to 3 integer parameters: begin, end and step<jupyter_code>print(range(15))
list(range(15))
range(3,7)
list(range(3,7))
range(0,10,2)
list(range(0,10,2))<jupyter_output><empty_output><jupyter_text>As with other indexes in Python, the result does not include the second index.<jupyter_code>list(range(1,13)) 
list(range(0,11,2))<jupyter_output><empty_output><jupyter_text>The third parameter sets the step. The Default value is 1.<jupyter_code>gen50 = range(5,51,5)
gen50
unfold_gen50 = list(gen50)
unfold_gen50
range(9**12)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14170922710248554, 'fraction_numerical': 0.042560435818862784, 'mean_word_length': 6.108422071636012, 'pattern_counts': {'":': 1, '<': 122, '<?xml version=': 0, '>': 124, 'https://': 11, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '33', 'dir': 'jupyter-structured-clean-dedup', 'id': '60802', 'license': 'Apache-2.0', 'n_tokens_mistral': 5903, 'n_tokens_neox': 5532, 'n_words': 1533, 'path': 'Notebooks/01_Python_Datatypes.ipynb', 'repo_name': 'pavelcristina/Python_Course', 'size': '14691'}