diff --git a/.vscode/.ropeproject/config.py b/.vscode/.ropeproject/config.py new file mode 100644 index 0000000..dee2d1a --- /dev/null +++ b/.vscode/.ropeproject/config.py @@ -0,0 +1,114 @@ +# The default ``config.py`` +# flake8: noqa + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', + '.hg', '.svn', '_svn', '.git', '.tox'] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + # prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + # prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + # prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs['save_objectdb'] = True + prefs['compress_objectdb'] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs['automatic_soa'] = True + # The depth of calls to follow in static object analysis + prefs['soa_followed_calls'] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs['perform_doa'] = True + + # Rope can check the validity of its object DB when running. + prefs['validate_objectdb'] = True + + # How many undos to hold? + prefs['max_history_items'] = 32 + + # Shows whether to save history across sessions. + prefs['save_history'] = True + prefs['compress_history'] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs['indent_size'] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs['extension_modules'] = [] + + # Add all standard c-extensions to extension_modules list. + prefs['import_dynload_stdmods'] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs['ignore_syntax_errors'] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs['ignore_bad_imports'] = False + + # If `True`, rope will insert new module imports as + # `from import ` by default. + prefs['prefer_module_from_imports'] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs['split_imports'] = False + + # If `True`, rope will remove all top-level import statements and + # reinsert them at the top of the module when making changes. + prefs['pull_imports_to_top'] = True + + # If `True`, rope will sort imports alphabetically by module name instead + # of alphabetically by import statement, with from imports after normal + # imports. + prefs['sort_imports_alphabetically'] = False + + # Location of implementation of + # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general + # case, you don't have to change this value, unless you're an rope expert. + # Change this value to inject you own implementations of interfaces + # listed in module rope.base.oi.type_hinting.providers.interfaces + # For example, you can add you own providers for Django Models, or disable + # the search type-hinting in a class hierarchy, etc. + prefs['type_hinting_factory'] = ( + 'rope.base.oi.type_hinting.factory.default_type_hinting_factory') + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/week_1/Assignment/assignment.py b/week_1/Assignment/assignment.py new file mode 100644 index 0000000..3553c2f --- /dev/null +++ b/week_1/Assignment/assignment.py @@ -0,0 +1,38 @@ +# Assignment # 1 +## function to print a string diagonally +name = input('Enter Your Name:') +def diagonalPrint(name): + print(f'Name is: {name}') + print('\nYour name diagonaly print as: ') + for i in range(len(name)): + if(i == 0): + print(name[i]) + else: + print(' '*(i-1),name[i]) +diagonalPrint(name) + +## function to print a string reverse diagonally +def reverseDiagonalPrint(name): + print('\nYour name reverse diagonaly print as: ') + for i in range(len(name),-1,-1): + if(i == 0): + print(name[i]) + else: + print(' '*(i-1),name[i-1]) +reverseDiagonalPrint(name) + +# Assignment 2 +## Create a program to take as input 5 student records: + + +# Assignment 3 +## A function that will print lyrics of given song with 1 second delay between each line. +song = "Tere Jaane Ka Gam,Aur Na Aane Ka Gam, Phir Zamaane Ka Gam, Kya Karein?, Meri Dehleez Se Hokar, Bahaarein Jab Gujarti Hai, Yahan Kya Dhup Kya Saawan, Hawayein Bhi Barashti Hai, Hume Puchhon Kya Hota Hai, Bina Dil Ke Jiye Jaana, Bahot Aayi Gayi Yaadein, Magar Iss Baar Tum Hi Aana" +def printSong(song): + import time + songparagraph = song.split(', ') + print('Your Song is:') + for i in range(len(songparagraph)): + print(songparagraph[i])g + time.sleep(1) +printSong(song) \ No newline at end of file diff --git a/week_1/Assignment/readme.md b/week_1/Assignment/readme.md new file mode 100644 index 0000000..df63379 --- /dev/null +++ b/week_1/Assignment/readme.md @@ -0,0 +1,53 @@ +## Assignments + +1. Define a function to print a string diagonally, for example: + + Tarun will be printed as: + + ![https://s3.us-west-2.amazonaws.com/secure.notion-static.com/ba165be3-eab3-43f3-9399-211180238841/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20201206%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201206T191214Z&X-Amz-Expires=86400&X-Amz-Signature=b85fda20d735dfdfd9ebfd409d440d93bed5391ad5ca4bd1dc594c30fd616c35&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Untitled.png%22](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/ba165be3-eab3-43f3-9399-211180238841/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20201206%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201206T191214Z&X-Amz-Expires=86400&X-Amz-Signature=b85fda20d735dfdfd9ebfd409d440d93bed5391ad5ca4bd1dc594c30fd616c35&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Untitled.png%22) + +Optional (recommended): + +- Try printing reverse diagonal as well. + + +### Solution +- for printing characters diagonaly i create a loop which have range of user input then i add spaces at each itration then the character of user input + + +
+2. Create a program to take as input 5 student records in the following format: + +``` +**roll_num** | **name** | **age** | **marks**(out of 100) +``` + +And then output the records in a tabular form with class average, class highest and class lowest at end in the following format. + +- Use dictionaries (list of dictionaries in exact) +- Insert atleast 5 records +- Input must be user-given +- (Optional) validate the user input, i.e marks aren't greater 100 and other such validations you think there might be + +### Not completed + +
+
+ + +3. A function that will print lyrics of given song with 1 second delay between each line. + + - Use time.sleep() + - Use split() function of string + +### Solution +-store a song in a song variable then split it at every part which has , then print all the parts at 1 sec delay + +
+Note: + +- You can use main function to predefine anything but make sure you divide everything you can in functions. +- Submit your github folder link and your output on Google Classroom +- Make sure you fork [https://github.com/sinnytk/Python-Bootcamp-DSC-DSU](https://github.com/sinnytk/Python-Bootcamp-DSC-DSU), clone the repo locally and create your scripts in the respective week's folder and push it. +- Make sure in each folder there's a [readme.md](http://readme.md) file with code output and brief explanation of what you did and why you did it (not necessary, but good practice) + diff --git a/week_1/__pycache__/Day2_1.cpython-39.pyc b/week_1/__pycache__/Day2_1.cpython-39.pyc new file mode 100644 index 0000000..5f24e40 Binary files /dev/null and b/week_1/__pycache__/Day2_1.cpython-39.pyc differ diff --git a/week_1/day2/day 2 pthon bootcamp.py b/week_1/day2/day 2 pthon bootcamp.py new file mode 100644 index 0000000..af01db4 --- /dev/null +++ b/week_1/day2/day 2 pthon bootcamp.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[17]: + + +x = 7 +def func(): + global x + a = x + a = a * 8 + + print(a) +func() +print(x) + + +# In[18]: + + +print("My name is {} I am From {}".format("Shahab","Faislabad")) + + +# In[20]: + + +a = 'pagal' +print(f'hell wajeeha {a}') + + +# In[21]: + + +x = input('Enter your Name:') + + +# In[22]: + + +x + + +# In[23]: + + +x = "87"; + + +# In[24]: + + +int(x) + + +# In[25]: + + +x + + +# In[26]: + + +a , b = 8 ,9 + + +# In[28]: + + +a , b + + +# In[29]: + + +a , b = b , a + + +# In[30]: + + +a , b + + +# In[32]: + + +for i in range (1,100,2): + print(i,end=' ') + + +# In[33]: + + +row = 7 + + +# In[39]: + + +for i in range(row): + for j in range(i): + print("* ",end=' ') + + +# In[40]: + + +print "hello" + + +# In[ ]: + + + + diff --git a/week_1/day3/Day3.py b/week_1/day3/Day3.py new file mode 100644 index 0000000..c10e528 --- /dev/null +++ b/week_1/day3/Day3.py @@ -0,0 +1,10 @@ +# Make Exponent of a number +def exponent(num,expo): + return int(num) ** int(expo) + + +number = input('Enter a number: ') +exponent2 = input('Enter a Exponenet: ') +print(exponent(number,exponent2)) + + diff --git a/week_1/day3/Day3_1.py b/week_1/day3/Day3_1.py new file mode 100644 index 0000000..060a7e4 --- /dev/null +++ b/week_1/day3/Day3_1.py @@ -0,0 +1,34 @@ +#Understanding the Scopes + +def alo(): + # it will make a variable a in local scope of this function + # a = 20 + global a + # glabal tell the funstion the a you will be refrening will be global a + a = a * 10 + print(f'funstion1 {a} {b}') + +def alo2(): + print(f'function2 {a} {b}') + +a = 2 +b = 3 + +# __name__ +# The __name__ variable (two underscores before and after) is a special Python variable. It gets its value depending on how we execute the containing script. +# When a Python interpreter reads a Python file, it first sets a few special variables. Then it executes the code from the file. +# when the interpreter runs a module, the __name__ variable will be set as __main__ if the module that is being run is the main program. But if the code is importing the module from another module, then the __name__ variable will be set to that module’s name. + +def myFunction(): + print('The value of __name__ is ' + __name__) + +def main(): + myFunction() + alo() + alo2() + +# Now the problem is when i import this file in Day3_2.py if my function are globaly calling each they will call them there too thats we use this + +if __name__ == "__main__": + main() + # now it will only call the function in this file make complications less \ No newline at end of file diff --git a/week_1/day3/Week 1 Day 3 ClassCode.py b/week_1/day3/Week 1 Day 3 ClassCode.py new file mode 100644 index 0000000..16a951c --- /dev/null +++ b/week_1/day3/Week 1 Day 3 ClassCode.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python +# coding: utf-8 + +# Reverse Indexing in list + +# In[1]: + + +i = [1,2,3,4,4,3] + + +# In[2]: + + +i[-1] + + +# Add something in list + +# In[3]: + + +i.append('hi') + + +# In[4]: + + +i + + +# Array mst have homogenous element where as list hae hetrogenous elements + +# In[5]: + + +l2 = ['áli','sara','kahn','muheeb'] + + +# Mix to lists + +# In[7]: + + +l2.extend(i) + + +# In[8]: + + +i + + +# In[10]: + + +l2 + + +# Remove Specific Character but its first ocuurence only + +# In[11]: + + +l2.remove(3) + + +# In[18]: + + +l2 + + +# Remove from last or from any index + +# In[19]: + + +l2.pop() + + +# list comprehention + +# In[20]: + + +l1 = [1,1,2,4,3,9,7,5,1,11,2,44] + + +# In[33]: + + +def iseven(el): + return el % 2 == 0 +oddl1 = [el for el in l1 if el % 2 != 0] + + +# In[34]: + + +oddl1 + + +# In[42]: + + +def square1(el): + return el * el +oddl1sqaure = [square1(i) for i in oddl1] + + +# In[43]: + + +oddl1sqaure + + +# List are copy by refrence + +# In[46]: + + +l1 = [1,2,3,4,5] +l2 = l1 +print(l1) +l2.append(5) +print(l1) +print(l2) + + +# Solution of the problem + +# In[48]: + + +l3 = l1.copy() + + +# In[49]: + + +l3 + + +# Chunks slicing + +# In[55]: + + +# refrence [initial : final-1 : steps] +l3[1:5] + + +# In[63]: + + +l3[0:4:1] + + +# In[65]: + + +l3[::2] + + +# Class activity
+# give last twoo elements
+# write the function to skil elements from start and end + +# In[68]: + + +l = [2,2,3,4,5,6,3,42,53,542,22,22] +len(l) + + +# Tuples
+# Not mutable + +# In[69]: + + +a = (1,2,3,5) +b = (5,3,2,4) + + +# In[70]: + + +a[1] + + +# In[71]: + + +a[1] = 34 + + +# Remove white spaces + +# In[74]: + + +st = " \n\n\n\n shahab bukhari \n\n " + + +# In[75]: + + +st + + +# In[76]: + + +print(st) + + +# In[79]: + + +st = st.replace("\n",'') + + +# In[80]: + + +st + + +# In[82]: + + +st.replace(' ','') + + +# In[84]: + + +st2 = " \n\n\n\n shahab bukhari \n\n " +st2 + + +# In[86]: + + +st2.strip() + + +# In[87]: + + +'shahab' in st2 + + +#

Palindrom Example

+ +# In[91]: + + +l1 = [5,4,3,2,1] + + +# In[93]: + + +l1[::-1] + + +# In[97]: + + +'madam' == 'madam'[::-1] + + +# dictionary + +# In[103]: + + +dic = { + 'Islamabad': 'Nust', + 'karachi': 'NED', + 'lahore': 'Uet' +} +print(dic.keys()) +print(dic.items()) +print(dic.get('karachi','not found')) +print(dic.get('faislabad','not found')) +print(dic.get('lahore','not found')) + + +# In[ ]: + + + + diff --git a/week_1/readme.md b/week_1/readme.md index 1660724..f2bd6f0 100644 --- a/week_1/readme.md +++ b/week_1/readme.md @@ -1,3 +1,892 @@ -# DSC-DSU | Python Bootcamp 2020 | Week 1 +## Week 1, Day 1 -Paste questions and brief writeup here +### Day 1 we have learn + +- [Python Installation](<###\ Python\ Installation>) +- [Path Configuration (Windows only)](<###\ Path\ Configuration\ (Windows\ only)>) +- [What is PIP?](<###\ What\ is\ PIP?>) +- [How does Python code run?](<###\ How\ does\ Python\ code\ run?>) +- [Running Python: **Interactive shell (terminal)**](<###\ Running\ Python:\ **Interactive\ shell\ (terminal)**>) +- [Running Python: **Interactive Python notebooks (Jupyter Notebook/Google Colab)**](<###\ Running Python: **Interactive Python notebooks (Jupyter Notebook/Google Colab)**>) +- [Running Python: **Scripts**](<###\ Running\ Python:\ **Scripts**>) + +<<<<<<< HEAD +## Week 1, Day 2 + +By _Bahawal Baloch_, Python@DSU Co-Lead and Core Team member + +## Naming Convention + +The standard naming convention to be followed through out the Python developers. This is the PEP8 naming convention, for more detailed code guidelines: [PEP8](https://www.python.org/dev/peps/pep-0008/). + +[Naming Convention Table](https://www.notion.so/8df8f18fd31340d8a65b2abcf0ebdc91) + +## Variables + +- Dynamically typed + + ```python + x = "Hello world" + x = 1.25 + x = 5 + ``` + + - No need to initialize variables with data types, like so: + + ```cpp + int x = 5; + ``` + +### Primitive Datatypes + +1. int +2. float +3. string(str) +4. bool + + ```python + bool(True) + True + + bool(False) + False + + bool(1) + True + + bool(0) + False + + bool(None) + False + + bool([]) + False + + bool('') + False + ``` + +### Global vs local scope + +In most programming languages, variables, classes and objects (and sometimes functions) have scope where they may be referenced and mutated, Python also has a global and local scope. + +- Global variables as their name suggests may be accessed through out the program, however cannot be referenced from a function's local scope. +- Local variables exist within a function's scope and cannot be accessed outside that function. + +```python +x = "global" +def foo(): + print("x inside:", x) +foo() +print("x outside:", x) +# Output +# x inside: global +# x outside: global +``` + +```python +x = 5 + +def foo(): + x = x * 2 + print(x) + +foo() + +# Output +# UnboundLocalError: local variable 'x' referenced before assignment +``` + +- Using the `global` keyword you can mutate a global variable in a local scope. + + ```python + x = 5 + + def foo(): + global x + x = x * 2 + print(x) + + foo() + + # Output + # 10 + ``` + +### Printing in Python + +- F-strings +- Format() + +### Input + +![Lecture%20Notes%20ab4cded2c8ea400186b447dadfc415bf/Untitled.png](Lecture%20Notes%20ab4cded2c8ea400186b447dadfc415bf/Untitled.png) + +### Casting types + +![Lecture%20Notes%20ab4cded2c8ea400186b447dadfc415bf/Untitled%201.png](Lecture%20Notes%20ab4cded2c8ea400186b447dadfc415bf/Untitled%201.png) + +### Swapping variables without third variable + +In conventional language, you require a intermediate variable to swap variables (unless you involve some integer mathematics) + +```python +x=1 +y=2 + +temp = x +x = y +y = temp +# y becomes 1 and x becomes 2 +``` + +```python +x = 5 +y = 8 +print(x,y) +x,y = y,x +print(x,y) +``` + +## Control Structure + +- `if` + + conditional statement with change the control of program + + if condition is true: + + do this + +- `else` + + else if a block of code which is written after an if statement and only execute if the "if" condition is not satisfied + +- `elif` + + short for else if + + used to make ladder if else condition + +```python +x = int(input()) +if x > 5 : + print("x is greater than 5") +elif x < 5 : + print("x is less than 5") +else : + print("x is equal to 5") + +``` + +## Loops + +- `for` + + - Use case scenario is when number of iterations are **_known_** + + ```python + for i in range(100): #do something 100 times, increment value in i + ``` + + - What does `range` function do? + + A function which generates a list (we'll discuss lists in detail tomorrow) in the format required: _(start, end, step)_ + + start default is 0, step default is 1 + + ```python + range(5) + # [0,1,2,3,4] + ``` + + ```python + range(1,5) + # [1,2,3,4] + ``` + + ```python + range(0,5,2): + # [0,2,4] + ``` + + - Iterating over a collection (again, we'll discuss in detail in next lecture) + + ```python + l = [1,2,3,4] + for i in l: + print(i) + + # 1,2,3,4 + ``` + +- `while` + + - Use case scenario is when number of iterations are **_unknown_** + + ```python + x = 0 + while x < 100: + print(x) + x+=1 + + # same output as **for i in range(100)** + ``` + +- `break`, `continue` + + Are control statements to be used when you want to skip an iteration based on some condition or break the loop operation entirely + + - Give some use case of `continue` + + ```python + for letter in 'Python': + if letter == 'h': + continue + print('current letter :',letter) + ``` + + - Give some use case of `break` + + ```python + for letter in 'Python': + if letter == 'h': + break + print('current letter :',letter) + ``` + +## Week 1, Day 3 + +By _Tarun Kumar_, **Python@DSU Lead** and Core Team **DSC@DSU** + +### Index + +- [Functions](<###\ Functions>) +- [Main function](<###\ Main\ function>) +- [Importing scripts into other scripts](<###\ Importing\ scripts\ into\ other\ scripts>) +- [Lists](<###\ Lists>) +- [List Indexing](<###\ List\ Indexing>) +- [Common List Functions](<###\ Common\ List\ Functions>) +- [Iterating over lists](<###\ Iterating\ over\ lists>) +- [List Comprehension](<###\ List\ Comprehension>) +- [List is copy by reference](<###\ List\ is\ copy\ by\ reference>) +- [Tuples](<###\ Tuples>) +- [Destructuring Lists or Tuples](<###\ Destructuring\ Lists\ or\ Tuples>) +- [Strings](<###\ Strings>) +- [String functions](<###\ String\ functions>) +- [Dictionaries](<###\ Dictionaries>) +- [Defining dictionaries](<###\ Defining\ dictionaries>) +- [Accessing dictionaries](<###\ Accessing\ dictionaries>) +- [Updating and adding values to dictionaries](<###\ Updating\ and\ adding\ values\ to\ dictionaries>) +- [Dictionary keys](<###\ Dictionary\ keys>) +- [Dictionary functions and operators](<###\ Dictionary\ functions\ and\ operators>) + +### Functions + +Before we move onto those, I will introduce a building block of any programming language and that is a **function**. + +Defining a function in Python is as sample as: + +```python +def function_name(arg1,arg): +``` + +Now we've gone over the scope of variables previously, however to refresh the concept: + +A function will have **read and write** access to: + +- All variables defined inside it +- Mutable variables (list, set, dict) passed to it through arguments + +A function will have **read only** access to: + +- Global variables \* +- Immutable variables (int, bool, float, str) passed to it through arguments \* + +* While you can assign values to either global variables and passed immutable variables in a function, their value will stay as a local copy to the variable. + +\*\* You can however also modify global variables by initializing `global` keyword on the variable before mutating it, like so: + +```python +var = 5 + +def func(): + var = 6 # global value doesn't change + +def func2(): + global var + var = 24 # global value becomes 24 + +func() +print(var) # output: 5 +func2() +print(var) # output: 24 +``` + +### Main function + +Now for those coming from C/C++ might be familiar with the concept of a `main` function which acts as an _entry-point_ to your code. Contrary to that, `main` function doesn't exist for languages like Python or JavaScript since the whole code is essentially an entry-point and in other words a `main` function. + +However, worry not, for it is considered a good practice at times to have a `main` function calling other functions and acting as an entry point to your whole code in Python as well. + +To emulate a similar concept here we have a special variable called `__name__` that defaults to a constant `'__main__'` + +These variables are initialized when executing a script using the interpreter, i.e `python script.py` will initialize the `__name__` variable for that script to `'__main__'` + +To execute a specific function i.e the main function, we simply do a if check globally and execute that function. The `main` function that is defined below can be of any name. + +```python +def main(): # the name of function can be anything, make sure that name is called tho + print("Main function") + +print("global scope") +if __name__ == '__main__': + main() + +#output +# global scope +# Main function +``` + +```python +# Suppose this is foo.py + +print("before import") +import math + +print("before functionA") +def functionA(): + print("Function A") + +print("before functionB") +def functionB(): + print("Function B {}".format(10)) + +print("before __name__ guard") +if __name__ == '__main__': + functionA() + functionB() +print("after __name__ guard") + +## What will be the output? +``` + +### Importing scripts into other scripts + +You can include existing scripts into your script by using the `import` keyword, you can reference the functions and global variables defined in other scripts. + +For example: + +Suppose we have two scripts `[foo.py](http://foo.py)` and `[bar.py](http://bar.py)` and they're in the same folder: + +```python +./ + |-foo.py + |-bar.py +./ +``` + +```python +# foo.py +global_variable = 'global' +def is_even(n): + return n % 2 == 0 + +def main(): + x = 2 + if is_even(x): + print(f"{x} is even") + else: + print(f"{x} is odd") +if __name__ == '__main__': + main() + +## output +# 2 is even +``` + +```python +# bar.py +import foo + +print(f"Global value in foo.py is {foo.global_variable}") +x=5 +if foo.is_even(x): # we can reference the other script's function using . + print(f"{x} is even") +else: + print(f"{x} is odd") + +## output +# Global value in foo.py is global +# 5 is odd +``` + +Question arises, why doesn't `main` function of `[foo.py](http://foo.py)` execute automatically? + +And answer is that when you import another script, that script's `__name__` is initialized to it's original name, in this case `foo` and hence the `if` statement fails to call the main function. + +Let's modify `[foo.py](http://foo.py)` to print `__name__` if it's not equal to `'__main__'` i.e in the case it's being imported. + +```python +#foo.py +... +if __name__ == '__main__': + main() +else: + print(__name__) +``` + +Now if I execute `[bar.py](http://bar.py)` I get a different output + +```bash +# before + Global value in foo.py is global + 5 is odd + +# after... +foo #going into else in foo.py and printing __name__ +Global value in foo.py is global +5 is odd +``` + +### Lists + +A collection of variables or items in Python is called a list, which is the same as an array in other languages but a Python list can also contain **non-homogeneous** items. + +```python +l = [1,2,3] +l = [2,2.3,'abc'] #Python list can contain non-homogeneous items + +``` + +### List Indexing + +Just like a normal array, the Python list is **also indexed by `0`** + +```python +l = [1,2,3] +l[0] # returns 1 +``` + +However the index `i` doesn't need to be positive integer (i.e ≥ 0), in _Python_ you can use negative integers for reverse indexing, i.e getting elements from end of array. + +Negative indexing starts from -1, instead of 0. + +i.e + +```python +l[-1] #returns last element, 3 +l[-2] #returns second last element, 2 +l[-4] #index out of range +``` + +### Common List Functions + +- `len` + + ```python + # no of items in the list + l = [1,2,3,'str'] + print(len(l)) # returns 4 + ``` + +- `append` + + ```python + # adds an item to end of list + l = [1,2,3] + l.append(4) # l becomes [1,2,3,4] + ``` + +- `extend` + + ```python + # to extend a list with all items of other list + l1 = [1,2,3] + l2 = [4,5,6] + l1.append(l2) # it's an inplace operation,i.e returns nothing + + # alternatively, you can also use + operator to do out of place extension + l1 = [1,2,3] + l2 = [4,5,6] + l3 = l1+l2 # l1 and l2 are unchanged, l3 becomes [1,2,3,4,5,6] + ``` + +- `remove` + + ```python + # to remove element by value from a list, first found! + l = [1,2,3,4,4] + l.remove(4) # again, an in-place operation removes 4 from the list + # new list becomes [1,2,3,4], the first 4 found is removed + ``` + +- `pop` + + ```python + # to remove an element by it's index and return it, if left empty removes last item + l = [1,2,3,4] + a = l.pop(3) # 4 is removed from the list and stored in a, new list becomes [1,2,3] + ``` + +### Iterating over lists + +There are two ways to iterate over list items: + +Conventional index incrementing: + +```python +l = [1,2,3,4] +for i in range(len(l)): + print(i, end=' ') +# output +# 1 2 3 4 +``` + +Using list iterator: + +```python +l = [1,2,3,4] +for i in l: # acts in a similar fashion as 'for each' or 'foreach' + print(i, end=' ') +# output +# 1 2 3 4 +``` + +### List Comprehension + +Python provides a syntactic sugar to unpack a list in a single line + +```python +l = [1,2,3,4] +even_list = [i for i in l if i%2==0] # even_list has all even items from l +squared_list = [i*i for i in l] # squares every element of l +``` + +You can check out [https://realpython.com/list-comprehension-python/](https://realpython.com/list-comprehension-python/) for more detailed overview + +### List is copy by reference + +The datatypes that we discussed in last 1.2 were primitive and were passed by copies, however lists are passed by references to save memory (imagine making copies of a list with million items), which means that `listA = listB` actually means any modifications made to either of references(`listA` or `listB`) will be mirrored because both variables refer to same memory space. + +```python +# pass by copy +a=5 +b=a +b=6 # a stays 5, b becomes 6 + +# pass by reference +l1 = [1,2,3] +l2 = l1 +l2.pop() # pop is discussed above, it removes given element or last element + +# l1 and l2 both become [1,2] +``` + +## List chunk or slicing + +Just like our `range(start, stop, step)` function which produces a list given parameters, in a similar fashion we can also retrieve specific parts of our array and in required format using `list[start:stop:step]` + +```python +l = [51,45,234,75,55] + + +# give me elements starting with index 0 and stop before index 2, +l[0:2] # output: [51,45] +# just like the range function stops before stop + +# empty start is defaulted to 0 +l[:2] # output: [51,45] + +l[:] # [1,2,3,4,5] likewise empty stop is defaulted to length of list + +# give even **index** elements (0,2,4) +l[::2] # [51,234,55] + +#give odd **index** elements (1,3) +l[1::2] # [45,75] + +#step could also be negative, i.e to reverse a list +l[::-1] # [55,75,234,45,51] +# ^ start from 0 add -1 (i.e decrement 1) till + +#class activity: +# give last two elements +# write function to skip n elements from start and end + +``` + +### Tuples + +Tuples are almost same as Lists, in the sense that they're a collection of items. However key difference is that you cannot mutate a tuple, i.e add or remove items from it after initialization. + +```python +# Tuples are defined using round braces instead of square as in lists +a = (1,2) + +# however, they're indexed in a similar fashion +print(a[0]) # output 1 +``` + +In a world of lists, a tuple might not make sense at first. But one can use tuples when: + +1. Immutability of list contents is required +2. More optimized performance +3. Useful when indexes have semantic meaning. For example `point[0], point[1]` might represent x,y coordinates +4. Objects are heterogeneous, think as if a struct in C/C++ or custom storage + +### Destructuring Lists or Tuples + +```python +a,b = [1,2] +a,b = (1,2) + +# a becomes 1 +# b becomes 2 +``` + +### Strings + +While we did discuss `str` datatype in our previous session, however we didn't go into the details of it. Strings are basically lists of characters, but in Python there's no `char` datatype, even a single alphabet is a `str` in Python + +```python +a = 'a' +type(a) # str +``` + +- You can use either `''`, `""` and even `''' '''` + +Unlike lists however, Python strings are immutable. + +```python +name = 'tarun' +print(name[0]) # prints 't' +name[0] = 'b' # error, cannot mutate + +``` + +### String functions + +- `lower` and `upper` + + Make all letters lowercase and uppercase, respectively: + + ```bash + >>> "tarun".lower() + 'tarun' + >>> "TARUNnn".lower() + 'tarunnn' + + >>> "tarun".upper() + 'TARUN' + >>> "tArun".upper() + 'TARUN' + ``` + +- `islower` or `isupper` + + Returns whether a string is all lower or all upper + + ```bash + >>> "tarun".islower() + True + >>> "taruN".islower() + False + >>> "TARUN".isupper() + True + ``` + +- `strip` + + Removes any leading or trailing spaces in a string. + + Will be extensively used as we move forward towards web scraping. + + ```bash + >>> " tarun".strip() + 'tarun' + >>> " tar un".strip() + 'tar un' + >>> "tarun\n\n".strip() + 'tarun' + ``` + +- `replace` + + Replaces a substring in your string with another substring + + ```bash + >>> "kumarr".replace("rr","r") + 'kumar' + >>> "tarun kumar".replace(" ","\t") + 'tarun\tkumar' + ``` + +- `find` + + Return index of where a substring is first found in a str (case sensitive) + + ```bash + >>> quote = 'Let it be, let it be, let it be' + >>> + >>> # first occurrence of 'let it'(case sensitive) + >>> result = quote.find('let it') + >>> print("Substring 'let it':", result) + Substring 'let it': 11 + >>> + >>> # find returns -1 if substring not found + >>> result = quote.find('small') + >>> print("Substring 'small ':", result) + Substring 'small ': -1 + ``` + +- substring `in` str + + Returns `True` if a substring exists in a string. + + ```bash + >>> "ta" in "tarun" + True + >>> "Ta" in "tarun" + False + ``` + +### Dictionaries + +Dictionaries are Python's key-value stores, similar to JavaScript's Object. + +Imagine an array which you can index and reference by strings. + +Some properties of dictionaries shared by lists. + +- Mutable +- Dynamic +- Support for nested elements + +### Defining dictionaries + +```bash +>>> PSL_teams = { +... "Islamabad":"Islamabad United", +... "Karachi":"Karachi Kings", +... "Lahore":"Lahore Qalandars", +... "Multan":"Multan Sultans", +... "Quetta":"Quetta Gladiators", +... "Peshawar":"Peshawar Zalmi" +... } +``` + +### Accessing dictionaries + +```bash +>>> PSL_teams["Karachi"] +'Karachi Kings' +>>> PSL_teams["Islamabad"] +'Islamabad United' +>>> PSL_teams["Shikarpur"] +Traceback (most recent call last): + File "", line 1, in +KeyError: 'Shikarpur' +``` + +### Updating and adding values to dictionaries + +```bash +PSL_teams["Lahore"] = "Lahore Lions" +PSL_teams["Thatta"] = "Thatta Tigers" # creates a new entry +``` + +### Dictionary keys + +While I mentioned above it's good practice to have strings as dictionary keys, however Python doesn't stop you from using: + +```bash +# ints +>>> d = {0:"Tarun"} +>>> d[0] +'Tarun' +# floats +>>> d = {1.2:"Tarun"} +>>> d[1.2] +'Tarun' + +# however you cannot use mutable objects like lists, dicts as keys +>>> d = {[1,2]:4} +Traceback (most recent call last): + File "", line 1, in +TypeError: unhashable type: 'list' +``` + +### Dictionary functions and operators + +- `in` + + Check whether a key value pair exists in the dictionary + + ```bash + >>> "Karachi" in PSL_teams + True + >>> "Shikarpur" in PSL_teams + False + ``` + +- `len` + + Find number of key-value pairs in a dict + + ```bash + >>> PSL_teams + {'Islamabad': 'Islamabad United', + 'Karachi': 'Karachi Kings', + 'Lahore': 'Lahore Qalandars', + 'Multan': 'Multan Sultans', + 'Quetta': 'Quetta Gladiators', + 'Peshawar': 'Peshawar Zalmi'} + + >>> len(PSL_teams) + 6 + ``` + +- `get` + + Finds the value for given key otherwise returns a default value. This is used if you're not sure whether a dict contains a key-value pair or not. + + ```bash + >>> PSL_teams.get("Shikarpur") # returns none, hence nothing printed + >>> PSL_teams.get("Shikarpur","Not found") + 'Not found' + ``` +======= + for printing characters diagonaly i create a loop which have range of user input then i add spaces at each itration then the character of user input + +
+2. Create a program to take as input 5 student records in the following format: + +
+
+>>>>>>> c2dfbd5daa4bc2edecc870e02d7be60c845ce70a + +- `.keys()` `.values()` and `.items()` + +<<<<<<< HEAD + ```bash + >>> PSL_teams.keys() + dict_keys(['Islamabad', 'Karachi', 'Lahore', 'Multan', 'Quetta', 'Peshawar']) + + >>> PSL_teams.values() + dict_values(['Islamabad United', 'Karachi Kings', + 'Lahore Qalandars', 'Multan Sultans', + 'Quetta Gladiators', 'Peshawar Zalmi']) + + >>> PSL_teams.items() + dict_items([('Islamabad', 'Islamabad United'), + ('Karachi', 'Karachi Kings'), + ('Lahore', 'Lahore Qalandars'), + ('Multan', 'Multan Sultans'), + ('Quetta', 'Quetta Gladiators'), + ('Peshawar', 'Peshawar Zalmi')]) + ``` +======= +store a song in a song variable then split it at every part which has , then print all the parts at 1 sec delay +>>>>>>> c2dfbd5daa4bc2edecc870e02d7be60c845ce70a diff --git a/week_2/class work/fileSorter.py b/week_2/class work/fileSorter.py new file mode 100644 index 0000000..19e476c --- /dev/null +++ b/week_2/class work/fileSorter.py @@ -0,0 +1,51 @@ +import os +import shutil +curentDir = input('Enter the Path:') +extensions = ['pdf','deb','jpg','txt','tar','mp4','png','mp3','sh'] + +for folder, subfolders, filenames in os.walk(curentDir): + + # Avoid these Folders + subfolders[:] = [subfolder for subfolder in subfolders for i in extensions if subfolder!= i] + + #rint(f'the current working folder is: {folder}') + + # Itrate over all the files in the curent folder + for filename in filenames: + + # Extract the file extension from filename + fileExt = (filename.split('.'))[1:2] + print(fileExt) + + for i in range(len(extensions)): + + # # Move file to directory + # def moveF(dirt): + # shutil.move((curentDir+'/'+filename),(curentDir+"/"+extensions[i]+'/'+filename)) + + + # Check the file with every possible extension + if fileExt[0] == extensions[i]: + + #Creates the Directory path based on the Extension + dirt = os.path.join(curentDir, extensions[i]) + + # Check if the directory is already created + if os.path.isdir(dirt): + #Just Moved the file to the directory + print(f'this {filename} file is moved') + shutil.move((curentDir+'/'+filename),(curentDir+"/"+extensions[i]+'/'+filename)) + else: + # First Create the Directory + os.mkdir(dirt) + # then move the file + print(f'this {filename} file is move') + shutil.move((curentDir+'/'+filename),(curentDir+"/"+extensions[i]+'/'+filename)) + + else: + #Make Directory for other files + dirt = os.path.join(curentDir, 'Others') + os.mkdir(dirt) + # then move the file + print(f'this {filename} file is moved') + shutil.move((curentDir+'/'+filename),(curentDir+"/"+extensions[i]+'/'+filename)) \ No newline at end of file diff --git a/week_2/readme.md b/week_2/class work/readme.md similarity index 100% rename from week_2/readme.md rename to week_2/class work/readme.md diff --git a/week_2/class work/test.py b/week_2/class work/test.py new file mode 100644 index 0000000..4c7b3f4 --- /dev/null +++ b/week_2/class work/test.py @@ -0,0 +1,38 @@ +import csv + +# Name print diagonally +with open('txt.csv') as songFile: + data = csv.reader(songFile,delimiter=',') + count = 0 + for row in data: + for i in row[0]: + print(' '*count,i) + count += 1 + count = 0 + +# Add Record +with open("txt.csv",mode='a') as class_record: + fieldnames = ['name', 'roll number','age','marks'] + record_entry = csv.DictWriter(class_record,fieldnames=fieldnames) + count = 0 + more = True + + while more: + name = input('name:') + roll_number = int(input('Roll Number:')) + age = int(input('Age:')) + marks = int(input('Marks')) + + record_entry.writerow({'name':name,'roll number':roll_number,'age':age,'marks':marks}) + + ans = input('Do you want to add more') + if ans == 'no': + more = False + +with open('txt.csv') as read_record: + read_entry = csv.DictReader(read_record) + + print('Name | Roll numbers | Age | Marks') + + for row in read_entry: + print(row['name'],' | ',row['roll number'],' | ',row['age'],' | ',row['marks']) \ No newline at end of file diff --git a/week_2/class work/txt.csv b/week_2/class work/txt.csv new file mode 100644 index 0000000..a4796b5 --- /dev/null +++ b/week_2/class work/txt.csv @@ -0,0 +1,5 @@ +name,roll number,age,marks +Shahab,2020,20,200 +ali,2020,21,32 +kashid,875,25,356 +maleeha,548,21,658 diff --git a/week_3/bot.gif b/week_3/bot.gif new file mode 100644 index 0000000..73be4c1 Binary files /dev/null and b/week_3/bot.gif differ diff --git a/week_3/fbBot.py b/week_3/fbBot.py new file mode 100644 index 0000000..6b8aee4 --- /dev/null +++ b/week_3/fbBot.py @@ -0,0 +1,75 @@ +from selenium import webdriver +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.by import By +from selenium.webdriver.chrome.options import Options + +driver = webdriver.Chrome() + +def main(): + fb = 'https://m.facebook.com/' + post_url = 'https://m.facebook.com/DeveloperStudentClubDHASuffaUniversity/photos/a.1451042185216529/2839108256409908/' + my_review = 'CHALLENGE ACCEPTED. I name is shahab. I am doing BSCS currently in 1st semester. course was amazing. short and concise. i will explore data science and Ml after this bootcamp and try to excel my python knowledge. instructors were great especialy tarun they exlained everything simply and in a fun i enjoyed the and waiting for another one. Other than the cuuriculum i learn exception handling problem solving skills and many more. i try to learn more about open-source and try to contribute and maybe try GSOC(need tips in this) and. yes plz make some other bootcamp love to participate' + share_caption = "This post was shared using a bot that I learnt to create from Python Bootcamp 2020 held by DSC@DSU. #DSCDSU #DeveloperStudentClubs #DSCPakistan #Python #Bot" + + get_to(fb) + login() + like(post_url) + comment(post_url,my_review) + share(share_caption,post_url) + +def get_to(url): + driver.get(url) + +def login(): + # Enter your email password here + email = '' + password = input('') + + email_frm = driver.find_element_by_id("m_login_email") + pass_frm = driver.find_element_by_id("m_login_password") + login_btn = driver.find_element_by_css_selector('#u_0_4 button') + + email_frm.send_keys(email) + pass_frm.send_keys(password) + login_btn.click() + + # Cencel save password window + WebDriverWait(driver, 10).until(EC.presence_of_element_located( + (By.CSS_SELECTOR, "div._2pii div a"))).click() + +def like(post_url): + get_to(post_url) + like_btn = driver.find_element_by_id('u_0_s') + like_btn.click() + +def comment(post_url,review): + get_to(post_url) + paragraphs = review.split(".") + + for i in paragraphs: + commt_area = WebDriverWait(driver, 10).until(EC.element_to_be_clickable( + (By.CSS_SELECTOR, "div.mentions textarea#composerInput"))) + commt_area.send_keys(i) + + post_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable( + (By.CSS_SELECTOR, 'button[data-sigil="touchable composer-submit"]'))) + post_btn.click() + +def share(cap,post_url): + get_to(post_url) + share_btn = driver.find_element_by_css_selector('a[data-sigil="share-popup"]').click() + + write_post = WebDriverWait(driver, 10).until(EC.presence_of_element_located( + (By.ID, "share-with-message-button"))).click() + + post_msg = WebDriverWait(driver, 10).until(EC.presence_of_element_located( + (By.CSS_SELECTOR, 'textarea#share_msg_input'))) + post_msg.send_keys(cap) + + post_btn = driver.find_element_by_css_selector('div#modalDialogHeaderButtons button#share_submit').click() + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/week_3/readme.md b/week_3/readme.md index 1660724..a671e15 100644 --- a/week_3/readme.md +++ b/week_3/readme.md @@ -1,3 +1,122 @@ -# DSC-DSU | Python Bootcamp 2020 | Week 1 +# DSC-DSU | Python Bootcamp 2020 | Week 3 | Facebook Bot -Paste questions and brief writeup here +## Problem Statement +1. **TAKE AS USER INPUT A FACEBOOK POST LINK AND HAVE YOUR BOT LIKE THE POST AND SHARE IT ON YOUR TIMELINE** + - You'll need to use m.facebook.com for ease + - For submission, like and share this post: [Facebook Post](https://www.facebook.com/Developer.../posts/2838706263116774) + - The shared post should have the following caption(also sent through Selenium bot):"This post was shared using a bot that I learnt to create from Python Bootcamp 2020 held by DSC@DSU. #DSCDSU #DeveloperStudentClubs #DSCPakistan #Python #Bot" + The caption is not strict, but should contain the hashtags even if you modify your message according to your flavor. + - You'll need to submit a video recording of you running the script and showing the bot performing the liking and sharing of above mentioned post. +2. **OPTIONAL, EXTRA MARKS: MAKE THE BOT CREATED ABOVE MAKE AT LEAST 50 COMMENTS IN SUCCESSION ON THE PAGE. THESE 50 COMMENTS SHOULD BE LINES SPLIT FROM A PARAGRAPH YOU MAY WRITE ON:** + - Your aims and goals after this bootcamp? + - How did you like the instructors and the management? + - What did you learn from the bootcamp? + - Would you be willing to carry the legacy forward for a free, open source driven tech bootcamp like this one? + +## Output Video +![Bot Liking, Posting And Commenting on Post](./bot.gif) + +## Solution: + +### Code: +Libraries used are +```python +#Selenium Imports +from selenium import webdriver +from selenium.common.exceptions import NoSuchElementException, TimeoutException +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.by import By +``` +First from this this line sellenium driver initiate the browser from global scope. +```python +driver = webdriver.Chrome() +``` +Then main function is responsible of calling all the major function. first it call the get_to() function which open facebook login page then it the login() function whcih will login to your account then the like() function go to the post then like it. then comment function comment every '.' sepreated line one by one from my_review variable then finally it call the share() function which the share the post with caption from share_caption variable +```python +def main(): + fb = 'https://m.facebook.com/' + post_url = 'https://m.facebook.com/DeveloperStudentClubDHASuffaUniversity/photos/a.1451042185216529/2839108256409908/' + my_review = 'CHALLENGE ACCEPTED. I name is shahab. I am doing BSCS currently in 1st semester. course was amazing. short and concise. i will explore data science and Ml after this bootcamp and try to excel my python knowledge. instructors were great especialy tarun they exlained everything simply and in a fun i enjoyed the and waiting for another one. Other than the cuuriculum i learn exception handling problem solving skills and many more. i try to learn more about open-source and try to contribute and maybe try GSOC(need tips in this) and. yes plz make some other bootcamp love to participate' + share_caption = "This post was shared using a bot that I learnt to create from Python Bootcamp 2020 held by DSC@DSU. #DSCDSU #DeveloperStudentClubs #DSCPakistan #Python #Bot" + + get_to(fb) + login() + like(post_url) + comment(post_url,my_review) + share(share_caption,post_url) +``` +main() function only execute when this condition is true only when the script is not being imported and run from somewhere else: +```python +if __name__ == '__main__': + main() +``` +The following function first redirect the page based on the argument url: +``` python +def get_to(url): + driver.get(url) +``` +Following function log in to facebook account. +```python +def login(): + # Enter your email password here + email = '' + password = input('') + + email_frm = driver.find_element_by_id("m_login_email") + pass_frm = driver.find_element_by_id("m_login_password") + login_btn = driver.find_element_by_css_selector('#u_0_4 button') + + email_frm.send_keys(email) + pass_frm.send_keys(password) + login_btn.click() + + # Cencel save password window + WebDriverWait(driver, 10).until(EC.presence_of_element_located( + (By.CSS_SELECTOR, "div._2pii div a"))).click() +``` +Following Function Like the post: +```python +def like(post_url): + get_to(post_url) + like_btn = driver.find_element_by_id('u_0_s') + like_btn.click() +``` +Following function is responsible for commenting on the post +```python +def comment(post_url,review): + get_to(post_url) + paragraphs = review.split(".") + + for i in paragraphs: + commt_area = WebDriverWait(driver, 10).until(EC.element_to_be_clickable( + (By.CSS_SELECTOR, "div.mentions textarea#composerInput"))) + commt_area.send_keys(i) + + post_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable( + (By.CSS_SELECTOR, 'button[data-sigil="touchable composer-submit"]'))) + post_btn.click() +``` +Finaly the final function share the post with caption :) +```python +def share(cap,post_url): + get_to(post_url) + share_btn = driver.find_element_by_css_selector('a[data-sigil="share-popup"]').click() + + write_post = WebDriverWait(driver, 10).until(EC.presence_of_element_located( + (By.ID, "share-with-message-button"))).click() + + post_msg = WebDriverWait(driver, 10).until(EC.presence_of_element_located( + (By.CSS_SELECTOR, 'textarea#share_msg_input'))) + post_msg.send_keys(cap) + + post_btn = driver.find_element_by_css_selector('div#modalDialogHeaderButtons button#share_submit').click() +``` + +## Special Thanks to: +[***Trun Kumar - Instructor***](https://github.com/sinnytk) +[***Bhawal Baloch - instructor***](https://github.com/bahawal32) + +## Credits +README.md is inspired by Bilal Naseem readme template: +[Bilal Naseem](https://github.com/Bilal-Naseem) \ No newline at end of file