Day 9-12: Some Essential Topics
Tags: beginners, programming, python, 100daysofcode
Published: 2023-04-13 02:38:39

In this 4-day continuation of my Python trek, I managed to cover several essential topics. These will most likely help me go to the next level. I've learned how to work with regular expressions, manage filesystem paths, handle serialization, get familiar with iterators and iterable and more.

Day 9 was all about Regular Expressions which is a powerful tool for pattern matching and searching within strings. They are widely used for tasks like data validation, text parsing, and search-and-replace operations. With Python's re module, I got to work with match, search and split functions.

```
import re

item_list = [
    {"search": "hello world", "pattern": "hel.o"},
    {"search": "helpo world", "pattern": "hel[lp]o"},
    {"search": "hel7o world", "pattern": "hel[a-zA-Z0-9]o"},
    {"search": "bhellllllllozz", "pattern": "[a-z]*hel*o"},
    {"search": "xyyy7z", "pattern": "x[0-9]*y{3}[0-9]*z"},
    {"search": "545545545", "pattern": "(545){3}"}
]

for item in item_list:
    result = re.match(item["pattern"], item["search"])
    if result:
        print(f"{item['search']} matches {item['pattern']}")
    else:
        print(f"{item['search']} does not match {item['pattern']}")
```

Day 10: Filesystem paths (pathlib), Serialization (pickle) and Iterators and Iterable
The pathlib module provides an object-oriented way to work with filesystem paths which is more readable when compared to the older os.path module.

Example using os.path module:
`path = os.path.abspath(os.sep.join(['.', 'subdir', 'subsubdir', 'file.ext']))`

Example using pathlib module:
`path = (pathlib.Path(".") / "subdir" / " subsubdir" / "file.ext").absolute()`

Serialization (pickle):
Python's pickle module allows you to convert complex objects into a byte stream, which can be stored or transmitted and then reconstructed later. It's useful for saving the state of a program or sharing data between processes.

```
import pickle

class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def __repr__(self):
        return f'Person("{self.name}",{self.age},"{self.gender}")'

    def __str__(self):
        return f"({self.name},{self.age},{self.gender})"

    def __eq__(self, object):
        return self.name == object.name and self.age == object.age and self.gender == object.gender

person = Person("John", 30, "Male")

with open("person_file", 'wb') as file:
    pickle.dump(person, file)

with open("person_file", 'rb') as file:
    loaded_person = pickle.load(file)

print(loaded_person)
assert loaded_person == person

Iterators and Iterable:
Iterable objects are objects that can be looped over while an iterator is an object that defines a method __next__() 
for iterating over the elements of an iterable object.

class SeparatorIterable:
    def __init__(self, string, separator):
        self.string = string
        self.separator = separator

    def __iter__(self):
        return SeparatorIterator(self.string, self.separator)


class SeparatorIterator:
    def __init__(self, string, separator):
        self.words = ["-".join(w) for w in string.split()]
        self.index = 0

    def __next__(self):
        if self.index == len(self.words):
            raise StopIteration()

        word = self.words[self.index]
        self.index += 1
        return word

    def __iter__(self):
        return self


iterable = SeparatorIterable('hello world', '*')
iterator = iter(iterable)
while True:
    try:
        print(next(iterator))
    except StopIteration:
        break

Output:
h-e-l-l-o
w-o-r-l-d
```

Day 11 and 12: List Comprehensions, Set Comprehensions, and Dictionary Comprehensions
List comprehensions provide a concise way to create lists in a single line of code.

Set and Dictionary Comprehensions:
Similar to list comprehensions, set and dictionary comprehensions allow you to create sets and dictionaries in a concise and readable manner.

In the following examples, I show examples of using list comprehensions.

This first example prints out numbers from range(10) that are divisible by 3:

```
div_by_3list = [i for i in range(10) if i % 3 == 0]
print(div_by_3_list)

Output: [0, 3, 6, 9]
```

This next one prints out numbers from range(50) that are divisible by 3 and divisible by 5:

```
filtered_3_and_5_list = [x for x in range(50) if x % 3 == 0 if x % 5 == 0]
print(filtered_3_and_5_list)
Output: [0, 15, 30, 45]

```
This final example prints out 'vowel' if the letter is a vowel otherwise it prints 'consonant':

```
list = ["vowel" if y in 'aeiou' else "consonant" for y in 'abcde']
print(list)
Output: ['vowel', 'consonant', 'consonant', 'consonant', 'vowel']
```