├── .gitignore ├── Final-14002 └── Final.pdf ├── HW1-14002 ├── 1 │ └── 1.py ├── 2 │ └── 2.py ├── 3 │ └── 3.py ├── 4 │ └── 4.py └── HW1.pdf ├── HW2-14002 ├── 1 │ └── 1.py ├── 2 │ └── 2.py ├── 3 │ └── 3.py ├── 4 │ └── 4.py └── HW2.pdf ├── HW3-14002 └── HW3.pdf ├── HW4-14002 └── HW4.pdf ├── HW5-14002 ├── HW5.pdf ├── exams.csv └── fifa_data.csv ├── LICENSE ├── Midterm-14002 ├── 1.py ├── 2.py ├── 3.py └── Midterm.pdf ├── Project-14002 ├── Project.pdf ├── project.py └── test_project.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /Final-14002/Final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/Final-14002/Final.pdf -------------------------------------------------------------------------------- /HW1-14002/1/1.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | def main(): 5 | number = parse_number_of_scores() 6 | weight_scores = parse_weight_score(number) 7 | numeric_score = compute_score(weight_scores) 8 | result = to_ch(math.ceil(numeric_score)) 9 | return result 10 | 11 | 12 | def parse_number_of_scores(): 13 | number = input() 14 | return int(number) 15 | 16 | 17 | def parse_weight_score(number): 18 | weight_scores = [] 19 | for i in range(number): 20 | weight, score = input().split() 21 | weight = int(weight) 22 | weight_scores.append((weight, score)) 23 | return weight_scores 24 | 25 | 26 | def compute_score(weight_scores): 27 | sum_ = 0 28 | total_weights = 0 29 | for weight, score in weight_scores: 30 | sum_ += weight * to_numeral(score) 31 | total_weights += weight 32 | numeric_score = sum_ / total_weights 33 | return numeric_score 34 | 35 | 36 | def to_numeral(ch_score): 37 | scores = {'A': 5, 'B': 4, 'C': 3, 'D': 2, 'E': 1, 'F': 0} 38 | return scores[ch_score] 39 | 40 | 41 | def to_ch(num_score): 42 | scores = {5: 'A', 4: 'B', 3: 'C', 2: 'D', 1: 'E', 0: 'F'} 43 | return scores[num_score] 44 | 45 | 46 | if __name__ == '__main__': 47 | final_score = main() 48 | print(final_score) 49 | -------------------------------------------------------------------------------- /HW1-14002/2/2.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | n, m = parse_input() 3 | result = eratosthenes(n, m) 4 | return result 5 | 6 | 7 | def parse_input(): 8 | n = input() 9 | n = int(n) 10 | m = input() 11 | m = int(m) 12 | return n, m 13 | 14 | 15 | def is_prime(number): 16 | if number <= 1: 17 | return False 18 | for i in range(2, number): 19 | if number % i == 0: 20 | return False 21 | return True 22 | 23 | 24 | def least_factor(number): 25 | if number <= 1: 26 | return 1 27 | for i in range(2, number): 28 | if number % i == 0: 29 | return i 30 | 31 | 32 | def eratosthenes(n, m): 33 | if is_prime(m): 34 | return -1 35 | count = 0 36 | for r in range(m): 37 | if not is_prime(r) and least_factor(r) <= least_factor(m): 38 | count += 1 39 | for r in range(m + 1, n + 1): 40 | if not is_prime(r) and least_factor(r) < least_factor(m): 41 | count += 1 42 | return count 43 | 44 | 45 | if __name__ == '__main__': 46 | print(main()) 47 | -------------------------------------------------------------------------------- /HW1-14002/3/3.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | num = parse_input() 3 | stars_coordinates = find_stars(num) 4 | x, y = stars_coordinates[-1] 5 | print(x, y) 6 | draw(num, stars_coordinates) 7 | 8 | 9 | def find_stars(num): 10 | coordinates = [] 11 | for i in range(1, num + 1): 12 | x, y = find_x_y(i) 13 | coordinates.append((x, y)) 14 | return coordinates 15 | 16 | 17 | def draw(num, stars_coordinates): 18 | mat = create_pixels(num) 19 | insert_stars(mat, num, stars_coordinates) 20 | 21 | for row in mat: 22 | print("".join(row)) 23 | 24 | 25 | def insert_stars(mat, num, stars_coordinates): 26 | for x, y in stars_coordinates: 27 | if num % 4 == 0 or num % 4 == 1: 28 | mat[num // 2 - 2 * y][num // 2 + 2 * x] = "* " 29 | if num % 4 == 2: 30 | mat[num // 2 - 1 - 2 * y][num // 2 - 1 + 2 * x] = "* " 31 | if num % 4 == 3: 32 | mat[num // 2 + 1 - 2 * y][num // 2 - 1 + 2 * x] = "* " 33 | 34 | 35 | def create_pixels(num): 36 | if num % 2 == 0: 37 | mat = [[" " for _ in range(num + 1)] for _ in range(num + 1)] 38 | else: 39 | mat = [[" " for _ in range(num)] for _ in range(num)] 40 | 41 | return mat 42 | 43 | 44 | def find_x_y(num): 45 | x, y = 0, 0 46 | if num % 4 == 0: 47 | x, y = - num // 4, num // 4 48 | if num % 4 == 1: 49 | x, y = -(num - 1) // 4, -(num - 1) // 4 50 | if num % 4 == 2: 51 | x, y = (num + 2) // 4, -(num - 2) // 4 52 | if num % 4 == 3: 53 | x, y = (num + 1) // 4, (num + 1) // 4 54 | return x, y 55 | 56 | 57 | def parse_input(): 58 | num = input() 59 | num = int(num) 60 | return num 61 | 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /HW1-14002/4/4.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | n_sentences = parse_n_sentences() 3 | sentences = parse_sentences(n_sentences) 4 | number_of_duplicates(sentences) 5 | count = total_duplicate_adjunct_ch(sentences) 6 | print(count) 7 | 8 | 9 | def total_duplicate_adjunct_ch(sentences): 10 | count = 0 11 | for sentence in sentences: 12 | sentence_words = sentence.split() 13 | for word in sentence_words: 14 | if has_adjunct_ch(word): 15 | count += 1 16 | return count 17 | 18 | 19 | def has_adjunct_ch(word): 20 | for i in range(len(word) - 1): 21 | if word[i] == word[i + 1]: 22 | return True 23 | return False 24 | 25 | 26 | def number_of_duplicates(sentences): 27 | for sentence in sentences: 28 | duplicates = number_of_duplicate_words_in_a_sentence(sentence) 29 | print(duplicates) 30 | 31 | 32 | def number_of_duplicate_words_in_a_sentence(sentence): 33 | sentence_words = sentence.lower().split() 34 | return len(sentence_words) - len(set(sentence_words)) 35 | 36 | 37 | def parse_n_sentences(): 38 | n_sentences = input() 39 | n_sentences = int(n_sentences) 40 | return n_sentences 41 | 42 | 43 | def parse_sentences(n_sentences): 44 | sentences = [] 45 | for i in range(n_sentences): 46 | sentences.append(input().lower()) 47 | return sentences 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /HW1-14002/HW1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/HW1-14002/HW1.pdf -------------------------------------------------------------------------------- /HW2-14002/1/1.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | x1, y1, x2, y2 = parse_input() 3 | print(slope(x1, y1, x2, y2)) 4 | print(intercept(x1, y1, x2, y2)) 5 | print(linear(x1, y1, x2, y2)) 6 | 7 | 8 | def linear(x1, y1, x2, y2): 9 | a = slope(x1, y1, x2, y2) 10 | b = intercept(x1, y1, x2, y2) 11 | if float(b) >= 0: 12 | return f"{a}x+{b}" 13 | return f"{a}x{b}" 14 | 15 | 16 | def slope(x1, y1, x2, y2): 17 | if y1 - y2 == 0: 18 | return f"{0:.2f}" 19 | return f"{(y1 - y2) / (x1 - x2):0.2f}" 20 | 21 | 22 | def intercept(x1, y1, x2, y2): 23 | if y1 * x2 == y2 * x1: 24 | return f"{0:.2f}" 25 | b = y1 - (y1 - y2) / (x1 - x2) * x1 26 | return f"{b:0.2f}" 27 | 28 | 29 | def parse_input(): 30 | line1 = input() 31 | line2 = input() 32 | x1, y1 = line1.split() 33 | x1, y1 = int(x1), int(y1) 34 | x2, y2 = line2.split() 35 | x2, y2 = int(x2), int(y2) 36 | return x1, y1, x2, y2 37 | 38 | 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /HW2-14002/2/2.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | n, m = parse_number_of_cities_airlines() 3 | cities = parse_cities(n) 4 | airlines = parse_air_lines(m) 5 | print_destinations(cities, airlines) 6 | 7 | 8 | def print_destinations(cities, airlines): 9 | for city in cities: 10 | destinations = airlines.get(city, []) 11 | if destinations: 12 | print(len(destinations)) 13 | for dest in destinations: 14 | print(dest) 15 | else: 16 | print(0) 17 | 18 | 19 | def parse_cities(n): 20 | cities = [input() for _ in range(n)] 21 | return cities 22 | 23 | 24 | def parse_air_lines(m): 25 | airlines = dict() 26 | for i in range(m): 27 | start, dest = input().split() 28 | destinations = airlines.get(start, []) 29 | destinations.append(dest) 30 | airlines[start] = destinations 31 | return airlines 32 | 33 | 34 | def parse_number_of_cities_airlines(): 35 | n, m = input().split() 36 | n = int(n) 37 | m = int(m) 38 | return n, m 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /HW2-14002/3/3.py: -------------------------------------------------------------------------------- 1 | import string 2 | 3 | 4 | def main(): 5 | input_str = "Yek CHaractere kheyli AJ!!IB ghA@*Rib Mine$#visim" 6 | input_str = remove_spaces(input_str) 7 | sort(input_str) 8 | 9 | 10 | def sort(input_str): 11 | alphabet = [] 12 | digits = [] 13 | others = [] 14 | for ch in input_str: 15 | if ch in string.ascii_letters: 16 | alphabet.append(ch) 17 | elif ch in string.digits: 18 | digits.append(ch) 19 | else: 20 | others.append(ch) 21 | print(''.join(others) + 22 | ''.join(sorted(digits)) + 23 | ''.join(sorted(alphabet, key=lambda s: s.lower()))) 24 | 25 | 26 | def remove_spaces(input_str): 27 | input_str = ''.join(input_str.split()) 28 | return input_str 29 | 30 | 31 | if __name__ == '__main__': 32 | main() 33 | -------------------------------------------------------------------------------- /HW2-14002/4/4.py: -------------------------------------------------------------------------------- 1 | def controller(): 2 | x = parse_int() 3 | outs = compute(x) 4 | print_results(outs) 5 | 6 | 7 | def print_results(outs): 8 | for element in outs: 9 | print(element) 10 | 11 | 12 | def compute(x): 13 | outs = [] 14 | for _ in range(x): 15 | reach_star = False 16 | n, k = 100, 2 17 | while not reach_star: 18 | inp = input() 19 | if inp == "*": 20 | reach_star = True 21 | outs.append(josephus(n, k)) 22 | elif inp == "n": 23 | n = parse_int() 24 | elif inp == "k": 25 | k = parse_int() 26 | return outs 27 | 28 | 29 | def parse_int(): 30 | return int(input()) 31 | 32 | 33 | def g(n, k): 34 | if n == 1: 35 | return 0 36 | return (g(n - 1, k) + k) % n 37 | 38 | 39 | def josephus(n=100, k=2): 40 | return g(n, k) + 1 41 | 42 | 43 | if __name__ == '__main__': 44 | controller() 45 | -------------------------------------------------------------------------------- /HW2-14002/HW2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/HW2-14002/HW2.pdf -------------------------------------------------------------------------------- /HW3-14002/HW3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/HW3-14002/HW3.pdf -------------------------------------------------------------------------------- /HW4-14002/HW4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/HW4-14002/HW4.pdf -------------------------------------------------------------------------------- /HW5-14002/HW5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/HW5-14002/HW5.pdf -------------------------------------------------------------------------------- /HW5-14002/exams.csv: -------------------------------------------------------------------------------- 1 | "gender","race/ethnicity","parental level of education","lunch","test preparation course","math score","reading score","writing score" 2 | "female","group C","associate's degree","standard","none","44","63","59" 3 | "female","group A","bachelor's degree","free/reduced","none","48","50","54" 4 | "female","group A","some high school","standard","completed","59","78","71" 5 | "male","group C","high school","standard","none","68","72","63" 6 | "male","group E","some college","free/reduced","none","68","64","63" 7 | "male","group B","some high school","free/reduced","completed","47","51","46" 8 | "female","group B","master's degree","free/reduced","completed","84","99","100" 9 | "female","group E","bachelor's degree","standard","none","75","79","73" 10 | "male","group B","some college","standard","none","74","73","72" 11 | "male","group E","bachelor's degree","free/reduced","none","91","80","79" 12 | "female","group B","high school","free/reduced","none","50","61","60" 13 | "female","group C","some college","standard","none","58","68","64" 14 | "female","group B","bachelor's degree","standard","none","55","58","59" 15 | "female","group E","some college","standard","none","73","85","82" 16 | "female","group D","associate's degree","standard","completed","62","77","72" 17 | "male","group B","high school","standard","none","83","73","71" 18 | "female","group A","some high school","free/reduced","none","56","74","66" 19 | "male","group B","high school","free/reduced","none","66","65","63" 20 | "female","group E","high school","standard","completed","100","100","100" 21 | "female","group B","some high school","free/reduced","completed","75","90","84" 22 | "female","group D","master's degree","free/reduced","none","68","75","77" 23 | "male","group B","bachelor's degree","free/reduced","none","74","69","63" 24 | "male","group C","some college","standard","none","91","80","84" 25 | "male","group C","associate's degree","free/reduced","completed","92","88","87" 26 | "female","group C","associate's degree","free/reduced","none","54","61","52" 27 | "female","group E","associate's degree","standard","none","73","71","69" 28 | "female","group D","some college","standard","none","66","72","73" 29 | "male","group E","some high school","free/reduced","none","61","50","46" 30 | "female","group E","some college","standard","none","63","67","66" 31 | "male","group D","associate's degree","standard","none","68","72","64" 32 | "female","group D","associate's degree","free/reduced","completed","68","81","82" 33 | "male","group C","bachelor's degree","standard","completed","88","93","90" 34 | "female","group B","some college","standard","none","39","54","54" 35 | "male","group C","associate's degree","standard","completed","61","68","59" 36 | "male","group D","some high school","standard","none","60","64","61" 37 | "male","group C","some high school","free/reduced","none","63","72","55" 38 | "female","group A","high school","standard","none","41","60","55" 39 | "female","group B","associate's degree","free/reduced","none","37","47","42" 40 | "male","group D","associate's degree","free/reduced","completed","65","57","64" 41 | "female","group C","associate's degree","standard","completed","76","95","96" 42 | "female","group B","some high school","standard","none","50","58","49" 43 | "male","group E","some college","free/reduced","completed","91","83","82" 44 | "male","group C","some high school","standard","none","91","88","77" 45 | "female","group D","high school","standard","none","41","54","53" 46 | "female","group B","associate's degree","free/reduced","completed","51","67","66" 47 | "male","group D","some college","standard","none","81","73","68" 48 | "male","group D","associate's degree","standard","none","100","85","92" 49 | "male","group C","bachelor's degree","standard","completed","83","85","91" 50 | "male","group A","high school","standard","none","51","36","35" 51 | "female","group C","associate's degree","standard","none","40","42","39" 52 | "male","group E","associate's degree","free/reduced","completed","67","69","70" 53 | "female","group A","high school","standard","none","68","79","75" 54 | "female","group B","bachelor's degree","standard","none","60","73","70" 55 | "male","group D","high school","free/reduced","completed","63","68","69" 56 | "female","group C","some college","standard","none","85","85","84" 57 | "female","group B","associate's degree","free/reduced","none","63","76","75" 58 | "male","group B","high school","standard","completed","72","74","72" 59 | "male","group A","some high school","standard","none","67","58","55" 60 | "female","group D","master's degree","standard","none","68","75","76" 61 | "male","group D","some high school","standard","none","80","72","69" 62 | "male","group C","high school","standard","none","82","80","71" 63 | "female","group E","high school","standard","completed","85","79","89" 64 | "female","group B","bachelor's degree","free/reduced","none","38","47","45" 65 | "female","group E","associate's degree","free/reduced","none","76","69","68" 66 | "male","group D","some college","free/reduced","completed","93","87","91" 67 | "male","group E","associate's degree","standard","none","82","72","70" 68 | "male","group B","some high school","standard","none","68","60","63" 69 | "male","group C","some high school","standard","completed","48","61","59" 70 | "female","group D","high school","standard","none","53","55","57" 71 | "female","group E","bachelor's degree","standard","none","80","81","81" 72 | "female","group E","some college","standard","none","63","58","64" 73 | "male","group D","some college","standard","completed","65","62","66" 74 | "female","group B","some college","free/reduced","completed","58","70","71" 75 | "female","group C","high school","standard","none","78","87","86" 76 | "female","group D","some high school","free/reduced","none","25","40","32" 77 | "male","group E","some college","standard","completed","88","78","80" 78 | "female","group D","some college","free/reduced","none","73","82","84" 79 | "male","group C","associate's degree","standard","none","57","44","39" 80 | "female","group B","high school","standard","none","60","68","63" 81 | "male","group D","high school","free/reduced","completed","56","53","60" 82 | "female","group D","high school","standard","none","76","80","84" 83 | "female","group D","high school","free/reduced","none","60","57","54" 84 | "male","group D","bachelor's degree","standard","completed","68","59","60" 85 | "male","group B","some college","free/reduced","none","49","58","51" 86 | "male","group C","high school","free/reduced","completed","46","48","53" 87 | "female","group C","some college","free/reduced","completed","47","58","62" 88 | "male","group D","some college","standard","completed","75","83","82" 89 | "female","group D","associate's degree","standard","none","70","82","82" 90 | "female","group B","some high school","standard","none","80","87","86" 91 | "female","group C","some high school","standard","completed","85","100","95" 92 | "male","group E","associate's degree","standard","none","94","82","80" 93 | "male","group C","some college","free/reduced","none","41","47","46" 94 | "male","group C","high school","standard","none","77","68","70" 95 | "male","group B","high school","standard","none","69","57","54" 96 | "male","group C","some high school","free/reduced","completed","71","69","66" 97 | "male","group B","master's degree","free/reduced","none","85","79","80" 98 | "male","group B","some college","standard","completed","63","67","58" 99 | "female","group C","high school","standard","completed","76","83","79" 100 | "male","group C","bachelor's degree","free/reduced","none","67","74","64" 101 | "male","group C","some college","standard","completed","53","53","56" 102 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Alireza Aghamohammadi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Midterm-14002/1.py: -------------------------------------------------------------------------------- 1 | def is_magical(t): 2 | item = t[0] 3 | list_ = t[1] 4 | # your code goes here 5 | return False 6 | 7 | 8 | if __name__ == '__main__': 9 | assert is_magical((3, [1, 5, 2, 7, 12, 5])) 10 | assert is_magical((7, [3, 23, 4])) 11 | assert is_magical((-3, [-17, 12, 14, 103])) 12 | assert not is_magical((4, [5, 1, 2, 1])) 13 | assert not is_magical((6, [5, 2, 7, 17])) 14 | -------------------------------------------------------------------------------- /Midterm-14002/2.py: -------------------------------------------------------------------------------- 1 | def is_magical(t): 2 | item = t[0] 3 | list_ = t[1] 4 | visited = dict() 5 | # your code goes here 6 | return False 7 | 8 | 9 | if __name__ == '__main__': 10 | assert is_magical((3, [1, 5, 2, 7, 12, 5])) 11 | assert is_magical((7, [3, 23, 4])) 12 | assert is_magical((-3, [-17, 12, 14, 103])) 13 | assert not is_magical((4, [5, 1, 2, 1])) 14 | assert not is_magical((6, [5, 2, 7, 17])) 15 | -------------------------------------------------------------------------------- /Midterm-14002/3.py: -------------------------------------------------------------------------------- 1 | def is_magical(t): 2 | item = t[0] 3 | list_ = t[1] 4 | 5 | list_.sort() 6 | 7 | left = list_[0] 8 | right = list_[-1] 9 | 10 | # your code goes here 11 | return False 12 | 13 | 14 | if __name__ == '__main__': 15 | assert is_magical((3, [1, 5, 2, 7, 12, 5])) 16 | assert is_magical((7, [3, 23, 4])) 17 | assert is_magical((-3, [-17, 12, 14, 103])) 18 | assert not is_magical((4, [5, 1, 2, 1])) 19 | assert not is_magical((6, [5, 2, 7, 17])) 20 | -------------------------------------------------------------------------------- /Midterm-14002/Midterm.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/Midterm-14002/Midterm.pdf -------------------------------------------------------------------------------- /Project-14002/Project.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aaghamohammadi/python-tutor/73bf19b35bf665fd78b4a1008bad934cf6db7cb0/Project-14002/Project.pdf -------------------------------------------------------------------------------- /Project-14002/project.py: -------------------------------------------------------------------------------- 1 | """ 2 | MineSweeper Game - CLI Version 3 | 4 | Developed as part of the Fundamentals of Programming course 5 | Under the supervision of Prof. Alireza Aghamohammadi (@aaghamohammadi on GitHub) 6 | by Amin Hashemi (@minhashemi on GitHub) 7 | 8 | Spring 2021, Sharif University of Technology 9 | """ 10 | 11 | # libraries 12 | import csv 13 | import pandas as pd 14 | import sys 15 | import random 16 | from enum import Enum 17 | import pyfiglet 18 | from tabulate import tabulate 19 | import base64 20 | 21 | # classes - done 22 | class GameStatus(Enum): 23 | PLAYING = 0 24 | LOSE = 1 25 | WIN = 2 26 | 27 | 28 | class MineBoard(object): 29 | score = 0 30 | 31 | def __init__(self, w, h, k): 32 | # Create a new board with size w x h 33 | self.w = w 34 | self.h = h 35 | self.board = [[0 for i in range(w)] for j in range(h)] 36 | self.allocateMines(w, h, k) 37 | self.status = GameStatus.PLAYING 38 | self.cellsToOpen = w * h - k 39 | 40 | def allocateMines(self, w, h, numOfMines): 41 | allocIndexes = self.getRandomPos(w * h, numOfMines) 42 | for i in allocIndexes: 43 | self.setMine(int(i / w), i % h) 44 | self.setAdjacentMines(int(i / w), i % h) 45 | 46 | def printLayout(self): 47 | print(" " * 7 + "".join(map(lambda x: "{:^7d}".format(x + 1), range(self.w)))) 48 | print(" " * 7 + "-" * (self.w * 7)) 49 | for (i, row) in enumerate(self.board): 50 | print( 51 | "{:^7d}".format(i + 1) 52 | + "|" 53 | + " |".join(list(map(lambda x: "{:^5s}".format(self.display(x)), row))) 54 | + " | " 55 | ) 56 | print(" " * 7 + "-" * (self.w * 7)) 57 | 58 | def click(self, row, col): 59 | value = self.reveal(row, col) 60 | if value: 61 | self.cellsToOpen -= 1 62 | MineBoard.score += 10 63 | if self.cellsToOpen == 0: 64 | self.status = GameStatus.WIN 65 | if self.hasMine(row, col): 66 | self.status = GameStatus.LOSE 67 | elif self.isBlank(row, col): 68 | for dr in range(row - 1, row + 2): 69 | for dc in range(col - 1, col + 2): 70 | self.click(dr, dc) 71 | 72 | def flag(self, row, col): 73 | if self.isValidCell(row, col) and self.isHidden(row, col): 74 | self.toggleFlag(row, col) 75 | 76 | def isValidCell(self, row, col): 77 | return row >= 0 and row < self.h and col >= 0 and col < self.w 78 | 79 | def getRandomPos(self, n, k): 80 | res = [] 81 | remains = [i for i in range(n)] 82 | while k > 0: 83 | r = random.randint(0, len(remains) - 1) 84 | res.append(r) 85 | del remains[r] 86 | k -= 1 87 | return res 88 | 89 | # Convention for cell values: 90 | # - 0 : Hidden Blank 91 | # - 10 : Revealed Blank 92 | # - -1 : Hidden Bomb 93 | # - 9 : Revealed Bomb 94 | # - 1 ~ 8 : number of adjacent bomb (hidden) 95 | # - 11 ~ 18 : adjacent bomb (revealed) 96 | # - x + 100 : Flagged 97 | # 98 | 99 | def setMine(self, row, col): 100 | self.board[row][col] = -1 101 | 102 | def setAdjacentMines(self, row, col): 103 | for dr in range(row - 1, row + 2): 104 | for dc in range(col - 1, col + 2): 105 | if self.isValidCell(dr, dc) and not self.hasMine(dr, dc): 106 | self.board[dr][dc] += 1 107 | 108 | def toggleFlag(self, row, col): 109 | if self.isFlagged(row, col): 110 | self.board[row][col] -= 100 111 | else: 112 | self.board[row][col] += 100 113 | 114 | # Open a cell and return its value 115 | def reveal(self, row, col): 116 | if not self.isValidCell(row, col) or not self.isHidden(row, col): 117 | return None 118 | if self.isFlagged(row, col): 119 | self.toggleFlag(row, col) 120 | self.board[row][col] += 10 121 | return self.board[row][col] 122 | 123 | def isHidden(self, row, col): 124 | return self.board[row][col] < 9 125 | 126 | def hasMine(self, row, col): 127 | return self.board[row][col] % 10 == 9 128 | 129 | def isBlank(self, row, col): 130 | return self.board[row][col] % 10 == 0 131 | 132 | def isOver(self): 133 | return self.winGame() or self.loseGame() 134 | 135 | def loseGame(self): 136 | return self.status == GameStatus.LOSE 137 | 138 | def winGame(self): 139 | return self.status == GameStatus.WIN 140 | 141 | def isFlagged(self, row, col): 142 | return self.board[row][col] > 90 143 | 144 | def revealAll(self): 145 | for i in range(len(self.board)): 146 | for j in range(len(self.board[0])): 147 | self.reveal(i, j) 148 | 149 | def display(self, ip): 150 | if ip > 90: 151 | return "F" 152 | elif ip == 9: 153 | return "x" 154 | elif ip == 10: 155 | return "." 156 | elif ip > 10: 157 | return str(ip - 10) 158 | return "*" 159 | 160 | 161 | # functions 162 | # play function - done 163 | def play(): 164 | print("Select game level") 165 | print("[B]eginner, [I]ntermediate, [A]dvanced") 166 | lvl = input("Select game level: ").strip().upper() 167 | if lvl == "B": 168 | size = 10 169 | mine = random.randint(int(0.1 * (size**2)), int(0.3 * (size**2))) 170 | game = MineBoard(size, size, mine) 171 | elif lvl == "I": 172 | size = 15 173 | mine = random.randint(int(0.1 * (size**2)), int(0.3 * (size**2))) 174 | game = MineBoard(size, size, mine) 175 | elif lvl == "A": 176 | size = 25 177 | mine = random.randint(int(0.1 * (size**2)), int(0.3 * (size**2))) 178 | game = MineBoard(size, size, mine) 179 | else: 180 | print("I didn't Understand! Try again...") 181 | play() 182 | 183 | while not game.isOver(): 184 | game.printLayout() 185 | command = nextCommand() 186 | if command == "Q": 187 | main() 188 | splits = command.split(" ") 189 | row = int(splits[0]) - 1 190 | col = int(splits[1]) - 1 191 | if command[-1] == "F": 192 | game.flag(row, col) 193 | else: 194 | game.click(row, col) 195 | 196 | game.revealAll() 197 | game.printLayout() 198 | if game.loseGame(): 199 | print("Game Over 😵") 200 | 201 | elif game.winGame(): 202 | print("You won! Congradulations 🤩") 203 | 204 | 205 | def nextCommand(): 206 | return ( 207 | input( 208 | "Commands : \n : open cell\n F : flag cell\nq : quit\n" 209 | ) 210 | .strip() 211 | .upper() 212 | ) 213 | 214 | 215 | # main page - done 216 | def main(): 217 | print(pyfiglet.figlet_format("MineSweeper", font="speed")) 218 | print("Open as many cells as you can without hitting a bomb 💣") 219 | print("=====================") 220 | print("1.Login") 221 | print("2.Sign Up") 222 | print("3.Score Board") 223 | print("4.Exit") 224 | print("=====================") 225 | mainOptions() 226 | 227 | 228 | # main options - done 229 | def mainOptions(): 230 | try: 231 | choice = int(input("Please enter user choice : ")) 232 | if choice == 1: 233 | print("\n===================================================\n") 234 | login() 235 | print("\n===================================================\n") 236 | mainOptions() 237 | elif choice == 2: 238 | print("\n===================================================\n") 239 | signup() 240 | print("\n===================================================\n") 241 | mainOptions() 242 | elif choice == 3: 243 | print("\n===================================================\n") 244 | scoreboard() 245 | print("\n===================================================\n") 246 | mainOptions() 247 | elif choice == 4: 248 | sys.exit() 249 | else: 250 | print("\nInvalid Choice. Please enter valid choice") 251 | print("\n===================================================\n") 252 | main() 253 | print("\n===================================================\n") 254 | mainOptions() 255 | except ValueError: 256 | print("\nInvalid Choice. Please enter valid choice") 257 | print("\n===================================================\n") 258 | main() 259 | print("\n===================================================\n") 260 | mainOptions() 261 | 262 | 263 | # username get and check if it is in former users. - done 264 | def usrnmget(): 265 | with open("userdb.csv") as file: 266 | 267 | userdb = csv.DictReader(file) 268 | usr = input("Enter Username: ") 269 | for user in userdb: 270 | if usr == user["username"]: 271 | print("sorry! Username already taken. What would you like to do next?") 272 | print("=====================") 273 | print("1.Login") 274 | print("2.Try Again") 275 | print("3.Main Menu") 276 | print("=====================") 277 | choice = int(input()) 278 | if choice == 1: 279 | login() 280 | elif choice == 2: 281 | signup() 282 | elif choice == 3: 283 | main() 284 | else: 285 | print( 286 | "Oops! I didn't understand. So I will take you back to main menu :)" 287 | ) 288 | main() 289 | if usr: 290 | return usr 291 | else: 292 | print("Empty Username! Try again") 293 | usrnmget() 294 | 295 | 296 | # sign up function - done 297 | def signup(): 298 | try: 299 | file = open("userdb.csv") 300 | file.close() 301 | 302 | except FileNotFoundError: 303 | with open("userdb.csv", "a") as file: 304 | writer = csv.writer(file) 305 | writer.writerow(["username", "password", "score"]) 306 | print("=====================") 307 | print("1.Enter Credentials") 308 | print("2.Main Menu") 309 | print("=====================") 310 | choice = int(input("Enter your choice: ")) 311 | if choice == 1: 312 | username = usrnmget() 313 | password = input("Enter Password: ").encode("utf-8") 314 | encoded_pass = base64.b64encode(password) 315 | with open("userdb.csv", "a") as db: 316 | writer = csv.DictWriter(db, fieldnames=["username", "password", "score"]) 317 | writer.writerow( 318 | {"username": username, "password": encoded_pass, "score": 0.0} 319 | ) 320 | print("Congratulations! You registered successfully.") 321 | main() 322 | elif choice == 2: 323 | main() 324 | else: 325 | print("Oops! I don't understand. Try again...") 326 | signup() 327 | 328 | 329 | # login page - 330 | def login(): 331 | print("=====================") 332 | print("1.Enter Credentials") 333 | print("2.Sign Up") 334 | print("3.Main Menu") 335 | print("=====================") 336 | choice = int(input("Enter your choice: ")) 337 | if choice == 1: 338 | try: 339 | df = pd.read_csv("userdb.csv") 340 | username = input("Enter Username: ") 341 | if ind := list(df.index[df["username"] == username]): 342 | password = input("Enter Your Password: ").encode("utf-8") 343 | encoded_password = base64.b64encode(password) 344 | if str(encoded_password) == list(df.iloc[ind, 1])[0]: 345 | 346 | play() 347 | df.loc[ind[0], "score"] += MineBoard.score - 10 348 | df.to_csv("userdb.csv", index=False) 349 | MineBoard.score = 0 350 | scoreboard() 351 | 352 | else: 353 | print("Wrong Password. What would you like to do next?") 354 | print("=====================") 355 | print("1.Try Again") 356 | print("2.Sign Up") 357 | print("=====================") 358 | choice = int(input()) 359 | if choice == 1: 360 | login() 361 | elif choice == 2: 362 | signup() 363 | else: 364 | print( 365 | "Oops! I didn't understand. So I will take you back to main menu :)" 366 | ) 367 | else: 368 | print("sorry! User not found. What would you like to do next?") 369 | print("=====================") 370 | print("1.Try Again") 371 | print("2.Sign Up") 372 | print("=====================") 373 | choice = int(input()) 374 | if choice == 1: 375 | login() 376 | elif choice == 2: 377 | signup() 378 | else: 379 | print( 380 | "Oops! I didn't understand. So I will take you back to main menu :)" 381 | ) 382 | except FileNotFoundError: 383 | print("Sorry! No user Found. Sign up first") 384 | main() 385 | elif choice == 2: 386 | signup() 387 | elif choice == 3: 388 | main() 389 | else: 390 | print("Oops! I didn't understand. So I will take you back to main menu :)") 391 | main() 392 | 393 | 394 | # score board - done 395 | def scoreboard(): 396 | try: 397 | df = pd.read_csv("userdb.csv") 398 | df.sort_values( 399 | ["score", "username"], 400 | axis=0, 401 | ascending=[False, True], 402 | inplace=True, 403 | na_position="last", 404 | ) 405 | df.to_csv( 406 | path_or_buf="userdb.csv", 407 | sep=",", 408 | na_rep="", 409 | float_format=None, 410 | columns=None, 411 | header=True, 412 | index=False, 413 | index_label=None, 414 | mode="w", 415 | encoding=None, 416 | compression="infer", 417 | quoting=None, 418 | quotechar='"', 419 | line_terminator=None, 420 | chunksize=None, 421 | date_format=None, 422 | doublequote=True, 423 | escapechar=None, 424 | decimal=".", 425 | errors="strict", 426 | storage_options=None, 427 | ) 428 | df = pd.read_csv("userdb.csv") 429 | df = df[["username", "score"]] 430 | df.index += 1 431 | print(tabulate(df, headers=["Rank", "Username", "Score"], tablefmt="pretty")) 432 | print("Select your next Choice:") 433 | print("1.Main Menu") 434 | print("2.Exit") 435 | choice = int(input()) 436 | if choice == 1: 437 | main() 438 | elif choice == 2: 439 | sys.exit() 440 | except FileNotFoundError: 441 | print("No user found! Do some progress first...") 442 | main() 443 | 444 | 445 | if __name__ == "__main__": 446 | main() -------------------------------------------------------------------------------- /Project-14002/test_project.py: -------------------------------------------------------------------------------- 1 | # run using pytest test_project.py via terminal. 2 | 3 | from project import MineBoard 4 | 5 | def test_display(): 6 | mine = MineBoard(10, 10, 20) 7 | assert mine.display(9) == "x" 8 | assert mine.display(100) == "F" 9 | assert mine.display(10) == "." 10 | assert mine.display(2) == "*" 11 | 12 | def test_GameStat(): 13 | mine = MineBoard(15, 15, 75) 14 | assert mine.winGame() == False 15 | assert mine.loseGame() == False 16 | 17 | def test_isOver(): 18 | mine = MineBoard(25, 25, 100) 19 | assert mine.isOver() == False 20 | 21 | def test_isValidCell(): 22 | mine = MineBoard(5, 5, 10) 23 | assert mine.isValidCell(4, 3) == True 24 | assert mine.isValidCell(14, 3) == False -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | آموزش برنامه‌نویسی پایتون 3 |

4 |

5 | این مخزن، محتوای درس مبانی برنامه‌نویسی (پایتون) است که در دانشگاه صنعتی شریف برگزار کردم. تمامی تمرین‌ها، پروژه، امتحان‌های میان‌ترم، امتحان پایان‌ترم و ویدیوهای آموزشی را می‌توانید 6 | از طریق این مخزن دسترسی پیدا کنید. 7 |

8 |

9 | تمارین، پروژه و امتحانات 10 |

11 |
12 | 38 |
39 | 40 |

41 | منابع 42 |

43 | 44 |

45 | خواندن کتاب‌های زیر برای یادگیری بهتر پایتون را توصیه می‌کنم. 46 | 47 | 🔗 Python for Everybody (مقدماتی) 48 | 49 | 🔗 Writing Idiomatic Python (متوسط) 50 | 51 | 🔗 Python Tricks: A Buffet of Awesome Python Features (متوسط رو به بالا) 52 | 53 | 🔗 Effective Python: 90 Specific Ways to Write Better Python (متوسط رو به بالا) 54 | 55 | 🔗 Fluent Python: Clear, Concise, and Effective Programming (پیشرفته) 56 |

57 | 58 |

59 | ویدیوهای آموزشی 60 |

61 | 62 |

63 | ویدیوهای آموزش برنامه‌نویسی پایتون را می‌توانید در کانال یوتیوب مشاهده کنید. 64 | 65 | 🔗 پلی‌لیست آموزش برنامه‌نویسی پایتون (یوتیوب) 66 |

67 | 68 | آموزش برنامه‌نویسی پایتون 69 |
70 |

71 | 72 | 73 | --------------------------------------------------------------------------------