├── .gitignore ├── README.md ├── data └── input │ ├── dummy.txt │ └── people.csv ├── requirements.txt └── src ├── PYTHON-00-BASICS-EXERCISES ├── __init__.py ├── builtin-data-types.py ├── conditionals.py ├── date-time.py ├── dictionary-operations.py ├── file-operations.py ├── list-operations.py ├── loops-part-01.py ├── loops-part-02.py ├── stdin-stdout.py ├── string-operations.py └── tuple-set.py ├── PYTHON-01-INTERMEDIATE-EXERCISES ├── __init__.py ├── downloader.py ├── factorial-normal-and-recursion.py ├── function-args-kwargs.py ├── function-user-defined.py └── try-except-block.py ├── PYTHON-01-OBJECT-ORIENTED-PROGRAMMING ├── __init__.py ├── oop_basic_blocks.py ├── oop_class_object_additional.py ├── oop_encapsulation.py ├── oop_import_module.py ├── oop_inheritance.py ├── oop_inheritance_additional.py └── oop_polymorphism.py ├── PYTHON-02-FUNCTIONAL-PROGRAMMING ├── __init__.py ├── higher-order-functions.py └── lambda-anonymous-function.py └── PYTHON-03-EXTRA-EXCERCISES ├── __init__.py ├── kth-largest-smallest.py ├── list-chunk.py ├── list-flatten.py ├── loop-multiply-table.py ├── nested-list-flatten.py ├── odd-even-string-split.py ├── pixel-2d-array.py ├── string-operations.py └── swap-list-elements.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | venv 3 | data/output -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![pyversion](https://img.shields.io/static/v1?label=python&color=blue&message=3.7.5%20)](./) 2 | 3 | #### Python Refresher 4 | 5 | * quick reference for python fundamentals 6 | * code snippets were tested with Python 3.7.5 7 | -------------------------------------------------------------------------------- /data/input/dummy.txt: -------------------------------------------------------------------------------- 1 | Hi helloHi helloHi helloHi helloHi helloHi helloHi helloHi hello -------------------------------------------------------------------------------- /data/input/people.csv: -------------------------------------------------------------------------------- 1 | name,age,country,salary,department 2 | AAA,25,India,80000,IT 3 | BBB,25,India,85000,IT 4 | CCC,28,Russia,65000,HR 5 | DDD,24,UK,68000,HR 6 | EEE,26,USA,75000,Sales 7 | FFF,30,Canada,95000,IT 8 | GGG,45,China,110000,IT -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barath2904/python-workouts/3cc0204ef671f4fb271a24362e5390b0f98f2d69/requirements.txt -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barath2904/python-workouts/3cc0204ef671f4fb271a24362e5390b0f98f2d69/src/PYTHON-00-BASICS-EXERCISES/__init__.py -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/builtin-data-types.py: -------------------------------------------------------------------------------- 1 | # first hands-on 2 | print("Hello world!") 3 | 4 | # separator can be provided to string function 5 | print("Day", "Night", sep=" & ") 6 | 7 | # built-in types 8 | # Simple Data Types - Integer, String, Float, Boolean 9 | # Float & Double are same in python. we have float as the built-in type 10 | # collections - List, Dictionary, Tuple, Set (Basically collections or data structures) 11 | a = 10 12 | b = "hi" 13 | c = 25.7 14 | d = True 15 | 16 | print(type(a)) 17 | print(type(b)) 18 | print(type(c)) 19 | print(type(d)) 20 | 21 | print("*"*50) 22 | 23 | li = [1, 2, 3] 24 | di = {"one": 1, "two": 2, "three": 3} 25 | tu = (1, 2, 3) 26 | se = {1, 2, 3} 27 | print(type(li)) 28 | print(type(di)) 29 | print(type(tu)) 30 | print(type(se)) 31 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/conditionals.py: -------------------------------------------------------------------------------- 1 | total = 1000 2 | city = input("enter the city name:").lower() 3 | 4 | # simple if-else block 5 | if total == 100: 6 | print("total:100") 7 | else: 8 | print("total is not 100") 9 | 10 | # nested if-elif-else block 11 | if city == "bangalore": 12 | print(city.upper()) 13 | if total == 100: 14 | print("total:100") 15 | elif total < 100: 16 | print("total less than 100") 17 | else: 18 | print("total greater than 100") 19 | else: 20 | print("city provided is not bangalore") 21 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/date-time.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | # current date & datetime 4 | datetime_object = datetime.datetime.now() 5 | print(datetime_object) 6 | 7 | # specific formats 8 | print(datetime_object.strftime("%Y/%m/%d")) 9 | print(datetime_object.strftime("%Y|%m|%d")) 10 | 11 | date_object = datetime.date.today() 12 | print(date_object) 13 | 14 | # date object of today's date 15 | today = datetime.date.today() 16 | print("Current year:", today.year) 17 | print("Current month:", today.month) 18 | print("Current day:", today.day) 19 | 20 | # date difference operation 21 | date_info = (datetime.date.today() - datetime.timedelta(days=4)) 22 | print(date_info) 23 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/dictionary-operations.py: -------------------------------------------------------------------------------- 1 | # Python Dictionary is an unordered sequence of data of key-value pair form. 2 | # It is similar to Map or hash table type. 3 | # Dictionaries are written within curly braces in the form key:value 4 | # Mutable data type 5 | 6 | countries = {"India": "Delhi", "China": "Beijing", "USA": "Washington", "Australia": "Canberra"} 7 | print(countries) 8 | 9 | # adding entry 10 | countries["UK"] = "London" 11 | print(countries) 12 | 13 | # key values are case-sensitive 14 | # retrieving values 15 | print(countries["India"]) 16 | print(countries["Australia"]) 17 | 18 | # adding/updating entry 19 | countries.update({"India": "New Delhi", "France": "Paris"}) 20 | print(countries) 21 | 22 | # Retrieving values from Dictionary 23 | # print(countries["unknown_country"]) will return KeyError 24 | print(countries.get("unknown_country")) # will return None if Key not found 25 | print(countries.get("unknown_country", "NA")) # will return default value if key not found 26 | 27 | # print keys & values separately 28 | print(countries.keys()) 29 | print(countries.values()) 30 | print(countries.items()) 31 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/file-operations.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | print("version of python: ", sys.version) 5 | 6 | # r for reading 7 | # w for writing 8 | # a for appending 9 | 10 | # creating file with content 11 | f0 = open("D:\\file1.txt", "w") 12 | print("opening a new file file1.txt & writing contents to it") 13 | f0.write("Hi Hello Good morning \n") 14 | f0.write("End of File") 15 | f0.close() 16 | 17 | # reading an existing file 18 | f1 = open("D:\\file1.txt", "r") 19 | print("Reading file1.txt") 20 | v1 = f1.read() 21 | print(v1) 22 | f1.close() 23 | 24 | # creating file with content 25 | f2 = open("D:\\file2.txt", "w") 26 | print("writing the contents of file1.txt to file2.txt") 27 | f2.write(v1) 28 | f2.close() 29 | 30 | # appending lines to files 31 | l1 = "hi" 32 | l2 = "hello" 33 | l3 = "hey" 34 | lines = [l1, l2, l3] 35 | f3 = open("D:\\file2.txt", "a") 36 | print("Appending content to file2.txt") 37 | f3.write("\n\n") 38 | for line in lines: 39 | f3.write(line) 40 | f3.write("\n") 41 | f3.close() 42 | 43 | # file operations 44 | # getting current working directory 45 | dir_loc = os.getcwd() 46 | print(dir_loc) 47 | print(os.listdir(dir_loc)) 48 | pathname = os.path.join(dir_loc, "sample.txt") 49 | print(pathname) 50 | 51 | path_name = "D:/" 52 | file_name = "sample-file-creation.txt" 53 | with open(os.path.join(path_name, file_name), 'w') as new_file: 54 | new_file.write("First Line \n") 55 | new_file.write("Second Line \n") 56 | new_file.write("continuous line1 ") 57 | new_file.write("continuous line2") 58 | new_file.write("\n") 59 | new_file.write("End of File") 60 | 61 | # file & directory check 62 | print(os.path.isdir("D:/")) 63 | print(os.path.isfile("D:/sample-file-creation")) 64 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/list-operations.py: -------------------------------------------------------------------------------- 1 | # List - Heterogeneous collection of items 2 | # List is mutable - You can add/remove/modify elements ; Allows duplicate entries inside the list 3 | # List index starts at 0 4 | 5 | # List examples 6 | empty_list = [] 7 | number_list = [0, 1, 2, 3] 8 | word_list = ["apple", "banana", "mango", "grapes", "mango"] 9 | mixed_list = [1, "name", "department", 10000] 10 | 11 | # list operations 12 | 13 | print(type(empty_list)) # returns list 14 | print(number_list) # prints list contents 15 | 16 | number_list.append(4) # appends one more item to the list (by default adds to last) 17 | # output of number_list: [0, 1, 2, 3, 4] 18 | word_list.insert(0, "orange") # inserts orange as first element to the list (base on index value specified) 19 | 20 | number_list.remove(1) # removes the element having value as 1 21 | # output of number_list: [0, 2, 3, 4] 22 | number_list.pop(0) # removes the element at index 0 23 | # output of number_list: [2, 3, 4] 24 | 25 | print(number_list) 26 | print(word_list) 27 | 28 | print(len(mixed_list)) # gives length of list 29 | print(word_list.count("mango")) # gives occurrences of word "mango" 30 | 31 | number_list.reverse() # Reverse the number list 32 | print(number_list) 33 | 34 | word_list.sort() # sorts the list 35 | print(word_list) 36 | 37 | word_list.clear() # empties the list 38 | print(word_list) 39 | print("\n") 40 | 41 | # List unpacking 42 | fruit1, fruit2, fruit3 = ["apple", "banana", "mango"] 43 | print(fruit1) 44 | print(fruit2) 45 | print(fruit3) 46 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/loops-part-01.py: -------------------------------------------------------------------------------- 1 | iteration = 0 2 | for i in range(3): 3 | # i values ranges from 0 to 2 4 | iteration = iteration + 1 5 | print("iteration value: {}".format(iteration)) 6 | 7 | print("\n") 8 | for i in range(1, 4): 9 | # i values ranges from 1 to 3 10 | print(i) 11 | 12 | print("\n") 13 | for i in range(1, 6): 14 | print(i, end="\t") 15 | 16 | print("\n") 17 | base_value = 0 18 | while base_value < 5: 19 | base_value = base_value + 1 20 | print(base_value) 21 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/loops-part-02.py: -------------------------------------------------------------------------------- 1 | # for loop example 2 | 3 | # list iteration 4 | fruits = ["apple", "grapes", "mango"] 5 | for fruit in fruits: 6 | if fruit == "apple": 7 | print(True) 8 | else: 9 | print(False) 10 | 11 | # Ternary operator (conditional expression) inside iteration 12 | for fruit in fruits: 13 | bool_value = True if fruit == "mango" else False 14 | print(bool_value) 15 | 16 | new_fruits = [] 17 | for index in range(len(fruits)): 18 | print(index, fruits[index]) # printing the index & its corresponding value 19 | new_fruits.append(fruits[index]) 20 | 21 | print("\n") 22 | print(new_fruits) 23 | for index_num, index_val in enumerate(new_fruits): 24 | print("index is {} and value is {}".format(index_num, index_val)) 25 | 26 | # iteration with dictionary 27 | countries = {"India": "Delhi", "China": "Beijing", "USA": "Washington", "Australia": "Canberra"} 28 | print("\n") 29 | country_list = [] 30 | country_capital_list = [] 31 | country_capital_dic = {} 32 | for country_name in countries.keys(): 33 | country_list.append(country_name) 34 | for country_capital in countries.values(): 35 | country_capital_list.append(country_capital) 36 | for country, capital in countries.items(): 37 | country_capital_dic[country] = capital 38 | 39 | print(country_list) 40 | print(country_capital_list) 41 | print(country_capital_dic) 42 | print("\n") 43 | 44 | # break - operation to break any loop 45 | # In python, while loop is used to execute a block of statements repeatedly until a given a condition is satisfied. 46 | # And when the condition becomes false, the line immediately after the loop in program is executed. 47 | num = 0 48 | while num < 5: 49 | num += 1 # num = num + 1 50 | print("Hi" + " " + str(num)) 51 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/stdin-stdout.py: -------------------------------------------------------------------------------- 1 | user_input = input("Enter an input value:") 2 | 3 | print(type(user_input)) 4 | # input function always returns a string 5 | print(user_input.isdigit()) 6 | # strip function removes leading & trailing spaces if any 7 | if user_input.isdigit(): 8 | numeric_input = int(user_input.strip()) 9 | print(numeric_input) 10 | print(type(numeric_input)) 11 | else: 12 | print("enter a valid value; Example: 123") 13 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/string-operations.py: -------------------------------------------------------------------------------- 1 | # string operations 2 | var1 = "hello" 3 | var2 = "HI hi" 4 | 5 | print(var1.upper()) 6 | print(var2.lower()) 7 | 8 | # string interpolation : process for substituting values of variables into placeholders in a string 9 | print("hi {}".format("all")) 10 | print("hi {0} {1}".format("hello", "all")) 11 | print("hi {x} {y} all".format(x="hello", y="Good morning")) 12 | print("\n") 13 | 14 | # f-strings - available in python version >= 3.6 15 | # this way of string interpolation method is known as literal string interpolation 16 | # capitalize will change only first character of the string 17 | print(f"Good morning. {var2.capitalize()} {var1}") 18 | 19 | string1 = 'ruby scala python java' 20 | # Splits at space 21 | print(string1.split()) 22 | 23 | string2 = 'hi, hello, welcome' 24 | # Splits at ',' 25 | x = string2.split(',') 26 | # removing extra spaces around items in list 27 | # edge case handling => check if element is string 28 | x = [i.strip() if isinstance(i, str) else i for i in x] 29 | 30 | print(len(string2)) 31 | print(x) 32 | print(len(x)) 33 | 34 | swap_ex = "gOOD mORNING" 35 | print(swap_ex.swapcase()) 36 | 37 | # join split string 38 | join_x = "-".join(x) 39 | print(join_x) 40 | 41 | print("*"*25) 42 | y = ["hello ", 2, " morning"] 43 | # list comprehension 44 | z1 = [i.strip() for i in y if isinstance(i, str)] 45 | z2 = [i.strip() if isinstance(i, str) else i for i in y] 46 | print(z1) 47 | print(z2) 48 | print("*"*25) 49 | -------------------------------------------------------------------------------- /src/PYTHON-00-BASICS-EXERCISES/tuple-set.py: -------------------------------------------------------------------------------- 1 | # Tuple is similar to list. But it is immutable. 2 | # Data in a tuple is written using parenthesis and commas. 3 | fruits = ("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango") 4 | print("count of orange", fruits.count("orange")) 5 | print('Index value of orange', fruits.index("orange")) 6 | 7 | 8 | # A set is an unordered collection of items. Every element is unique (no duplicates). 9 | # In Python sets are written with curly brackets. 10 | set1 = {1, 2, 3, 3, 4, 5, 6, 7} 11 | 12 | # convert list to set 13 | l = [1, 1, 2] 14 | print(set(l)) 15 | 16 | print(set1) 17 | set1.add(10) 18 | 19 | # remove & discard does the same thing. removes the element. 20 | # difference is discard doesn't raise error while remove raise error if element doesn't exist in set 21 | set1.remove(6) 22 | set1.discard(7) 23 | print(set1) 24 | -------------------------------------------------------------------------------- /src/PYTHON-01-INTERMEDIATE-EXERCISES/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barath2904/python-workouts/3cc0204ef671f4fb271a24362e5390b0f98f2d69/src/PYTHON-01-INTERMEDIATE-EXERCISES/__init__.py -------------------------------------------------------------------------------- /src/PYTHON-01-INTERMEDIATE-EXERCISES/downloader.py: -------------------------------------------------------------------------------- 1 | # python script to download different data sets from internet 2 | from urllib import request 3 | import os 4 | 5 | 6 | # generates file name with absolute path 7 | def path_generator(file): 8 | # windows directory path 9 | data_directory = "D:\\python_data" 10 | output_file = os.path.join(data_directory, file) 11 | return output_file 12 | 13 | 14 | # downloads file from provided url & save it mentioned output file name 15 | def data_downloader(url_link, output_file): 16 | try: 17 | request.urlretrieve(url_link, output_file) 18 | except Exception as err: 19 | print("Error downloading the file. Exception occurred : {}".format(err)) 20 | 21 | 22 | # sample dataset 23 | # replace with corresponding links for required datasets 24 | file_url = "https://raw.githubusercontent.com/IBM/" \ 25 | "invoke-wml-using-cognos-custom-control/master/data/Telco-Customer-Churn.csv" 26 | output_file_name = "retail_all_day.csv" 27 | complete_name = path_generator(output_file_name) 28 | data_downloader(file_url, complete_name) 29 | -------------------------------------------------------------------------------- /src/PYTHON-01-INTERMEDIATE-EXERCISES/factorial-normal-and-recursion.py: -------------------------------------------------------------------------------- 1 | # recursive function 2 | # recursive function is a function that calls itself 3 | 4 | 5 | def recursive_factorial(num): 6 | if num == 1: 7 | return num 8 | else: 9 | return num * recursive_factorial(num-1) 10 | 11 | # Functionality explanation: 12 | # factorial(n) # 1st call 13 | # n * factorial(n-1) # 2nd call 14 | # n * n-1 * factorial(n-2) # 3rd call 15 | # n * n-1 * n-2 * factorial (n-3) # 4th call 16 | # ............................... # till n calls 17 | # recursive functions are clean & elegant, but recursive calls are expensive 18 | 19 | 20 | def normal_factorial(num): 21 | if num == 1: 22 | return num 23 | else: 24 | result = 1 25 | for i in range(1, num): 26 | result = result * (i+1) 27 | return result 28 | 29 | 30 | if __name__ == '__main__': 31 | x = int(input("Enter the number to find factorial for:")) 32 | print(recursive_factorial(x)) 33 | print(normal_factorial(x)) 34 | -------------------------------------------------------------------------------- /src/PYTHON-01-INTERMEDIATE-EXERCISES/function-args-kwargs.py: -------------------------------------------------------------------------------- 1 | def function1(argument1, argument2): 2 | print(argument1, argument2) 3 | 4 | 5 | def function2(argument1, argument2): 6 | print(argument1, argument2) 7 | 8 | 9 | def function3(argument1, argument2, argument3="Good Day"): 10 | print(f"{argument1} {argument2}! {argument3}") 11 | 12 | 13 | def function4(argument1): 14 | print(argument1) 15 | 16 | 17 | function1("hi", "hello") # positional argument 18 | function2(argument2="hello", argument1="hi") # keyword argument 19 | 20 | # calling function3 with default parameter. if no argument is passed, it will take the default value 21 | function3("hi", "hello", "How are you ?") 22 | function3("hi", "hello") 23 | 24 | string_list = ["hi", "hello"] 25 | for string_index, string_value in enumerate(string_list): 26 | print(F"index value of list item: {string_index}") 27 | function4(string_value) 28 | 29 | 30 | # *args & **kwargs are used when number of arguments is not static during function call 31 | def function4(*args): 32 | print(args) # returns tuples 33 | print(sum(args)) 34 | 35 | 36 | def function5(**kwargs): 37 | new_list = [] 38 | print(kwargs) # returns dictionary 39 | for value in kwargs.values(): 40 | new_list.append(value) 41 | print(new_list) 42 | 43 | 44 | function4(1, 2, 3) 45 | function4(1, 2, 3, 4) 46 | function5(India="Delhi", China="Beijing") 47 | function5(India="Delhi", China="Beijing", Australia="Canberra") 48 | -------------------------------------------------------------------------------- /src/PYTHON-01-INTERMEDIATE-EXERCISES/function-user-defined.py: -------------------------------------------------------------------------------- 1 | # Example of multi-line comment 2 | """ 3 | Two types of functions 4 | 1. Built-In Functions 5 | 2. User Defined Functions 6 | """ 7 | 8 | # functions with/without argument 9 | # functions with/without return value 10 | 11 | constant_value = 100 12 | 13 | 14 | def function1(): 15 | print("function without arguments") 16 | 17 | 18 | def function2(argument1): 19 | function_variable = 10 20 | print(F"constant value: {constant_value}") 21 | print(F"scope of this is with in this function only. Value: {function_variable}") 22 | print("parameterized function or function with arguments") 23 | print("argument/parameter: {}".format(argument1)) 24 | print(F"sum : {constant_value + function_variable + argument1}") 25 | 26 | 27 | def add_numbers(num1, num2): 28 | print("function with argument & return value") 29 | sum_val = num1 + num2 30 | return sum_val 31 | 32 | 33 | # calling statements for the defined functions 34 | function1() 35 | function2(1000) 36 | function2(2000) 37 | function2(3000) 38 | c1 = add_numbers(1, 2) 39 | c2 = add_numbers(10, 20) 40 | 41 | if c1 > 10: 42 | print("sum greater than 10") 43 | else: 44 | print("sum is less than 10") 45 | -------------------------------------------------------------------------------- /src/PYTHON-01-INTERMEDIATE-EXERCISES/try-except-block.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | # various exception combinations 5 | # keywords: try, except, finally 6 | 7 | try: 8 | print("Try Block") 9 | except Exception as general_error: 10 | # without except block try block will throw error 11 | print("Exception Block. {}".format(general_error)) 12 | 13 | 14 | try: 15 | vowels = ['a', 'e', 'i', 'o', 'u'] 16 | print(vowels[5]) 17 | except IndexError as index_err: 18 | print("Cannot print list item. Exception: {}".format(index_err)) 19 | 20 | try: 21 | size = os.path.getsize("class-object1.py") 22 | print("{} Bytes".format(size)) 23 | except FileNotFoundError as file_err: 24 | print("Unable to retrieve size. Exception: {}".format(file_err)) 25 | 26 | try: 27 | file_object = open("data.txt", "r") 28 | print(file_object.read()) 29 | except FileNotFoundError as no_file_err: 30 | print("Unable to open the file. Exception: {}".format(no_file_err)) 31 | 32 | try: 33 | file_object = open("../../data/input/dummy.txt", "a") 34 | file_object.write("Hi hello") 35 | except PermissionError as access_err: 36 | print("Unable to open the file. Exception: {}".format(access_err)) 37 | 38 | try: 39 | variable_one = "Hello Good morning" 40 | print(variable_two) 41 | except NameError as name_err: 42 | print("Unable to retrieve variable. Exception: {}".format(name_err)) 43 | 44 | try: 45 | print(10/0) 46 | except ZeroDivisionError as operation_err: 47 | print(operation_err) 48 | finally: 49 | # finally block gets executed regardless of exception generation 50 | # optional block for try-except group 51 | print("division operation over") 52 | 53 | try: 54 | user_input = int(input("enter a number")) 55 | print("received input: {}".format(user_input)) 56 | except ValueError as input_err: 57 | print("Unable to retrieve user input. {}".format(input_err)) 58 | sys.exit(1) 59 | 60 | # You can refer for various exceptions in python: https://docs.python.org/3/library/exceptions.html 61 | -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barath2904/python-workouts/3cc0204ef671f4fb271a24362e5390b0f98f2d69/src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/__init__.py -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/oop_basic_blocks.py: -------------------------------------------------------------------------------- 1 | # Object Oriented Programming (OOP) is a programming paradigm associated with concepts of Class & Object 2 | # Class is a blueprint of any entity that defines certain properties & functions (behaviour) 3 | # Class allows you logically group the data (Attributes) & functions (Methods) in a way to reuse 4 | 5 | # Creating object from class is called instantiation & functions inside a class is called as methods 6 | # In general, methods is like any other usual function that does some action except that it is associated with an object 7 | # Class is blueprint for objects. Multiple objects can be created with a class 8 | # Classes are essentially user defined data types 9 | 10 | # OOP facilitates to have properties & behaviour bundled into an object 11 | # objects that has its own attributes (properties) & methods (behaviour) 12 | # Example: object person with properties like a name, age and behaviors such as walking, talking 13 | 14 | # __init__ is a special method that is called when instance of class (object) is created. 15 | # __init__ is also referred as magic or dunder method. Dunder: method name starts & ends with double underscore 16 | # __init__ is similar to constructor that used to initialize state of an object 17 | # self represents instance of a class. It allows us access to the attributes and methods of the class. 18 | # There are 2 types of attributes -> class attribute & instance attribute 19 | # class attributes are defined outside __init__ method while instance attributes are defined within __init__ method. 20 | # There are 3 types of methods -> regular methods, class methods & static methods 21 | # Regular methods automatically takes instance (self) a first argument. 22 | # Class method is bound to class rather than object. Hence instance creation is not required 23 | # static method is similar to normal except that it is logically connected to the class 24 | # class methods & static methods are denoted using decorators: @classmethod & @staticmethod respectively 25 | 26 | # Four Principles of OOP : Inheritance, Encapsulation, Abstraction & Polymorphism 27 | 28 | class Employee: 29 | # class attribute/variables 30 | company = "Microsoft" 31 | 32 | def __init__(self, name, salary): 33 | # instance attributes/variables 34 | self.first_name = name 35 | self.salary = salary 36 | 37 | def calculate_salary(self): 38 | total_salary = 12 * self.salary 39 | print(F"{self.first_name} earns Rs.{total_salary} per year at {self.company}") 40 | 41 | @classmethod 42 | def modify_company(cls, company_name): 43 | # cls -> class Employee 44 | cls.company = company_name 45 | 46 | @classmethod 47 | def parse_employee(cls, employee_data): 48 | first_name, salary = employee_data.split("-") 49 | return cls(first_name, int(salary)) 50 | 51 | @staticmethod 52 | def emp_category(category): 53 | if category == "FTE": 54 | print("Long Term Employee") 55 | elif category == "C2C": 56 | print("Short Term Employee") 57 | else: 58 | print(F"{category} is undefined") 59 | 60 | 61 | # object creation 62 | emp1 = Employee("Ram", 100000) 63 | emp1.calculate_salary() 64 | 65 | # self represents instance of a class 66 | emp2 = Employee("Sam", 100000) 67 | Employee.calculate_salary(emp2) 68 | 69 | print("\n") 70 | # changing the class variable 71 | Employee.company = "Amazon" 72 | emp1.calculate_salary() 73 | emp2.calculate_salary() 74 | print("\n") 75 | # changing the class variable for a specific instance 76 | emp2.company = "Google" 77 | emp2.calculate_salary() 78 | emp1.calculate_salary() 79 | 80 | # changing the class variable value without object creation 81 | Employee.modify_company("Facebook") 82 | 83 | # class methods can be used as alternative constructor 84 | emp_data = "Michael-200000" 85 | emp3 = Employee.parse_employee(emp_data) 86 | emp3.calculate_salary() 87 | emp3.emp_category("FTE") 88 | -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/oop_class_object_additional.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | # class attribute 3 | area = "Chennai" 4 | 5 | def __init__(self, name, age): 6 | # instance attributes 7 | self.name = name 8 | self.age = age 9 | 10 | def is_teenage(self): 11 | if 18 <= self.age <= 24: 12 | print("teenager") 13 | else: 14 | print("not teenager") 15 | 16 | def is_senior_citizen(self): 17 | if self.age > 60: 18 | print("senior citizen") 19 | else: 20 | print("not senior citizen") 21 | 22 | def is_indian(self, nationality): 23 | if nationality.lower() == "india": 24 | print("{} is from India".format(self.name)) 25 | else: 26 | print("{} is foreigner".format(self.name)) 27 | return nationality 28 | 29 | def is_tamil(self, language, nationality): 30 | # calling is_indian method inside current method 31 | person_nationality = self.is_indian(nationality) 32 | if language.lower() == "tamil": 33 | if 18 <= self.age <= 24: 34 | print("tamil teenager living in {0}; Nationality: {1}".format(self.area, person_nationality.upper())) 35 | else: 36 | print("other age category living in {x}; Nationality: {y}".format(x=self.area, 37 | y=person_nationality.upper())) 38 | else: 39 | print("other language person living in {}; Nationality: {}".format(self.area, person_nationality.upper())) 40 | 41 | 42 | # object creation 43 | person1 = Person("xxx", 18) 44 | person2 = Person("yyy", 75) 45 | person3 = Person("zzz", 22) 46 | person4 = Person("abc", 25) 47 | 48 | # printing type of object & instance attributes 49 | print("printing info on person1 object") 50 | print(type(person1)) 51 | print(person1.name) 52 | print(person1.age) 53 | print("\n") 54 | 55 | # calling methods 56 | print("methods calling") 57 | person1.is_teenage() 58 | person1.is_senior_citizen() 59 | person2.is_teenage() 60 | person2.is_senior_citizen() 61 | 62 | print("\n") 63 | person1.is_tamil("tamil", "india") 64 | person2.is_tamil("bengali", "india") 65 | person3.is_tamil("tamil", "singapore") 66 | print("\n") 67 | nationality_info = person4.is_indian("USA") 68 | print(nationality_info + ";" + " person4 attributes: " + person4.name + " " + str(person4.age)) 69 | -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/oop_encapsulation.py: -------------------------------------------------------------------------------- 1 | # Encapsulation is a way of restricting access to methods inside a class 2 | # As python is an interpreted language ; hence encapsulation is weak 3 | # Encapsulation can be performed by convention, but not enforced by language 4 | # Restriction levels: private, protected, public 5 | 6 | 7 | class Base: 8 | def __init__(self): 9 | self.amount = 100 10 | self._amount = 200 11 | self.__amount = 300 12 | 13 | def print_amount(self): 14 | print(self.amount) 15 | print(self._amount) 16 | print(self.__amount) 17 | 18 | def set_amount(self, amount1, amount2, amount3): 19 | self.amount, self._amount, self.__amount = amount1, amount2, amount3 20 | 21 | def __private(self): 22 | print("private value in Base") 23 | 24 | def _protected(self): 25 | print("protected value in Base") 26 | 27 | def public(self): 28 | print("public value in Base") 29 | self.__private() 30 | 31 | 32 | class Derived(Base): 33 | 34 | def __private(self): 35 | print("derived private") 36 | 37 | def _protected(self): 38 | self.__private() 39 | print("derived protected") 40 | 41 | 42 | b = Base() 43 | b.print_amount() 44 | print("") 45 | b.amount = 150 46 | # protected & private attributes can't be changed 47 | b.__amount = 250 48 | b.__amount = 350 49 | b.print_amount() 50 | # protected & private attributes can be changed via setter method 51 | print("") 52 | b.set_amount(150, 250, 350) 53 | b.print_amount() 54 | 55 | print("") 56 | d = Derived() 57 | # d.public() 58 | print("") 59 | # not recommended to call protected method & hence it shows warning 60 | # private methods - we won't be able to call as python doesn't recognize 61 | # d._protected() # ---> will work, but not 62 | # d.__private() # ---> will throw error 63 | 64 | # print(dir(d)) # --> prints attributes & methods of object 65 | # d.__private() can be called as d._Base_private() --> Name Mangling 66 | # Name mangling: Double underscore prefix causes python interpreter to rewrite attribute & method names 67 | # d._Base__private() # ---> still accessible ; Remember Encapsulation is not enforced 68 | -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/oop_import_module.py: -------------------------------------------------------------------------------- 1 | from oop_inheritance import Parents, Child 2 | 3 | boy = Child("Shiva", "Parvathy", "Murugan") 4 | boy.get_father_name() # method inherited from Parents class 5 | boy.get_mother_name() # method inherited from Parents Class 6 | boy.get_parents_info() # child class method that uses attributes from Parents class 7 | boy.get_location() 8 | 9 | parent = Parents("Shiva", "Parvathi") 10 | parent.get_location() 11 | -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/oop_inheritance.py: -------------------------------------------------------------------------------- 1 | # Inheritance allows us to define a class that inherits all the methods and attributes (properties) from another class. 2 | # Parent class or base class [being inherited from] --> Class Parents 3 | # Child class or derived class [inherits from another class] --> Class Child(Parents) 4 | # Inheritance benefits with code reuse, extensibility & readability 5 | # Types of Inheritance - Single, Multiple, Multilevel, Hierarchical, Hybrid 6 | # Single Inheritance: Derived class inherits from single base class 7 | # Multiple Inheritance: Derived class inherits from multiple base class 8 | # Multilevel Inheritance: Base - Intermediate - Derived --> Intermediate is base class for Derived. 9 | # Hierarchical Inheritance: More than one derived class created from single base class 10 | # Hybrid: Implemented mix of above mentioned inheritance 11 | 12 | 13 | class Parents: 14 | 15 | def __init__(self, father, mother): 16 | self.father = father 17 | self.mother = mother 18 | 19 | def get_father_name(self): 20 | print("Father Name:" + self.father) 21 | 22 | def get_mother_name(self): 23 | print("Mother Name:" + self.mother) 24 | 25 | def get_location(self): 26 | print("{} and {} are residing in India".format(self.father, self.mother)) 27 | 28 | 29 | class Child(Parents): 30 | 31 | def __init__(self, father, mother, child): 32 | Parents.__init__(self, father, mother) 33 | # super().__init__(father, mother) 34 | self.child = child 35 | 36 | def get_child_name(self): 37 | print("Child Name:", self.child) 38 | 39 | def get_parents_info(self): 40 | print("Dad Name: {} \nMom Name: {}".format(self.father, self.mother)) 41 | 42 | # Polymorphism with inheritance 43 | # method overriding 44 | def get_location(self): 45 | print("{} is residing in Malaysia".format(self.child)) 46 | 47 | # calls are being made from oop_import_module.py program 48 | -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/oop_inheritance_additional.py: -------------------------------------------------------------------------------- 1 | class Employee: 2 | def __init__(self, first_name, last_name, age): 3 | self.first_name = first_name 4 | self.last_name = last_name 5 | self.age = age 6 | 7 | 8 | class Technology(Employee): 9 | def __init__(self, first_name, last_name, age, skill): 10 | super().__init__(first_name, last_name, age) 11 | self.skill = skill 12 | self.department = Technology.__name__ 13 | 14 | 15 | class HR(Employee): 16 | def __init__(self, first_name, last_name, age, speciality): 17 | super().__init__(first_name, last_name, age) 18 | self.speciality = speciality 19 | self.department = HR.__name__ 20 | 21 | 22 | class Supervisor(Employee): 23 | def __init__(self, first_name, last_name, age, employees=None): 24 | super().__init__(first_name, last_name, age) 25 | if employees is None: 26 | self.employees = [] 27 | else: 28 | self.employees = employees 29 | 30 | def add_employee(self, employee): 31 | if employee not in self.employees: 32 | self.employees.append(employee) 33 | else: 34 | print("Employee already tagged") 35 | 36 | def remove_employee(self, employee): 37 | if employee in self.employees: 38 | self.employees.remove(employee) 39 | else: 40 | print("Employee not available") 41 | 42 | def list_employees(self): 43 | for employee in self.employees: 44 | if "skill" in dir(employee): 45 | speciality = employee.skill 46 | else: 47 | speciality = employee.speciality 48 | print(F"Manager: {self.first_name} {self.last_name}; " 49 | F"Employee: {employee.first_name} {employee.last_name}; " 50 | F"Speciality: {speciality}; " 51 | F"Department: {employee.department}") 52 | 53 | 54 | emp1 = Technology("Michael", "Clarke", 28, "Python") 55 | emp2 = Technology("Sara", "Johnson", 26, "ReactJS") 56 | emp3 = HR("Alan", "Simon", 30, "Recruitment") 57 | 58 | manager1 = Supervisor("James", "Davis", 35, [emp1]) 59 | manager1.list_employees() 60 | manager2 = Supervisor("Tim", "Connors", 32) 61 | manager2.add_employee(emp2) 62 | manager2.add_employee(emp3) 63 | print("") 64 | manager2.list_employees() 65 | -------------------------------------------------------------------------------- /src/PYTHON-01-OBJECT-ORIENTED-PROGRAMMING/oop_polymorphism.py: -------------------------------------------------------------------------------- 1 | # Polymorphism is creating an similar named entity to represent different behaviours at different scenarios 2 | # method names are same but action items are different for different scenarios 3 | # polymorphism can be applicable at built-in function levels as well. "len" is a classic example 4 | # "len" can be applied on string, list, dictionary, etc. function name is same but usage is different as per data type 5 | 6 | 7 | class Asia: 8 | 9 | def __init__(self): 10 | self.country = "India" 11 | 12 | def capital(self): 13 | print("New Delhi is the capital of {}".format(self.country)) 14 | 15 | def language(self): 16 | print("Hindi is widely spoken language in {}".format(self.country)) 17 | 18 | def type(self): 19 | print("{} is a developing country".format(self.country)) 20 | 21 | 22 | class NorthAmerica: 23 | 24 | def __init__(self): 25 | self.country = "USA" 26 | 27 | def capital(self): 28 | print("Washington, D.C. is the capital of {}".format(self.country)) 29 | 30 | def language(self): 31 | print("English is the widely spoken language in {}".format(self.country)) 32 | 33 | def type(self): 34 | print("{} is a developed country".format(self.country)) 35 | 36 | 37 | countries = [Asia(), NorthAmerica()] 38 | for country in countries: 39 | print("\n") 40 | country.capital() 41 | country.language() 42 | country.type() 43 | -------------------------------------------------------------------------------- /src/PYTHON-02-FUNCTIONAL-PROGRAMMING/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barath2904/python-workouts/3cc0204ef671f4fb271a24362e5390b0f98f2d69/src/PYTHON-02-FUNCTIONAL-PROGRAMMING/__init__.py -------------------------------------------------------------------------------- /src/PYTHON-02-FUNCTIONAL-PROGRAMMING/higher-order-functions.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | 4 | def multiply(multiply_argument): 5 | return multiply_argument*10 6 | 7 | 8 | def odd_filtering(filter_argument): 9 | if (filter_argument % 2) != 0: 10 | return True 11 | else: 12 | return False 13 | 14 | 15 | # Higher order functions are functions that take another function as argument 16 | 17 | # map() syntax= map(function, iterator object) 18 | # map() returns map object 19 | number_list = [1, 2, 3, 4, 5] 20 | a = (lambda x: x * 10) 21 | multiply_object = map(a, number_list) 22 | print("map object: {}".format(multiply_object)) 23 | lambda_multiply = list(multiply_object) 24 | 25 | normal_multiply = list(map(multiply, number_list)) 26 | print("multiply result using lambda function: {}".format(lambda_multiply)) 27 | print("multiply result using normal function: {}".format(normal_multiply)) 28 | 29 | fruits = ["apple", "mango"] 30 | # map usage example with a built-in function 31 | up_fruits = list(map(str.upper, fruits)) 32 | print("fruits in lower case: {}".format(fruits)) 33 | print("fruits in upper case: {}".format(up_fruits)) 34 | 35 | # filter() filters given sequence with help of passed function that evaluates the condition to be true or not 36 | # filter() syntax= filter(function returning Boolean, iterator object) 37 | # filter() returns filter object 38 | print("\n") 39 | filter_list = [5, 10, 15, 20, 25, 30, 35] 40 | even_object = filter(lambda x: (x % 2 == 0), filter_list) 41 | print("filter object: {}".format(even_object)) 42 | even_filtered = list(even_object) 43 | print("filtered even list using lambda function: {}".format(even_filtered)) 44 | normal_filtering = list(filter(odd_filtering, filter_list)) 45 | print("filtered odd list using normal function: {}".format(normal_filtering)) 46 | 47 | # reduce function used a mathematical technique called folding 48 | # folding reduces list of items to single/cumulative item 49 | # reduce() syntax= reduce(function, iterator object, ) 50 | reduce_numbers = [10, 20, 30, 40] 51 | added_value = reduce((lambda x, y: x+y), reduce_numbers) 52 | # reduce logic 53 | # 0 + 10 = 10 54 | # 10 + 20 = 30 55 | # 30 + 30 = 60 56 | # 60 + 40 = 100 57 | added_value_with_initializer = reduce((lambda x, y: x+y), reduce_numbers, 10) 58 | # reduce logic 59 | # 10 + 10 = 20 60 | # 20 + 20 = 40 61 | # 40 + 30 = 70 62 | # 70 + 40 = 110 63 | print("\n") 64 | print("reduce result type 1: {}".format(added_value)) 65 | print("reduce result type 2: {}".format(added_value_with_initializer)) 66 | 67 | # finding min & max using reduce function 68 | maximum_number = reduce((lambda a, b: a if a > b else b), reduce_numbers) 69 | minimum_number = reduce((lambda a, b: a if a < b else b), reduce_numbers) 70 | print("minimum: {}, maximum: {}".format(minimum_number,maximum_number)) 71 | -------------------------------------------------------------------------------- /src/PYTHON-02-FUNCTIONAL-PROGRAMMING/lambda-anonymous-function.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def area(radius): 5 | pi = 3.14 6 | return pi * radius * radius 7 | 8 | 9 | # lambda = anonymous function. 10 | # anonymous functions are functions without name ; they are not defined using "def" keyword 11 | # lambda can take any number of arguments, but can have only one expression 12 | # syntax = lambda : 13 | try: 14 | a = (lambda x: 3.14 * x * x) 15 | print("area value using lambda function: {}".format(a(10))) 16 | except Exception as lambda_error: 17 | print(lambda_error) 18 | sys.exit(1) 19 | 20 | # lambda implementation without try-except block 21 | b = (lambda x, y: 3.14 * x * y) 22 | print("area value using lambda function: {}".format(b(10, 10))) 23 | print("area value using normal function: {}".format(area(10))) 24 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/barath2904/python-workouts/3cc0204ef671f4fb271a24362e5390b0f98f2d69/src/PYTHON-03-EXTRA-EXCERCISES/__init__.py -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/kth-largest-smallest.py: -------------------------------------------------------------------------------- 1 | k = 5 2 | print(F"K value: {k}\n") 3 | 4 | a = [5, 1, 2, 3, 10, 59, 15] 5 | a.sort() 6 | print(F"ascending sorted list: {a}") 7 | # kth largest 8 | if len(a) == k: 9 | print(a[0]) 10 | elif len(a) > k: 11 | print(a[(len(a)-k)]) 12 | # K largest elements 13 | print(sorted(a[(len(a) - k):], reverse=True)) 14 | else: 15 | print("not applicable") 16 | 17 | print("\n") 18 | 19 | b = [5, 1, 2, 3, 10, 59, 15] 20 | b.sort(reverse=True) 21 | print(F"descending sorted list: {b}") 22 | # kth smallest 23 | if len(b) == k: 24 | print(b[0]) 25 | elif len(b) > k: 26 | print(b[(len(b)-k)]) 27 | # K smallest elements 28 | print(sorted(b[(len(b) - k):], reverse=True)) 29 | else: 30 | print("not applicable") 31 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/list-chunk.py: -------------------------------------------------------------------------------- 1 | # chunk the list based on n value 2 | l = [1, 2, 3, 4, 5, 6, 7, 8] 3 | n = 3 4 | nl= [] 5 | if n != 0: 6 | for i in range(0, len(l), n): 7 | print(i) 8 | nl.append(l[i: i+n]) 9 | print(nl) 10 | else: 11 | print("not applicable") 12 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/list-flatten.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | 3 | # works only for list of list 4 | # elements of parent list has to be list 5 | # can flatten only one level 6 | list_of_list = [[1, 2], [3, 4]] 7 | merged_list = list(itertools.chain.from_iterable(list_of_list)) 8 | print(merged_list) 9 | 10 | # flattening 2D list 11 | nested_list = [2, [1, 2], 5, [3, 4]] 12 | # nested_list = [1, [1, 1], 1, [1, 1, 1], 1, 1] 13 | flatten_list = [] 14 | for elem in nested_list: 15 | if isinstance(elem, list): 16 | for item in elem: 17 | flatten_list.append(item) 18 | else: 19 | flatten_list.append(elem) 20 | print(flatten_list) 21 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/loop-multiply-table.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | # looping 5 | def mul_table(num): 6 | # range function returns from x to y-1 in range(x,y) 7 | # range function returns from 0 to n-1 in range(n) 8 | for i in range(1, 16): 9 | print(str(num) + ' x ' + str(i) + ' = ' + str(num*i)) 10 | 11 | 12 | if __name__ == '__main__': 13 | try: 14 | n = int(input("enter the number to build multiplication table for:")) 15 | mul_table(n) 16 | except ValueError as e: 17 | print(F"Enter valid value to run multiplication program.\n{e}") 18 | sys.exit(1) 19 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/nested-list-flatten.py: -------------------------------------------------------------------------------- 1 | def rec_flatten(nested_list_elements): 2 | # works for any kind of nested list 3 | result = [] 4 | for list_element in nested_list_elements: 5 | if isinstance(list_element, list): 6 | result += rec_flatten(list_element) 7 | else: 8 | result.append(list_element) 9 | return result 10 | 11 | 12 | nested_ip_list = [1, 2, [3, 4], [5, [6, [7]]]] 13 | print(rec_flatten(nested_ip_list)) 14 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/odd-even-string-split.py: -------------------------------------------------------------------------------- 1 | # looping + String operation 2 | def index_split(line_content): 3 | even_string = '' 4 | odd_string = '' 5 | for index in range(len(line_content)): 6 | if index % 2 == 0: 7 | even_string += line_content[index] 8 | else: 9 | odd_string += line_content[index] 10 | print(even_string + " " + odd_string) 11 | 12 | 13 | if __name__ == '__main__': 14 | n = int(input("enter the number of lines:")) 15 | 16 | line_list = [] 17 | for i in range(n): 18 | line = input("enter line content:") 19 | line_list.append(line) 20 | 21 | for line_string in line_list: 22 | index_split(line_string) 23 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/pixel-2d-array.py: -------------------------------------------------------------------------------- 1 | # 2D array 2 | # prints BIG 3 | image = [ 4 | [1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], 5 | [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], 6 | [1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1], 7 | [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1], 8 | [1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1] 9 | ] 10 | 11 | for pixel_row in image: 12 | for pixel in pixel_row: 13 | if pixel is 1: 14 | fill = "*" 15 | else: 16 | fill = " " 17 | print(fill, end=' ') 18 | print('') 19 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/string-operations.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | # check occurrence of substring in a string 4 | check_string = "hellogoodhellogoodhellogoodhello" 5 | sub_string = "hellogoodhello" 6 | # fetches overlapping count as well 7 | occurrence_type1 = 0 8 | occurrence_index_list = [] 9 | for i in range(len(check_string)): 10 | if check_string.startswith(sub_string, i): 11 | occurrence_type1 += 1 12 | occurrence_index_list.append(i) 13 | print(occurrence_type1) 14 | # gets indices of occurrences as well 15 | print(occurrence_index_list) 16 | 17 | # returns non-overlapping count 18 | print(check_string.count(sub_string)) 19 | # -------------------------------------------------------------------------------------------------------------------- 20 | # check maximum occurrence of element in a string/list 21 | char_freq = {} 22 | list_val = [1, 2, 4, 5, 1, 2, 1] 23 | string_val = check_string 24 | for char in string_val: 25 | if char in char_freq: 26 | char_freq[char] += 1 27 | else: 28 | char_freq[char] = 1 29 | print(char_freq) 30 | max_char = max(char_freq, key=char_freq.get) 31 | print(F"max occurred character: '{max_char}', Occurrence: {char_freq[max_char]}") 32 | 33 | # using counter approach 34 | char_counter = Counter(check_string) 35 | print(char_counter) 36 | print(max(char_counter, key=char_counter.get)) 37 | 38 | list_counter = Counter([1, 2, 4, 5, 1, 2, 1]) 39 | print(list_counter) 40 | print(max(list_counter, key=list_counter.get)) 41 | # -------------------------------------------------------------------------------------------------------------------- 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/PYTHON-03-EXTRA-EXCERCISES/swap-list-elements.py: -------------------------------------------------------------------------------- 1 | # swap first & last elements 2 | input_list = [1, 2, 3, 5] 3 | # list unpacking 4 | start, *middle, end = input_list 5 | out_list = [end, *middle, start] 6 | print(out_list) 7 | 8 | # alternate approach 9 | # this can work for swap of any 2 positions 10 | ip_list = [1, 2, 3, 5] 11 | ip_list[0], ip_list[-1] = ip_list[-1], ip_list[0] 12 | print(ip_list) --------------------------------------------------------------------------------