From e2b78e37cc0422d3f76732dfc466c84fde3e5096 Mon Sep 17 00:00:00 2001 From: rjgeng Date: Thu, 27 Jul 2023 21:50:01 -0700 Subject: [PATCH 1/3] Py-DS: Section 1: Course Setup --- .../1_Course-Introduction.md | 11 + .../2_Full-Course-Curriculum-Overview.md | 10 + .../3_How-to-get-help-for-the-Course.md | 65 +++ .../4_Course-FAQ.md | 28 ++ .../Readme.md | 405 ++++++++++++++++++ 5 files changed, 519 insertions(+) create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/1_Course-Introduction.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/2_Full-Course-Curriculum-Overview.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/3_How-to-get-help-for-the-Course.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/4_Course-FAQ.md diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/1_Course-Introduction.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/1_Course-Introduction.md new file mode 100644 index 0000000..39056b6 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/1_Course-Introduction.md @@ -0,0 +1,11 @@ +# 1. Course Introduction + + + +## Resources for this lecture + + + +--- + +[Previous]() | [Next](./2_Full-Course-Curriculum-Overview.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/2_Full-Course-Curriculum-Overview.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/2_Full-Course-Curriculum-Overview.md new file mode 100644 index 0000000..d924ec8 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/2_Full-Course-Curriculum-Overview.md @@ -0,0 +1,10 @@ +# 2. Full Course Curriculum Overview + + +## Resources for this lecture + + + +--- + +[Previous](./1_Course-Introduction.md) | [Next](./3_How-to-get-help-for-the-Course.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/3_How-to-get-help-for-the-Course.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/3_How-to-get-help-for-the-Course.md new file mode 100644 index 0000000..f6de778 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/3_How-to-get-help-for-the-Course.md @@ -0,0 +1,65 @@ +# 3. How to get help for the Course! + +GUIDE TO GETTING HELP FOR THE COURSE + +Hey everyone, here are some helpful tips for getting help and your questions answered as quickly as possible! + +For non-technical section questions: + +Before asking a discussion question, you should try: + +1. Searching on Google for similar questions or comments to answer what you are looking for. + +2. If you do need to post to the discussion forum , ask good questions! + +- Be Positive! Other students will be more likely to help out! + +- Be clear with your question and phrase it with a clear thought in mind. + + + +Make sure to thank people who answer your questions! + +Try to answer other people's questions to improve your own understanding! + + + +For technical section questions: + +Before asking a discussion question, you should try: + +1. Debugging your code + +- Check for error messages + +- Remove all the code you just added until it works again, and then add it in line by line + +- Compare your code against the example Jupyter Notebook, all the technical section lectures have corresponding Jupyter Notebooks (notebooks with Python code and explanatory text) available for you to download and run. Make sure your code is exactly the like the Jupyter Notebooks! + +2. Find Solutions Online + +- Google the specific error message you got along with "Python" + +- Search StackOverflow for your problem or error + +- Google "How do I...." for what you are trying to do + +3. If you do need to post to the discussion forum , ask good questions! + +- Be Positive! Other students will be more likely to help out! + +- Be specific, don't paste in a massive amount of code. Instead try posting a screenshot of the error message + +- Try linking to the code hosted somewhere else, like a gist from GitHub + +Make sure to thank people who answer your questions! + +Try to answer other people's questions to improve your own understanding! + +## Resources for this lecture + + + +--- + +[Previous](./2_Full-Course-Curriculum-Overview.md) | [Next](./4_Course-FAQ.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/4_Course-FAQ.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/4_Course-FAQ.md new file mode 100644 index 0000000..ca6288f --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/4_Course-FAQ.md @@ -0,0 +1,28 @@ +# 4. Course FAQ + +**Course FAQ** + +**1. Where can I find the materials for the technical section of the course?** + +You can download them as a zip file in the resource lecture in the **Technical Break Section** of the course! + +Or you can view them online here: + +https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews + +**2. Which half of the course should I do first, Non-Technical or Technical?** + +That's up to you. If you're more than 4 months away from interviewing, just do the course in sequential order. + +If you have interviews coming up in less than a month, you might want to jump to the technical prep section, as well as overlooking the non-technical sectiosn focusing on what to do during an interview. + + +## Resources for this lecture + +- [Python-for-Algorithms--Data-Structures--and-Interviews-master.zip](https://python-ds.s3.us-west-1.amazonaws.com/Python-for-Data-Structures-Algorithms-and-Interviews/Resources/Python-for-Algorithms--Data-Structures--and-Interviews-master.zip) + +- [https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews) + +--- + +[Previous](./3_How-to-get-help-for-the-Course.md) | [Next]() diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md index e69de29..831fcad 100644 --- a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md @@ -0,0 +1,405 @@ +# Python for Data Structures, Algorithms, and Interviews! + +- [Python for Data Structures, Algorithms, and Interviews!](https://www.udemy.com/course/python-for-data-structures-algorithms-and-interviews) + +Get a kick start on your career and ace your coding interviews! + +## What you'll learn +- Create a great resume +- Have a LinkedIn and Github profile for recruiters +- Understand all major Data Structures and Algorithms +- Ace coding interviews after preparing with the course's mock interviews + +## Course content + +25 sections • 228 lectures • 17h 10m total length + +
+ Section 1: Course Setup + + - [1. Course Introduction](1_Course-Introduction.md) + - [2. Full Course Curriculum Overview](2_Full-Course-Curriculum-Overview.md) + - [3. How to get help for the Course!](3_How-to-get-help-for-the-Course.md) + - [4. Course FAQ](4_Course-FAQ.md) +
+ +
+ Section 2: Company and Job Types + + - [5. ]() + - [6. ]() +
+ +
+ Section 3: Resume Preparation + + - [7. ]() + - [8. ]() + - [9. ]() + - [10. ]() +
+ +
+ Section 4: Online Presence + + - [11. ]() + - [12. ]() + - [13. ]() +
+ +
+ Section 5: Networking + + - [14. ]() + - [15. ]() +
+ +
+ Section 6: Job Searching + + - [16. ]() + - [17. ]() + - [18. ]() + - [19. ]() + - [20. ]() +
+ +
+ Section 7: During the Interview (Non-Technical) + + - [21. ]() + - [22. ]() + - [23. ]() + - [24. ]() + - [25. ]() +
+ +
+ Section 8: Post Interview + + - [26. ]() + - [27. ]() + - [28. ]() +
+ +
+ Section 9: Technical Break Section + + - [29. ]() + - [30. ]() + - [31. ]() +
+ +
+ Section 10: Introduction to Jupyter Notebooks + + - [32. ]() + - [33. ]() + - [34. ]() + - [35. ]() + - [36. ]() + - [37. ]() +
+ +
+ Section 11: Algorithm Analysis and Big O + + - [38. ]() + - [39. ]() + - [40. ]() + - [41. ]() + - [42. ]() + - [43. ]() + - [44. ]() +
+ +
+ Section 12: Array Sequences + + - [45. ]() + - [46. ]() + - [47. ]() + - [48. ]() + - [49. ]() + - [50. ]() + - [51. ]() + - [52. ]() + - [53. ]() + - [54. ]() + - [55. ]() + - [56. ]() + - [57. ]() + - [58. ]() + - [59. ]() + - [60. ]() + - [61. ]() + - [62. ]() + - [63. ]() + - [64. ]() +
+ +
+ Section 13: Stacks Queues and Deques + + - [65. ]() + - [66. ]() + - [67. ]() + - [68. ]() + - [69. ]() + - [70. ]() + - [71. ]() + - [72. ]() + - [73. ]() + - [74. ]() + - [75. ]() + - [76. ]() + - [77. ]() + - [78. ]() + - [79. ]() +
+ +
+ Section 14: Linked List + + - [80. ]() + - [81. ]() + - [82. ]() + - [83. ]() + - [84. ]() + - [85. ]() + - [86. ]() + - [87. ]() + - [88. ]() + - [89. ]() + - [90. ]() + - [91. ]() + - [92. ]() +
+ +
+ Section 15: Recursion + + - [93. ]() + - [94. ]() + - [95. ]() + - [96. ]() + - [97. ]() + - [98. ]() + - [99. ]() + - [100. ]() + - [101. ]() + - [102. ]() + - [103. ]() + - [104. ]() + - [105. ]() +
+ +
+ Section 16: Trees + + - [106. ]() + - [107. ]() + - [108. ]() + - [109. ]() + - [110. ]() + - [111. ]() + - [112. ]() + - [113. ]() + - [114. ]() + - [115. ]() + - [116. ]() + - [117. ]() + - [118. ]() + - [119. ]() + - [120. ]() + - [121. ]() +
+ +
+ Section 17: Searching and Sorting + + - [122. ]() + - [123. ]() + - [124. ]() + - [125. ]() + - [126. ]() + - [127. ]() + - [128. ]() + - [129. ]() + - [130. ]() + - [131. ]() + - [132. ]() + - [133. ]() + - [134. ]() + - [135. ]() + - [136. ]() + - [137. ]() + - [138. ]() + - [139. ]() + - [140. ]() + - [141. ]() + - [142. ]() + - [143. ]() + - [144. ]() + - [145. ]() + - [146. ]() + - [147. ]() + - [148. ]() + - [149. ]() + - [150. ]() + - [151. ]() +
+ +
+ Section 18: Graph Algorithms + + - [152. ]() + - [153. ]() + - [154. ]() + - [155. ]() + - [156. ]() + - [157. ]() + - [158. ]() + - [159. ]() + - [160. ]() + - [161. ]() + - [162. ]() + - [163. ]() + - [164. ]() + - [165. ]() +
+ +
+ Section 19: Riddles + + - [166. ]() + - [167. ]() + - [168. ]() + - [169. ]() + - [170. ]() + - [171. ]() + - [172. ]() + - [173. ]() + - [174. ]() + - [175. ]() + - [176. ]() + - [177. ]() + - [178. ]() + - [179. ]() + - [180. ]() +
+ +
+ Section 20: Introduction to Mock Interview Section + + - [181. ]() + - [182. ]() + - [183. ]() + - [184. ]() + - [185. ]() +
+ +
+ Section 21: Mock Interview 1 - E-Commerce Company + + - [186. ]() + - [187. ]() + - [188. ]() + - [189. ]() + - [190. ]() + - [191. ]() + - [192. ]() + - [193. ]() + - [194. ]() + - [195. ]() +
+ +
+ Section 22: Mock Interview 2 - Large Search Engine Company + + - [196. ]() + - [197. ]() + - [198. ]() + - [199. ]() + - [200. ]() + - [201. ]() + - [202. ]() + - [203. ]() + - [204. ]() + - [205. ]() + - [206. ]() + - [207. ]() +
+ +
+ Section 23: Mock Interview 3 - Ride Share Start-Up Company + + - [208. ]() + - [209. ]() + - [210. ]() + - [211. ]() + - [212. ]() + - [213. ]() + - [214. ]() + - [215. ]() + - [216. ]() + - [217. ]() +
+ +
+ Section 24: Mock Interview 4 - Social Network Company + + - [218. ]() + - [219. ]() + - [220. ]() + - [221. ]() + - [222. ]() + - [223. ]() + - [224. ]() + - [225. ]() + - [226. ]() + - [227. ]() +
+ +
+ Section 25: BONUS SECTION: THANK YOU! + + - [228. ]() +
+ +## Requirements + +Basic to Intermediate Python skills. + +## Description + +PLEASE NOTE: IF YOU ARE A COMPLETE BEGINNER TO PYTHON, CHECK OUT MY OTHER COURSE: **COMPLETE PYTHON BOOTCAMP** TO LEARN PYTHON! + +**Welcome to Python for Data Structures, Algorithms and Interviews!** + +This is the most comprehensive course online to help you ace your coding interviews and learn about Data Structures and Algorithms! This course takes advantage of the easy to read Python programming language to efficiently teach you what you need to know to land the tech job of your dreams! + +This course will teach you everything you need to know to get a great job in the software technology field, including: + +- Creating a great resume +- Creating LinkedIn and GitHub profiles for recruiters to find +- Building and leveraging a network for job opportunities +- The latest job searching tools available online +- Non-Technical Interview Questions and Answers +- Post-Interview topics (Salary Negotiation and References Preparation) +- Jupyter Notebooks Overview +- Algorithm Analysis and Big-O Notation +- Array Sequences +- Stacks Queues and Deques +- Linked Lists +- Recursion +- Trees +- Searching and Sorting Algorithms +- Graph Algorithms +- Riddles and Brainteasers +- 4 Mock Interviews! + +**Achieve your career goals and get a fantastic job in technology by enrolling in this course!** + +## Who this course is for: +- Students familiar with Python programming looking to start a career in tech! \ No newline at end of file From e7fc4af53bf374132491dd24a75479c062ca8cc7 Mon Sep 17 00:00:00 2001 From: rjgeng Date: Fri, 28 Jul 2023 08:14:47 -0700 Subject: [PATCH 2/3] Py-DS: Section 11: Algorithm Analysis and Big O --- ...thm-Analysis-and-Big-O-Section-Overview.md | 23 ++++ ...duction-to-Algorithm-Analysis-and-Big-O.md | 85 +++++++++++++ .../40_Big-O-Notation.md | 64 ++++++++++ .../41_Big-O-Examples.md | 20 +++ .../42_Homework-Reading-Asssignment.md | 13 ++ .../43_Big-O-for-Python-Data-Structures.md | 18 +++ .../44-Big-O-Reference-Cheat-Sheet.md | 11 ++ .../Readme.md | 14 +-- .../01-intro-big-o/01-intro-analysis-big-o.py | 34 +++++ .../01-intro-big-o/02-big-o-notion.py | 30 +++++ .../01-intro-big-o/03-big-o-examples.py | 116 ++++++++++++++++++ .../04-big-o-for-python-data-structures.py | 0 codebase/python-ds-interview/Readme.md | 0 imgs/Readme.md | 0 imgs/py-ds/02-big-o-notion.png | Bin 0 -> 175407 bytes 15 files changed, 421 insertions(+), 7 deletions(-) create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/38_Algorithm-Analysis-and-Big-O-Section-Overview.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/39_Introduction-to-Algorithm-Analysis-and-Big-O.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/40_Big-O-Notation.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/41_Big-O-Examples.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/42_Homework-Reading-Asssignment.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/43_Big-O-for-Python-Data-Structures.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/44-Big-O-Reference-Cheat-Sheet.md create mode 100644 codebase/python-ds-interview/01-intro-big-o/01-intro-analysis-big-o.py create mode 100644 codebase/python-ds-interview/01-intro-big-o/02-big-o-notion.py create mode 100644 codebase/python-ds-interview/01-intro-big-o/03-big-o-examples.py create mode 100644 codebase/python-ds-interview/01-intro-big-o/04-big-o-for-python-data-structures.py create mode 100644 codebase/python-ds-interview/Readme.md create mode 100644 imgs/Readme.md create mode 100644 imgs/py-ds/02-big-o-notion.png diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/38_Algorithm-Analysis-and-Big-O-Section-Overview.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/38_Algorithm-Analysis-and-Big-O-Section-Overview.md new file mode 100644 index 0000000..ee7180c --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/38_Algorithm-Analysis-and-Big-O-Section-Overview.md @@ -0,0 +1,23 @@ +# 38. Algorithm Analysis and Big O Section Overview + +
+ Slides: Algorithm Analysis and Big O Section Overview + +

+ + + +

+ +
+ + +## Resources for this lecture + +- [Python-for-Algorithms--Data-Structures--and-Interviews-master.zip](https://python-ds.s3.us-west-1.amazonaws.com/Python-for-Data-Structures-Algorithms-and-Interviews/Resources/Python-for-Algorithms--Data-Structures--and-Interviews-master.zip) + +- [https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews) + +--- + +[Previous](./4_Course-FAQ.md) | [Next](./39_Introduction-to-Algorithm-Analysis-and-Big-O.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/39_Introduction-to-Algorithm-Analysis-and-Big-O.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/39_Introduction-to-Algorithm-Analysis-and-Big-O.md new file mode 100644 index 0000000..97172d6 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/39_Introduction-to-Algorithm-Analysis-and-Big-O.md @@ -0,0 +1,85 @@ +# 39. Introduction to Algorithm Analysis and Big O + +
+ Slides: Introduction to Algorithm Analysis and Big O + +

+ + + + + +

+ +
+ +
+ Result: picture capture + +- `01-intro-analysis-big-o.py` + +```python +import timeit + +# First function (Note the use of range since this is in Python 3) +def sum1(n): + ''' + Take an input of n and return the sum of the numbers from 0 to n + ''' + final_sum = 0 + for x in range(n+1): + final_sum += x + + return final_sum + +print(sum1(10)) + +timer1 = timeit.Timer('sum1(10)', globals=globals()) + +time_taken1 = timer1.timeit(number=1000) + +print(f"Time taken by sum1: {time_taken1:.6f} seconds") + +def sum2(n): + """ + Take an input of n and return the sum of the numbers from 0 to n + """ + return (n*(n+1))/2 + +print(sum2(10)) + +timer2 = timeit.Timer('sum2(10)', globals=globals()) + +time_taken2 = timer2.timeit(number=1000) + +print(f"Time taken by sum2: {time_taken2:.6f} seconds") + +``` + +- run `python3 01-intro-analysis-big-o.py` + +```bash +55 +Time taken by sum1: 0.000760 seconds +55.0 +Time taken by sum2: 0.000153 seconds +``` + +
+ +
+ Codebase: + +- [01-intro-analysis-big-o.py](../../codebase/python-ds-interview/01-intro-big-o/01-intro-analysis-big-o.py) + +- [01-Introduction to Algorithm Analysis and Big O .ipynb](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/01-Algorithm%20Analysis%20and%20Big%20O/01-Introduction%20to%20Algorithm%20Analysis%20and%20Big%20O%20.ipynb) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./38_Algorithm-Analysis-and-Big-O-Section-Overview.md) | [Next](./40_Big-O-Notation.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/40_Big-O-Notation.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/40_Big-O-Notation.md new file mode 100644 index 0000000..6c21663 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/40_Big-O-Notation.md @@ -0,0 +1,64 @@ +# 40. Big O Notation + +
+ Result: picture capture + +- `02-big-o-notion.py` + +```python +import numpy as np +import matplotlib.pyplot as plt + +# Import math module specifically for the log function +from math import log + +# Set up runtime comparisons +n = np.linspace(1, 10, 1000) +labels = ['Constant', 'Logarithmic', 'Linear', 'Log Linear', 'Quadratic', 'Cubic', 'Exponential'] +big_o = [np.ones(n.shape), np.log(n), n, n*np.log(n), n**2, n**3, 2**n] + +# Plot setup +plt.figure(figsize=(12, 10)) +plt.ylim(0, 50) + +for i in range(len(big_o)): + plt.plot(n, big_o[i], label=labels[i]) + +plt.legend(loc=0) +plt.ylabel('Relative Runtime') +plt.xlabel('n') + +fig = plt.gcf() +fig.set_size_inches(12, 4) +fig.savefig('../../../imgs/py-ds/02-big-o-notion.png', dpi=300) + +# Display the plot +plt.show() + +``` + +- run `python3 02-big-o-notion.py` + +

+ + +

+ +
+ +
+ Codebase: + +- [02-big-o-notion.py](../../codebase/python-ds-interview/01-intro-big-o/02-big-o-notion.py) + +- [02-Big O Notation.ipynb](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/01-Algorithm%20Analysis%20and%20Big%20O/02-Big%20O%20Notation.ipynb) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./39_Introduction-to-Algorithm-Analysis-and-Big-O.md) | [Next](./41_Big-O-Examples.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/41_Big-O-Examples.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/41_Big-O-Examples.md new file mode 100644 index 0000000..c9da38c --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/41_Big-O-Examples.md @@ -0,0 +1,20 @@ +# 41. Big O Examples + +
+ Codebase: + +- [03-big-o-examples.py](../../codebase/python-ds-interview/01-intro-big-o/03-big-o-examples.py) + +- [03-Big O Examples .ipynb](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/01-Algorithm%20Analysis%20and%20Big%20O/03-Big%20O%20Examples%20.ipynb) + +
+ +## Resources for this lecture + +* [Big-O Notation Explained](http://stackoverflow.com/questions/487258/plain-english-explanation-of-big-o/487278#487278) + +* [Big-O Examples Explained](http://stackoverflow.com/questions/2307283/what-does-olog-n-mean-exactly) + +--- + +[Previous](./40_Big-O-Notation.md) | [Next](./42_Homework-Reading-Asssignment.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/42_Homework-Reading-Asssignment.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/42_Homework-Reading-Asssignment.md new file mode 100644 index 0000000..3e70329 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/42_Homework-Reading-Asssignment.md @@ -0,0 +1,13 @@ +# 42. Homework Reading Asssignment + +Remember to finish the reading assignment mentioned in the last lecture before continuing so you can fully understand Big O! It's another great resource available to you! + +## Resources for this lecture + +* [Big-O Notation Explained](http://stackoverflow.com/questions/487258/plain-english-explanation-of-big-o/487278#487278) + +* [Big-O Examples Explained](http://stackoverflow.com/questions/2307283/what-does-olog-n-mean-exactly) + +--- + +[Previous](./41_Big-O-Examples.md) | [Next](./43_Big-O-for-Python-Data-Structures.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/43_Big-O-for-Python-Data-Structures.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/43_Big-O-for-Python-Data-Structures.md new file mode 100644 index 0000000..9774084 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/43_Big-O-for-Python-Data-Structures.md @@ -0,0 +1,18 @@ +# 43. Big O for Python Data Structures + +
+ Codebase: + +- [04-big-o-for-python-data-structures.py](../../codebase/python-ds-interview/01-intro-big-o/04-big-o-for-python-data-structures.py) + +- [04-Big O for Python Data Structures.ipynb](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/01-Algorithm%20Analysis%20and%20Big%20O/04-Big%20O%20for%20Python%20Data%20Structures.ipynb) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./42_Homework-Reading-Asssignment.md) | [Next](./44-Big-O-Reference-Cheat-Sheet.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/44-Big-O-Reference-Cheat-Sheet.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/44-Big-O-Reference-Cheat-Sheet.md new file mode 100644 index 0000000..ae7fb55 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/44-Big-O-Reference-Cheat-Sheet.md @@ -0,0 +1,11 @@ +# 44. Big-O Reference Cheat Sheet + +Check out the link for a Cheat Sheet which covers Big-O performance for common data structures! Reference this cheat sheet once you learn about the data structure! + +## Resources for this lecture + +- [Big-O Cheat Sheet](http://bigocheatsheet.com/) + +--- + +[Previous](./43_Big-O-for-Python-Data-Structures.md) | [Next]() diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md index 831fcad..87d205f 100644 --- a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md @@ -104,13 +104,13 @@ Get a kick start on your career and ace your coding interviews!
Section 11: Algorithm Analysis and Big O - - [38. ]() - - [39. ]() - - [40. ]() - - [41. ]() - - [42. ]() - - [43. ]() - - [44. ]() + - [38. Algorithm Analysis and Big O Section Overview](38_Algorithm-Analysis-and-Big-O-Section-Overview.md) + - [39. Introduction to Algorithm Analysis and Big O](39_Introduction-to-Algorithm-Analysis-and-Big-O.md) + - [40. Big O Notation](40_Big-O-Notation.md) + - [41. Big O Examples](41_Big-O-Examples.md) + - [42. Homework Reading Asssignment](42_Homework-Reading-Asssignment.md) + - [43. Big O for Python Data Structures](43_Big-O-for-Python-Data-Structures.md) + - [44. Big-O Reference Cheat Sheet](44-Big-O-Reference-Cheat-Sheet.md)
diff --git a/codebase/python-ds-interview/01-intro-big-o/01-intro-analysis-big-o.py b/codebase/python-ds-interview/01-intro-big-o/01-intro-analysis-big-o.py new file mode 100644 index 0000000..daf9c7a --- /dev/null +++ b/codebase/python-ds-interview/01-intro-big-o/01-intro-analysis-big-o.py @@ -0,0 +1,34 @@ +import timeit + +# First function (Note the use of range since this is in Python 3) +def sum1(n): + ''' + Take an input of n and return the sum of the numbers from 0 to n + ''' + final_sum = 0 + for x in range(n+1): + final_sum += x + + return final_sum + +print(sum1(10)) + +timer1 = timeit.Timer('sum1(10)', globals=globals()) + +time_taken1 = timer1.timeit(number=1000) + +print(f"Time taken by sum1: {time_taken1:.6f} seconds") + +def sum2(n): + """ + Take an input of n and return the sum of the numbers from 0 to n + """ + return (n*(n+1))/2 + +print(sum2(10)) + +timer2 = timeit.Timer('sum2(10)', globals=globals()) + +time_taken2 = timer2.timeit(number=1000) + +print(f"Time taken by sum2: {time_taken2:.6f} seconds") diff --git a/codebase/python-ds-interview/01-intro-big-o/02-big-o-notion.py b/codebase/python-ds-interview/01-intro-big-o/02-big-o-notion.py new file mode 100644 index 0000000..2c0ac89 --- /dev/null +++ b/codebase/python-ds-interview/01-intro-big-o/02-big-o-notion.py @@ -0,0 +1,30 @@ +import numpy as np +import matplotlib.pyplot as plt + +# Import math module specifically for the log function +from math import log + +# Set up runtime comparisons +n = np.linspace(1, 10, 1000) +labels = ['Constant', 'Logarithmic', 'Linear', 'Log Linear', 'Quadratic', 'Cubic', 'Exponential'] +big_o = [np.ones(n.shape), np.log(n), n, n*np.log(n), n**2, n**3, 2**n] + +# Plot setup +plt.figure(figsize=(12, 10)) +plt.ylim(0, 50) + +for i in range(len(big_o)): + plt.plot(n, big_o[i], label=labels[i]) + +plt.legend(loc=0) +plt.ylabel('Relative Runtime') +plt.xlabel('n') + +fig = plt.gcf() +fig.set_size_inches(12, 4) +fig.savefig('../../../imgs/py-ds/02-big-o-notion.png', dpi=300) + + + +# Display the plot +plt.show() \ No newline at end of file diff --git a/codebase/python-ds-interview/01-intro-big-o/03-big-o-examples.py b/codebase/python-ds-interview/01-intro-big-o/03-big-o-examples.py new file mode 100644 index 0000000..2c02f00 --- /dev/null +++ b/codebase/python-ds-interview/01-intro-big-o/03-big-o-examples.py @@ -0,0 +1,116 @@ +# O(1) Constant example + +def func_constant(values): + ''' + Prints first item in a list of values. + ''' + print(values[0]) + +func_constant([1,2,3]) + +# O(n) Linear example + +def func_lin(lst): + ''' + Takes in list and prints out all values + ''' + for val in lst: + print(val) + +func_lin([1,2,3]) + +# O(n^2) Quadratic example + +def func_quad(lst): + ''' + Prints pairs for every item in list. + ''' + for item_1 in lst: + for item_2 in lst: + print(item_1,item_2) + +func_quad([1,2,3]) + +# Calculating Scale of Big-O + +def print_once(lst): # O(n) + ''' + Prints all items once + ''' + for val in lst: + print(val) + +print_once([1,2,3]) + +def print_3(lst): # O(3n) --> O(n) + ''' + Prints all items three times + ''' + for val in lst: + print(val) + + for val in lst: + print(val) + + for val in lst: + print(val) + +print_3([1,2,3]) + +def comp(lst): # O(1 + 1/2n + 10) --> O(n) + ''' + This function prints the first item O(1) + Then is prints the first 1/2 of the list O(n/2) + Then prints a string 10 times O(10) + ''' + print(lst[0]) + + midpoint = len(lst)//2 + + for val in lst[:midpoint]: + print(val) + + for x in range(10): + print('number') + +print(comp([1,2,3,4,5,6,7,8,9,10])) + + # Worst Case vs Best Case + +def matcher(lst,match): # O(n) + ''' + Given a list lst, return a boolean indicating if match item is in the list + ''' + for item in lst: + if item == match: + return True + return False + +# Best case: O(1) --> item is first item in list +# Worst case: O(n) --> item is not in list or is last item in list + +print(matcher([1,2,3,4,5],1)) + +# Space Complexity + +def printer(n=10): # O(1) + ''' + Prints "hello world!" n times + ''' + for x in range(n): + print('Hello World!') + +printer() + +def create_list(n): # O(n) + ''' + Creates a list containing 1 to n + ''' + new_list = [] + + for num in range(n): + new_list.append('new') + + return new_list + +print(create_list(5)) \ No newline at end of file diff --git a/codebase/python-ds-interview/01-intro-big-o/04-big-o-for-python-data-structures.py b/codebase/python-ds-interview/01-intro-big-o/04-big-o-for-python-data-structures.py new file mode 100644 index 0000000..e69de29 diff --git a/codebase/python-ds-interview/Readme.md b/codebase/python-ds-interview/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/imgs/Readme.md b/imgs/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/imgs/py-ds/02-big-o-notion.png b/imgs/py-ds/02-big-o-notion.png new file mode 100644 index 0000000000000000000000000000000000000000..66accfb764f9ece2025e42c91e481e7d32a874f6 GIT binary patch literal 175407 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¥iaE4UT&z=hQXnX%66h9hCYB~A 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 literal 0 HcmV?d00001 From 4be18aec4b6a77003825db88a0e0c6631b442307 Mon Sep 17 00:00:00 2001 From: rjgeng Date: Mon, 31 Jul 2023 06:01:06 -0700 Subject: [PATCH 3/3] Py-DS: Section 12: Array Sequences --- .DS_Store | Bin 6148 -> 6148 bytes .../44-Big-O-Reference-Cheat-Sheet.md | 2 +- ...5_Introduction-to-Array-Based-Sequences.md | 24 ++++ .../46_Low-Level-Arrays.md | 41 ++++++ .../47_Dynamic-Array.md | 81 ++++++++++++ .../48_Dynamic-Array-Excercise.md | 35 +++++ .../49_Amortization.md | 37 ++++++ .../50_Interview-Problems-Arrays.md | 35 +++++ .../51_Anagram-Check-Interview-Problem.md | 61 +++++++++ ...nagram-Check-Interview-Problem-SOLUTION.md | 18 +++ .../53_Array-Pair-Sum-Interview-Problem.md | 63 +++++++++ ...ray-Pair-Sum-Interview-Problem-SOLUTION.md | 18 +++ ...d-the-Missing-Element-Interview-Problem.md | 61 +++++++++ ...sing-Element-Interview-Problem-SOLUTION.md | 18 +++ ...argest-Continuous-Sum-Interview-Problem.md | 49 +++++++ ...ntinuous-Sum-Interview-Problem-SOLUTION.md | 18 +++ .../59_Sentence-Reversal-Interview-Problem.md | 68 ++++++++++ ...nce-Reversal-Interview-Problem-SOLUTION.md | 18 +++ ...61_String-Compression-Interview-Problem.md | 53 ++++++++ ...-Compression-Interview-Problem-SOLUTION.md | 18 +++ ...haracters-in-a-String-Interview-Problem.md | 50 ++++++++ ...rs-in-String-Interview-Problem-SOLUTION.md | 18 +++ .../Readme.md | 42 +++--- .../notes/48.1_How_to_use_ctypes_in_python.md | 69 ++++++++++ .../notes/48.2_How-to-use-make_array.md | 42 ++++++ .../48.3_Why_double_size_in_append_method.md | 7 + ...timate-the-memory-usage-by-DynamicArray.md | 50 ++++++++ Curricula/edabit-py/Readme.md | 14 ++ .../edabit-py/RegEx/RegEx-XV_Alternation.md | 43 +++++++ .../RegEx/RegEx_X-A_Word-Character-Class.md | 30 +++++ codebase/.DS_Store | Bin 6148 -> 6148 bytes codebase/python-ds-interview/.DS_Store | Bin 0 -> 6148 bytes .../02-array-sequences/.DS_Store | Bin 0 -> 6148 bytes .../02-array-sequences/03_dynamic_array.py | 22 ++++ .../04_dynamic_array_exercise.py | 121 ++++++++++++++++++ .../01-Anagram-Check/01-anagram-assert.py | 98 ++++++++++++++ .../01-Anagram-Check/01-anagram-doctest.py | 26 ++++ .../01-Anagram-Check/01-anagram-unittest.py | 36 ++++++ .../02-array-pair-sum-assert.py | 57 +++++++++ .../02-array-pair-sum-doctest.py | 24 ++++ .../02-array-pair-sum-unittest.py | 32 +++++ .../03-find-the-missing-element-assert.py | 36 ++++++ .../03-find-the-missing-element-doctest.py | 26 ++++ .../03-find-the-missing-element-unittest.py | 42 ++++++ .../04-largest-continuous-sum-assert.py | 27 ++++ .../04-largest-continuous-sum-doctest.py | 24 ++++ .../04-largest-continuous-sum-unittest.py | 32 +++++ .../05-sentence-reversal-assert.py | 43 +++++++ .../05-sentence-reversal-doctest.py | 24 ++++ .../05-sentence-reversal-unittest.py | 32 +++++ .../06-string-compression-assert.py | 28 ++++ .../06-string-compression-doctest.py | 24 ++++ .../06-string-compression-unittest.py | 32 +++++ .../07-unique-characters-in-string-assert.py | 25 ++++ .../07-unique-characters-in-string-doctest.py | 18 +++ ...07-unique-characters-in-string-unittest.py | 22 ++++ .../ctypes-make_array/my_library.c | 11 ++ .../ctypes-make_array/my_library.h | 3 + .../ctypes-make_array/my_python.py | 62 +++++++++ imgs/.DS_Store | Bin 0 -> 6148 bytes index.js | 0 index.py | 24 ++++ 62 files changed, 2013 insertions(+), 21 deletions(-) create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/45_Introduction-to-Array-Based-Sequences.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/46_Low-Level-Arrays.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/47_Dynamic-Array.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/48_Dynamic-Array-Excercise.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/49_Amortization.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/50_Interview-Problems-Arrays.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/51_Anagram-Check-Interview-Problem.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/52_Anagram-Check-Interview-Problem-SOLUTION.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/53_Array-Pair-Sum-Interview-Problem.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/54_Array-Pair-Sum-Interview-Problem-SOLUTION.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/55_Find-the-Missing-Element-Interview-Problem.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/56_Find-the-Missing-Element-Interview-Problem-SOLUTION.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/57_Largest-Continuous-Sum-Interview-Problem.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/58_Largest-Continuous-Sum-Interview-Problem-SOLUTION.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/59_Sentence-Reversal-Interview-Problem.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/60_Sentence-Reversal-Interview-Problem-SOLUTION.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/61_String-Compression-Interview-Problem.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/62_String-Compression-Interview-Problem-SOLUTION.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/63_Unique-Characters-in-a-String-Interview-Problem.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/64_Unique-Characters-in-String-Interview-Problem-SOLUTION.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.1_How_to_use_ctypes_in_python.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.2_How-to-use-make_array.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.3_Why_double_size_in_append_method.md create mode 100644 Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.4_use-sys.getsizeof()-to-estimate-the-memory-usage-by-DynamicArray.md create mode 100644 Curricula/edabit-py/Readme.md create mode 100644 Curricula/edabit-py/RegEx/RegEx-XV_Alternation.md create mode 100644 Curricula/edabit-py/RegEx/RegEx_X-A_Word-Character-Class.md create mode 100644 codebase/python-ds-interview/.DS_Store create mode 100644 codebase/python-ds-interview/02-array-sequences/.DS_Store create mode 100644 codebase/python-ds-interview/02-array-sequences/03_dynamic_array.py create mode 100644 codebase/python-ds-interview/02-array-sequences/04_dynamic_array_exercise.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-assert.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-doctest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-unittest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-assert.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-doctest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-unittest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-assert.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-doctest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-unittest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-assert.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-doctest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-unittest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-assert.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-doctest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-unittest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-assert.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-doctest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-unittest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-assert.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-doctest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-unittest.py create mode 100644 codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.c create mode 100644 codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.h create mode 100644 codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_python.py create mode 100644 imgs/.DS_Store create mode 100644 index.js create mode 100644 index.py diff --git a/.DS_Store b/.DS_Store index 26c6c6350e0f7f4446b37a6da74a16506eaf10b8..039307e804819b395c45017ff01d1ed1b50bd39c 100644 GIT binary patch delta 40 ucmZoMXfc@J&&WJ6z#2&O$S^WaT&cv#!jQ?3%aG1cym7xV`(}2Izx)8<4GTB` delta 35 rcmZoMXfc@J&&V_}z +

Slides: Introduction to Array Based Sequences + +

+ + + + + + +

+ +
+ + +## Resources for this lecture + + + +--- + +[Previous](./44-Big-O-Reference-Cheat-Sheet.md) | [Next](./46_Low-Level-Arrays.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/46_Low-Level-Arrays.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/46_Low-Level-Arrays.md new file mode 100644 index 0000000..c449f00 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/46_Low-Level-Arrays.md @@ -0,0 +1,41 @@ +# 46. Low Level Arrays + +
+ Slides: Introduction to Array Based Sequences + +

+ + + + + + + + + + + + + + + + + + + + + + + +

+ +
+ + +## Resources for this lecture + + + +--- + +[Previous](./45_Introduction-to-Array-Based-Sequences.md) | [Next](./47_Dynamic-Array.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/47_Dynamic-Array.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/47_Dynamic-Array.md new file mode 100644 index 0000000..19a9cba --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/47_Dynamic-Array.md @@ -0,0 +1,81 @@ +# 47. Dynamic Array + +
+ Slides: Dynamic Array + +

+ + + + + + + + + + + +

+ +
+ +
+ Result: print or picture capture + +- `03_dynamic_array.py` + +```python +import sys + +# Set n +n = 10 + +data = [] + +for i in range(n): + + # Number of elements + a = len(data) + + # Actual size in bytes + b = sys.getsizeof(data) + + print('Length: {0:3d}; Size in bytes: {1:4d}'.format(a, b)) + + # increase length by one + data.append(n) +``` + +- run `python 03_dynamic_array.py` + +```bash +Length: 0; Size in bytes: 56 +Length: 1; Size in bytes: 88 +Length: 2; Size in bytes: 88 +Length: 3; Size in bytes: 88 +Length: 4; Size in bytes: 88 +Length: 5; Size in bytes: 120 +Length: 6; Size in bytes: 120 +Length: 7; Size in bytes: 120 +Length: 8; Size in bytes: 120 +Length: 9; Size in bytes: 184 +``` + +
+ +
+ Codebase: + +- [03_dynamic_array.py](../../codebase/python-ds-interview/02-array-sequences/03_dynamic_array.py) + +- [02-Array Sequences](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/tree/master/02-Array%20Sequences) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./46_Low-Level-Arrays.md) | [Next](./48_Dynamic-Array-Excercise.md) diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/48_Dynamic-Array-Excercise.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/48_Dynamic-Array-Excercise.md new file mode 100644 index 0000000..f0bc9c9 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/48_Dynamic-Array-Excercise.md @@ -0,0 +1,35 @@ +# 48. Dynamic Array Excercise + +
+ Study Notes: + +- [ChatGPT: How to us `ctypes` in Python?](./notes/48.1_How_to_use_ctypes_in_python.md) + +- [ChatGPT: How to use `make_array`?](./notes/48.2_How-to-use-make_array.md) + +- [ChatGPT: Why double size `in append(self, ele)`?](./notes/48.3_Why_double_size_in_append_method.md) + +- [ChatGPT: How to use `sys.getsizeof()` or `tracemalloc`?](./notes/48.4_use-sys.getsizeof()-to-estimate-the-memory-usage-by-DynamicArray.md) + +
+ +
+ Codebase: + +- [04_dynamic_array_exercise.py](../../codebase/python-ds-interview/02-array-sequences/04_dynamic_array_exercise.py) + +- [04-Dynamic Array Exercise.ipynb](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/02-Array%20Sequences/04-Dynamic%20Array%20Exercise.ipynb) + +- [ctypes and make_array](../../codebase/python-ds-interview/02-array-sequences/ctypes-make_array/) + +
+ +## Resources for this lecture + +- [ctypes — A foreign function library for Python](https://docs.python.org/3/library/ctypes.html) + + + +--- + +[Previous](./47_Dynamic-Array.md) | [Next](./49_Amortization.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/49_Amortization.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/49_Amortization.md new file mode 100644 index 0000000..7d1c8e0 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/49_Amortization.md @@ -0,0 +1,37 @@ +# 49. Amortization + +
+ Slides: Amortization + +

+ + + + + + + + + +

+ +
+ +
+ Codebase: + +- [04_dynamic_array_exercise.py](../../codebase/python-ds-interview/02-array-sequences/04_dynamic_array_exercise.py) + +- [04-Dynamic Array Exercise.ipynb](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/02-Array%20Sequences/04-Dynamic%20Array%20Exercise.ipynb) + +
+ +## Resources for this lecture + +- [Amortized Analysis](https://python-ds.s3.us-west-1.amazonaws.com/Python-for-Data-Structures-Algorithms-and-Interviews/Resources/Amortized-Analysis.pdf) + + + +--- + +[Previous](./48_Dynamic-Array-Excercise.md) | [Next](./50_Interview-Problems-Arrays.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/50_Interview-Problems-Arrays.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/50_Interview-Problems-Arrays.md new file mode 100644 index 0000000..7bd08d6 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/50_Interview-Problems-Arrays.md @@ -0,0 +1,35 @@ +# 50. Interview Problems - Arrays + +
+ Slides: Interview Problems - Arrays + +

+ + + + + + + + + +

+ +
+ +
+ Codebase: + +- [Array-Sequences-Interview-Questions](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/) + +- [Array Sequences Interview Questions](https://github.com/jmportilla/Python-for-Algorithms--Data-Structures--and-Interviews/tree/master/02-Array%20Sequences/Array%20Sequences%20Interview%20Questions) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./49_Amortization.md) | [Next](./51_Anagram-Check-Interview-Problem.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/51_Anagram-Check-Interview-Problem.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/51_Anagram-Check-Interview-Problem.md new file mode 100644 index 0000000..5b5b01f --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/51_Anagram-Check-Interview-Problem.md @@ -0,0 +1,61 @@ +# 51. Anagram Check - Interview Problem + +
+

Interview Problems:

+ +## Anagram Check + +### Problem + +Given two strings, check to see if they are anagrams. An anagram is when the two strings can be written using the exact same letters (so you can just rearrange the letters to get a different phrase or word). + +For example: + + "public relations" is an anagram of "crap built on lies." + + "clint eastwood" is an anagram of "old west action" + +**Note: Ignore spaces and capitalization. So "d go" is an anagram of "God" and "dog" and "o d g".** + +## Solution + +Fill out your solution below: + +```python +def anagram(s1,s2): + pass +``` + +## Test Your Solution + +Run the cell below to test your solution + +```python +from nose.tools import assert_equal + +class AnagramTest(object): + + def test(self,sol): + assert_equal(sol('go go go','gggooo'),True) + assert_equal(sol('abc','cba'),True) + assert_equal(sol('hi man','hi man'),True) + assert_equal(sol('aabbcc','aabbc'),False) + assert_equal(sol('123','1 2'),False) + print("ALL TEST CASES PASSED") + +# Run Tests +t = AnagramTest() +t.test(anagram) +``` + +
+ + + +## Resources for this lecture + + + +--- + +[Previous](./50_Interview-Problems-Arrays.md) | [Next](./52_Anagram-Check-Interview-Problem-SOLUTION.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/52_Anagram-Check-Interview-Problem-SOLUTION.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/52_Anagram-Check-Interview-Problem-SOLUTION.md new file mode 100644 index 0000000..a63e016 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/52_Anagram-Check-Interview-Problem-SOLUTION.md @@ -0,0 +1,18 @@ +# 52. Anagram Check - Interview Problem - SOLUTION + +
+

CodeBase:

+ +- [01-anagram-assert.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-assert.py) +- [01-anagram-doctest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-doctest.py) +- [01-anagram-unittest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-unittest.py) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./51_Anagram-Check-Interview-Problem.md) | [Next](./53_Array-Pair-Sum-Interview-Problem.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/53_Array-Pair-Sum-Interview-Problem.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/53_Array-Pair-Sum-Interview-Problem.md new file mode 100644 index 0000000..bf88275 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/53_Array-Pair-Sum-Interview-Problem.md @@ -0,0 +1,63 @@ +# 53. Array Pair Sum - Interview Problem + +
+

Interview Problems:

+ +## Array Pair Sum + +### Problem + +Given an integer array, output all the ***unique*** pairs that sum up to a specific value **k**. + +So the input: + + pair_sum([1,3,2,2],4) + +would return **2** pairs: + + (1,3) + (2,2) + +**NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS** + +## Solution + +Fill out your solution below: + +```python +def pair_sum(arr,k): + pass +``` + +## Test Your Solution + +Run the cell below to test your solution + +```python +from nose.tools import assert_equal + +class TestPair(object): + + def test(self,sol): + assert_equal(sol([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10),6) + assert_equal(sol([1,2,3,1],3),1) + assert_equal(sol([1,3,2,2],4),2) + print('ALL TEST CASES PASSED') + +#Run tests +t = TestPair() +t.test(pair_sum) +print("All tests passed!") +``` + +
+ + + +## Resources for this lecture + + + +--- + +[Previous](./52_Anagram-Check-Interview-Problem-SOLUTION.md) | [Next](./54_Array-Pair-Sum-Interview-Problem-SOLUTION.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/54_Array-Pair-Sum-Interview-Problem-SOLUTION.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/54_Array-Pair-Sum-Interview-Problem-SOLUTION.md new file mode 100644 index 0000000..b940ae8 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/54_Array-Pair-Sum-Interview-Problem-SOLUTION.md @@ -0,0 +1,18 @@ +# 54. Array Pair Sum - Interview Problem - SOLUTION + +
+

CodeBase:

+ +- [02-array-pair-sum-assert.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-assert.py) +- [02-array-pair-sum-doctest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-doctest.py) +- [02-array-pair-sum-unittest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-unittest.py) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./53_Array-Pair-Sum-Interview-Problem.md) | [Next](./55_Find-the-Missing-Element-Interview-Problem.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/55_Find-the-Missing-Element-Interview-Problem.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/55_Find-the-Missing-Element-Interview-Problem.md new file mode 100644 index 0000000..7abd921 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/55_Find-the-Missing-Element-Interview-Problem.md @@ -0,0 +1,61 @@ +# 55. Find the Missing Element - Interview Problem + +
+

Interview Problems:

+ +## Find the Missing Element + +### Problem + +Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array. + +Here is an example input, the first array is shuffled and the number 5 is removed to construct the second array. + +Input: + + finder([1,2,3,4,5,6,7],[3,7,2,1,4,6]) + +Output: + + 5 is the missing number + +## Solution + +Fill out your solution below: + +```python +ddef finder(arr1,arr2): + pass +``` + +## Test Your Solution + +Run the cell below to test your solution + +```python +from nose.tools import assert_equal + +class TestFinder(object): + + def test(self,sol): + assert_equal(sol([5,5,7,7],[5,7,7]),5) + assert_equal(sol([1,2,3,4,5,6,7],[3,7,2,1,4,6]),5) + assert_equal(sol([9,8,7,6,5,4,3,2,1],[9,8,7,5,4,3,2,1]),6) + print('ALL TEST CASES PASSED') + +# Run test +t = TestFinder() +t.test(finder) +``` + +
+ + + +## Resources for this lecture + + + +--- + +[Previous](./54_Array-Pair-Sum-Interview-Problem-SOLUTION.md) | [Next](./56_Find-the-Missing-Element-Interview-Problem-SOLUTION.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/56_Find-the-Missing-Element-Interview-Problem-SOLUTION.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/56_Find-the-Missing-Element-Interview-Problem-SOLUTION.md new file mode 100644 index 0000000..1618f04 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/56_Find-the-Missing-Element-Interview-Problem-SOLUTION.md @@ -0,0 +1,18 @@ +# 56. Find the Missing Element - Interview Problem - SOLUTION + +
+

CodeBase:

+ +- [03-find-the-missing-element-assert.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-assert.py) +- [03-find-the-missing-element-doctest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-doctest.py) +- [03-find-the-missing-element-unittest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-unittest.py) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./55_Find-the-Missing-Element-Interview-Problem.md) | [Next](./57_Largest-Continuous-Sum-Interview-Problem.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/57_Largest-Continuous-Sum-Interview-Problem.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/57_Largest-Continuous-Sum-Interview-Problem.md new file mode 100644 index 0000000..4782247 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/57_Largest-Continuous-Sum-Interview-Problem.md @@ -0,0 +1,49 @@ +# 57. Largest Continuous Sum - Interview Problem + +
+

Interview Problems:

+ +## Largest Continuous Sum + +### Problem +Given an array of integers (positive and negative) find the largest continuous sum. + +## Solution + +Fill out your solution below: + +```python +def large_cont_sum(arr): + pass +``` + +## Test Your Solution + +Run the cell below to test your solution + +```python +from nose.tools import assert_equal + +class LargeContTest(object): + def test(self,sol): + assert_equal(sol([1,2,-1,3,4,-1]),9) + assert_equal(sol([1,2,-1,3,4,10,10,-10,-1]),29) + assert_equal(sol([-1,1]),1) + print('ALL TEST CASES PASSED') + +#Run Test +t = LargeContTest() +t.test(large_cont_sum) +``` + +
+ + + +## Resources for this lecture + + + +--- + +[Previous](./56_Find-the-Missing-Element-Interview-Problem-SOLUTION.md) | [Next](./58_Largest-Continuous-Sum-Interview-Problem-SOLUTION.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/58_Largest-Continuous-Sum-Interview-Problem-SOLUTION.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/58_Largest-Continuous-Sum-Interview-Problem-SOLUTION.md new file mode 100644 index 0000000..5c45ccc --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/58_Largest-Continuous-Sum-Interview-Problem-SOLUTION.md @@ -0,0 +1,18 @@ +# 58. Largest Continuous Sum - Interview Problem - SOLUTION + +
+

CodeBase:

+ +- [04-largest-continuous-sum-assert.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-assert.py) +- [04-largest-continuous-sum-doctest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-doctest.py) +- [04-largest-continuous-sum-unittest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-unittest.py) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./57_Largest-Continuous-Sum-Interview-Problem.md) | [Next](./59_Sentence-Reversal-Interview-Problem.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/59_Sentence-Reversal-Interview-Problem.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/59_Sentence-Reversal-Interview-Problem.md new file mode 100644 index 0000000..f82d43b --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/59_Sentence-Reversal-Interview-Problem.md @@ -0,0 +1,68 @@ +# 59. Sentence Reversal - Interview Problem + +
+

Interview Problems:

+ +## Sentence Reversal + +### Problem + +Given a string of words, reverse all the words. For example: + +Given: + + 'This is the best' + +Return: + + 'best the is This' + +As part of this exercise you should remove all leading and trailing whitespace. So that inputs such as: + + ' space here' and 'space here ' + +both become: + + 'here space' + +## Solution + +Fill out your solution below: + +```python +def rev_word(s): + pass +``` + +## Test Your Solution + +Run the cell below to test your solution + +```python +from nose.tools import assert_equal + +class ReversalTest(object): + + def test(self,sol): + assert_equal(sol(' space before'),'before space') + assert_equal(sol('space after '),'after space') + assert_equal(sol(' Hello John how are you '),'you are how John Hello') + assert_equal(sol('1'),'1') + print("ALL TEST CASES PASSED") + +# Run and test +t = ReversalTest() +t.test(rev_word) +``` + +
+ + + +## Resources for this lecture + + + +--- + +[Previous](./58_Largest-Continuous-Sum-Interview-Problem-SOLUTION.md) | [Next](./60_Sentence-Reversal-Interview-Problem-SOLUTION.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/60_Sentence-Reversal-Interview-Problem-SOLUTION.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/60_Sentence-Reversal-Interview-Problem-SOLUTION.md new file mode 100644 index 0000000..31db4ca --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/60_Sentence-Reversal-Interview-Problem-SOLUTION.md @@ -0,0 +1,18 @@ +# 60. Sentence Reversal - Interview Problem - SOLUTION + +
+

CodeBase:

+ +- [05-sentence-reversal-assert.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-assert.py) +- [05-sentence-reversal-doctest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-doctest.py) +- [05-sentence-reversal-unittest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-unittest.py) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./59_Sentence-Reversal-Interview-Problem.md) | [Next](./61_String-Compression-Interview-Problem.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/61_String-Compression-Interview-Problem.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/61_String-Compression-Interview-Problem.md new file mode 100644 index 0000000..c4a4dba --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/61_String-Compression-Interview-Problem.md @@ -0,0 +1,53 @@ +# 61. String Compression - Interview Problem + +
+

Interview Problems:

+ +## String Compression + +### Problem + +Given a string in the form 'AAAABBBBCCCCCDDEEEE' compress it to become 'A4B4C5D2E4'. For this problem, you can falsely "compress" strings of single or double letters. For instance, it is okay for 'AAB' to return 'A2B1' even though this technically takes more space. + +The function should also be case sensitive, so that a string 'AAAaaa' returns 'A3a3'. + +## Solution + +Fill out your solution below: + +```python +def compress(s): + pass +``` + +## Test Your Solution + +Run the cell below to test your solution + +```python +from nose.tools import assert_equal + +class TestCompress(object): + + def test(self, sol): + assert_equal(sol(''), '') + assert_equal(sol('AABBCC'), 'A2B2C2') + assert_equal(sol('AAABCCDDDDD'), 'A3B1C2D5') + print('ALL TEST CASES PASSED') + +# Run Tests +t = TestCompress() +t.test(compress) +``` + +
+ + + +## Resources for this lecture + + + +--- + +[Previous](./60_Sentence-Reversal-Interview-Problem-SOLUTION.md) | [Next](./62_String-Compression-Interview-Problem-SOLUTION.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/62_String-Compression-Interview-Problem-SOLUTION.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/62_String-Compression-Interview-Problem-SOLUTION.md new file mode 100644 index 0000000..38859b4 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/62_String-Compression-Interview-Problem-SOLUTION.md @@ -0,0 +1,18 @@ +# 62. String Compression - Interview Problem - SOLUTION + +
+

CodeBase:

+ +- [06-string-compression-assert.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-assert.py) +- [06-string-compression-doctest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-doctest.py) +- [06-string-compression-unittest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-unittest.py) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./61_String-Compression-Interview-Problem.md) | [Next](./63_Unique-Characters-in-a-String-Interview-Problem.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/63_Unique-Characters-in-a-String-Interview-Problem.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/63_Unique-Characters-in-a-String-Interview-Problem.md new file mode 100644 index 0000000..8cbb444 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/63_Unique-Characters-in-a-String-Interview-Problem.md @@ -0,0 +1,50 @@ +# 63. Unique Characters in a String - Interview Problem + +
+

Interview Problems:

+ +## Unique Characters in String + +### Problem +Given a string,determine if it is compreised of all unique characters. For example, the string 'abcde' has all unique characters and should return True. The string 'aabcde' contains duplicate characters and should return false. + +## Solution + +Fill out your solution below: + +```python +def uni_char(s): + pass +``` + +## Test Your Solution + +Run the cell below to test your solution + +```python +from nose.tools import assert_equal + +class TestUnique(object): + + def test(self, sol): + assert_equal(sol(''), True) + assert_equal(sol('goo'), False) + assert_equal(sol('abcdefg'), True) + print('ALL TEST CASES PASSED') + +# Run Tests +t = TestUnique() +t.test(uni_char) +``` + +
+ + + +## Resources for this lecture + + + +--- + +[Previous](./62_String-Compression-Interview-Problem-SOLUTION.md) | [Next](./64_Unique-Characters-in-a-String-Interview-Problem-SOLUTION.md) \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/64_Unique-Characters-in-String-Interview-Problem-SOLUTION.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/64_Unique-Characters-in-String-Interview-Problem-SOLUTION.md new file mode 100644 index 0000000..3989837 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/64_Unique-Characters-in-String-Interview-Problem-SOLUTION.md @@ -0,0 +1,18 @@ +# 64. Unique Characters in String - Interview Problem - SOLUTION + +
+

CodeBase:

+ +- [07-unique-characters-in-string-assert.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-assert.py) +- [07-unique-characters-in-string-doctest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-doctest.py) +- [07-unique-characters-in-string-unittest.py](../../codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-unittest.py) + +
+ +## Resources for this lecture + + + +--- + +[Previous](./63) | [Next]() \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md index 87d205f..bc114b3 100644 --- a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/Readme.md @@ -2,6 +2,8 @@ - [Python for Data Structures, Algorithms, and Interviews!](https://www.udemy.com/course/python-for-data-structures-algorithms-and-interviews) +- [https://github.com/BloomTech-DS/Python-for-Algorithms--Data-Structures--and-Interviews](https://github.com/BloomTech-DS/Python-for-Algorithms--Data-Structures--and-Interviews) + Get a kick start on your career and ace your coding interviews! ## What you'll learn @@ -116,26 +118,26 @@ Get a kick start on your career and ace your coding interviews!
Section 12: Array Sequences - - [45. ]() - - [46. ]() - - [47. ]() - - [48. ]() - - [49. ]() - - [50. ]() - - [51. ]() - - [52. ]() - - [53. ]() - - [54. ]() - - [55. ]() - - [56. ]() - - [57. ]() - - [58. ]() - - [59. ]() - - [60. ]() - - [61. ]() - - [62. ]() - - [63. ]() - - [64. ]() + - [45. Introduction to Array Based Sequences](45_Introduction-to-Array-Based-Sequences.md) + - [46. Low Level Arrays](46_Low-Level-Arrays.md) + - [47. Dynamic Array](47_Dynamic-Array.md) + - [48. Dynamic Array Excercise](48_Dynamic-Array-Excercise.md) + - [49. Amortizatio](49_Amortization.md) + - [50. Interview Problems - Arrays](50_Interview-Problems-Arrays.md) + - [51. Anagram Check - Interview Problem](51_Anagram-Check-Interview-Problem.md) + - [52. Anagram Check - Interview Problem - SOLUTION](52_Anagram-Check-Interview-Problem-SOLUTION.md) + - [53. Array Pair Sum - Interview Problem](53_Array-Pair-Sum-Interview-Problem.md) + - [54. Array Pair Sum - Interview Problem - SOLUTION](54_Array-Pair-Sum-Interview-Problem-SOLUTION.md) + - [55. Find the Missing Element - Interview Problem](55_Find-the-Missing-Element-Interview-Problem.md) + - [56. Find the Missing Element - Interview Problem - SOLUTION](56_Find-the-Missing-Element-Interview-Problem-SOLUTION.md) + - [57. Largest Continuous Sum - Interview Problem](57_Largest-Continuous-Sum-Interview-Problem.md) + - [58. Largest Continuous Sum - Interview Problem - SOLUTION](58_Largest-Continuous-Sum-Interview-Problem-SOLUTION.md) + - [59. Sentence Reversal - Interview Problem](59_Sentence-Reversal-Interview-Problem.md) + - [60. Sentence Reversal - Interview Problem - SOLUTION](60_Sentence-Reversal-Interview-Problem-SOLUTION.md) + - [61. String Compression - Interview Problem](61_String-Compression-Interview-Problem.md) + - [62. String Compression - Interview Problem - SOLUTION](62_String-Compression-Interview-Problem-SOLUTION.md) + - [63. Unique Characters in a String - Interview Problem](63_Unique-Characters-in-a-String-Interview-Problem.md) + - [64. Unique Characters in String - Interview Problem - SOLUTION](64_Unique-Characters-in-String-Interview-Problem-SOLUTION.md)
diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.1_How_to_use_ctypes_in_python.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.1_How_to_use_ctypes_in_python.md new file mode 100644 index 0000000..79cdcdc --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.1_How_to_use_ctypes_in_python.md @@ -0,0 +1,69 @@ +# 48.1 How to us `ctypes` in Python? + +`ctypes` is a Python module that allows you to call functions and work with dynamic libraries written in C or C++ directly from Python. It provides a way to interact with low-level memory and data types in a C-compatible way. + +Here's a brief overview of how to use `ctypes` in Python: + +1. Import the `ctypes` module: + +```python +import ctypes +``` + +2. Define C data types and structures: + +Before using `ctypes`, you need to define C data types and structures that will be used to interact with C functions or libraries. You can use `ctypes` to represent basic C data types like int, float, double, etc., and define complex C data structures using `ctypes` classes like `Structure` and `Union`. + +3. Load the shared library: + +To use C functions from a shared library (dynamic library) in Python, you need to load the library using `ctypes.CDLL` or `ctypes.CWindll` (for Windows DLLs). + +4. Access C functions from the loaded library: + +Once the library is loaded, you can access C functions from it and call them as if they were Python functions. You need to specify the function's return type and argument types using `ctypes` data types. + +5. Handle c-compound data types: + +When calling C functions, you may need to pass C-compatible data to and from these functions. `ctypes` provides functions to create C-compatible arrays, pointers, and strings. + +**Here's a simple example to illustrate how to use ctypes:** + +Suppose you have a simple C library named "my_library" with the following functions: + +```c +// my_library.h +int add(int a, int b); +double multiply(double x, double y); +``` + +1. Create a shared library from the C code: + +```bash +gcc -shared -o my_library.so -fPIC my_library.c +``` + +2. In Python, you can use `ctypes` to call these functions: + +```python +import ctypes + +# Load the shared library +my_library = ctypes.CDLL('./my_library.so') + +# Specify function return types and argument types +my_library.add.restype = ctypes.c_int +my_library.add.argtypes = [ctypes.c_int, ctypes.c_int] + +my_library.multiply.restype = ctypes.c_double +my_library.multiply.argtypes = [ctypes.c_double, ctypes.c_double] + +# Call the C functions from Python +result_add = my_library.add(10, 5) +result_multiply = my_library.multiply(3.14, 2.0) + +print("Result of add:", result_add) # Output: Result of add: 15 +print("Result of multiply:", result_multiply) # Output: Result of multiply: 6.28 + +``` + +This example demonstrates how to use `ctypes` to call C functions from a shared library in Python. You can extend this approach to work with more complex C libraries and data structures. However, keep in mind that working with `ctypes` requires some knowledge of C and low-level memory management, so use it with caution. \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.2_How-to-use-make_array.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.2_How-to-use-make_array.md new file mode 100644 index 0000000..cb0c348 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.2_How-to-use-make_array.md @@ -0,0 +1,42 @@ +# 48.2 how to use `make_array`? + +To use the `make_array` method, you need to have an instance of the `DynamicArray` class (as defined in the initial code) since the method is part of that class. Once you have an instance, you can call the `make_array` method to create a new dynamic array (C-style array) with a specified capacity. Here's how you can use it: + +```python +import ctypes + +class DynamicArray(object): + """ + DYNAMIC ARRAY CLASS (Similar to Python List) + """ + + # ... (Other methods and constructor as defined in the initial code) ... + + def make_array(self, new_cap): + return (new_cap * ctypes.py_object)() + +# Creating an instance of DynamicArray +dynamic_array = DynamicArray() + +# Using make_array to create a new array +new_capacity = 10 +new_array = dynamic_array.make_array(new_capacity) + +# The new_array is a dynamic array with a capacity of 10. +# It can store Python objects, similar to a Python list. +# However, it's not directly accessible as a Python list, and you need to work with it using ctypes or other low-level approaches. + +# For example, you can store values in the new array using ctypes: +for i in range(new_capacity): + new_array[i] = i * 2 + +# Accessing elements in the new array: +for i in range(new_capacity): + print(new_array[i]) + +# Note: This new_array is a C-style array and not directly usable as a Python list. +# If you want a dynamic array similar to Python's list, you should use the DynamicArray class and its append method as described in the initial code. + +``` + +It's essential to understand that the `make_array` method creates a low-level dynamic array using C-style array concepts from the `ctypes` module. While it can store Python objects like a list, it is not directly accessible using standard Python list methods. If you want a dynamic array with list-like behavior, you should use the `DynamicArray` class with its `append` method, as shown in the initial code. The `DynamicArray` class handles the low-level memory management and provides a more user-friendly interface for working with dynamic arrays in Python. \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.3_Why_double_size_in_append_method.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.3_Why_double_size_in_append_method.md new file mode 100644 index 0000000..a34b8e6 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.3_Why_double_size_in_append_method.md @@ -0,0 +1,7 @@ +# 48.3 Why double size in `append(self, ele)`? + +In the original code, the line `self._resize(2 * self.capacity)` is used to double the capacity of the dynamic array whenever it becomes full. Doubling the capacity helps reduce the number of resizing operations and provides an amortized constant-time complexity for most `append` operations, which is a common resizing strategy for dynamic arrays. + +However, this strategy may not be the most efficient in all scenarios. Sometimes, you may have a use case where you expect the dynamic array to grow slowly, and doubling the capacity could result in a significant waste of memory. + +Keep in mind that the choice of resizing strategy depends on the specific use case and the expected pattern of element additions. If you expect frequent and large batches of elements to be appended, the doubling strategy might be more appropriate. On the other hand, if you expect a gradual growth or occasional additions, the incremental strategy can be more memory-friendly. \ No newline at end of file diff --git a/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.4_use-sys.getsizeof()-to-estimate-the-memory-usage-by-DynamicArray.md b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.4_use-sys.getsizeof()-to-estimate-the-memory-usage-by-DynamicArray.md new file mode 100644 index 0000000..2013447 --- /dev/null +++ b/Curricula/Python-for-Data-Structures-Algorithms-and-Interviews/notes/48.4_use-sys.getsizeof()-to-estimate-the-memory-usage-by-DynamicArray.md @@ -0,0 +1,50 @@ +# How to use `sys.getsizeof()` or `tracemalloc` to get an estimate of the memory usage of the `DynamicArray`? + +you can use `sys.getsizeof()` to get an estimate of the memory usage of the `DynamicArray` and its underlying array. However, keep in mind that the value returned by `sys.getsizeof()` might not provide an accurate representation of the actual memory usage. + +`sys.getsizeof()` returns the size of the object in bytes, but it doesn't take into account the memory overhead of the Python interpreter or other optimizations that Python might apply. Additionally, `sys.getsizeof()` only provides the size of the Python object and not the memory used by the elements stored in the array. + +Here's an example of how you can use `sys.getsizeof()` to get the size of the `DynamicArray` object: + +```python +import sys + +# Assuming the DynamicArray class is defined as before +dynamic_array = DynamicArray() + +# Append some elements to the array +for i in range(100): + dynamic_array.append(i) + +# Get the size of the DynamicArray object in bytes +size_of_dynamic_array = sys.getsizeof(dynamic_array) +print("Size of DynamicArray:", size_of_dynamic_array, "bytes") +``` + +However, to get a more accurate memory usage estimate, you could use the `tracemalloc` module, which provides more detailed memory tracing capabilities. Using `tracemalloc`, you can measure memory usage before and after specific operations, allowing you to see how much memory your data structures consume in total. Here's an example of how you can use `tracemalloc`: + +```python +import tracemalloc + +# Assuming the DynamicArray class is defined as before +dynamic_array = DynamicArray() + +# Enable tracing +tracemalloc.start() + +# Append some elements to the array +for i in range(100): + dynamic_array.append(i) + +# Measure memory usage after appending elements +snapshot = tracemalloc.take_snapshot() +top_stats = snapshot.statistics("lineno") + +for stat in top_stats[:10]: + print(stat) + +# Disable tracing +tracemalloc.stop() +``` + +Keep in mind that memory usage can be affected by many factors, and accurately measuring memory consumption in Python can be challenging. It's essential to understand the limitations of each method and use them accordingly based on your specific use case. \ No newline at end of file diff --git a/Curricula/edabit-py/Readme.md b/Curricula/edabit-py/Readme.md new file mode 100644 index 0000000..2c8a410 --- /dev/null +++ b/Curricula/edabit-py/Readme.md @@ -0,0 +1,14 @@ +# edabit + +- [edabit](https://edabit.com/) + +## Content + +
+ RegEx + +- [RegEx X-A: Word Character Class](./RegEx/RegEx_X-A_Word-Character-Class.md) + +- [RegEx XV: Alternation]() + +
\ No newline at end of file diff --git a/Curricula/edabit-py/RegEx/RegEx-XV_Alternation.md b/Curricula/edabit-py/RegEx/RegEx-XV_Alternation.md new file mode 100644 index 0000000..bfbf6e1 --- /dev/null +++ b/Curricula/edabit-py/RegEx/RegEx-XV_Alternation.md @@ -0,0 +1,43 @@ +# RegEx XV: Alternation + +- [RegEx XV: Alternation](https://edabit.com/challenge/9ZAHTYWTP5c7FW4RY) + +**The vertical bar** `|` is the equivalent to "or" in RegEx. The regular expression `x|y` matches either "x" or "y". Write the **regular expression** that will match all `red flag` and `blue flag` in a string. You must use `|` in your expression. Flags can come in any order. + +**Examples** + +``` +txt1 = "red flag blue flag" +txt2 = "yellow flag red flag blue flag green flag" +txt3 = "pink flag red flag black flag blue flag green flag red flag" +pattern = "yourregularexpressionhere" + +re.findall(pattern, txt1) ➞ ["red flag", "blue flag"] +re.findall(pattern, txt2) ➞ ["red flag", "blue flag"] +re.findall(pattern, txt3) ➞ ["red flag", "blue flag", "red flag"] +``` + +**Notes** + +You **don't** need to write a function, just the pattern. +Do **not** remove `import re` from the code. +Find more info on RegEx and alternation in the Resources tab. +You can find all the challenges of this series in my [Basic RegEx](https://edabit.com/collection/8PEq2azWDtAZWPFe2) collection. + +**Solution** + +``` +import re + +pattern = "red flag|blue flag" +``` + +**Solution 2** + +- [cvf](https://edabit.com/user/yjtdwc2AC4jA2RWtn) + +``` +import re + +pattern = "(?:red|blue) flag" +``` \ No newline at end of file diff --git a/Curricula/edabit-py/RegEx/RegEx_X-A_Word-Character-Class.md b/Curricula/edabit-py/RegEx/RegEx_X-A_Word-Character-Class.md new file mode 100644 index 0000000..2cc9ad9 --- /dev/null +++ b/Curricula/edabit-py/RegEx/RegEx_X-A_Word-Character-Class.md @@ -0,0 +1,30 @@ +# RegEx X-A: Word Character Class + +[RegEx X-A: Word Character Class](https://edabit.com/challenge/mtfCmMo9fL5yqB3Sy) + +Write the regular expression that matches all alphabetic characters in a string. Use the character class \w in your expression. + +**Example** + +```python + txt = "**^&$Regular#$%Expressions$%$$%^**" + pattern = "yourregularexpressionhere" + + " ".join(re.findall(pattern, txt)) ➞ "Regular Expressions" +``` + +**Notes** + +You **don't** need to write a function, just the pattern. +Do **not** remove `import re` from the code. +Find more info on RegEx and alternation in the Resources tab. +You can find all the challenges of this series in my [Basic RegEx](https://edabit.com/collection/8PEq2azWDtAZWPFe2) collection. + +**Solution** + +``` +import re + +pattern = '\w+' +``` + diff --git a/codebase/.DS_Store b/codebase/.DS_Store index 9d10ed73bb0e9a3a498c42971dae461fd91f1160..664820c440c43f0d4ce2e6ef5f008ed7e29382eb 100644 GIT binary patch delta 119 zcmZoMXfc=|#>B`mu~2NHo+2a5!~pBb0*nnnMvn|5!^D-o2Eq&l43!Ke3>ggh40#N? z3@Hr7Kr$1^E@4PzC}JoBvQrt#Q;L&wlJfI&7&kLACbDg2=iui68VlrnXP(S2V#vYB Pz`)P|#G5@t_AmnguiP6@ delta 69 zcmZoMXfc=|#>CJ*u~2NHo+2aj!~knX=E*#aGK`FqH5q+3Z)FT(n|y$A|7La$eh#3z Z%^MlNGf(ChF=S+zY{MhHIYwj!GXRTu61@Nb diff --git a/codebase/python-ds-interview/.DS_Store b/codebase/python-ds-interview/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..dba0c0b00ca8d7807a22b73249a664fa96c2e1f3 GIT binary patch literal 6148 zcmeHKJ5Iw;5S)b+k!T_+%69=I-~?6_PQV2SNxFy#tQ6^7aW0O=?5D8|O(dFV*4mx- z);rJg6kaa?TOPNMzyiRW?uaiBQ}g@o6T7O65$QbRlh+z2+@qgV|DJH}EgtYh&U(b( z;R8qP@Qw{*zwI~sx5HuY1ep|&0#ZNOzYldUEci>LGa z7Ui%mQBev=fw2PDxm|ewf2RL2|Bp%9NdYNvQ3}{>^|D&>m8!Q+Ue0@MqrcL<=9})u pbx;_h9TTG+bK~v!E{d|Q`I`5;!XYu}%mCs%knviy@v) zzC>IN>>NEE63vIi%@Q4o*zG*OSU99Q=9mhk0(}K8eL2zkzo4J#|NBX~N(EAZf2Dwo z=F9nvuN1X)@N!yf3;mJ)ZH%>W4pxeZR*JdMQhfa@uIQZmHL!EEbn=!?%pU>OB`p>B H3kALa5cM8H literal 0 HcmV?d00001 diff --git a/codebase/python-ds-interview/02-array-sequences/03_dynamic_array.py b/codebase/python-ds-interview/02-array-sequences/03_dynamic_array.py new file mode 100644 index 0000000..ac1c303 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/03_dynamic_array.py @@ -0,0 +1,22 @@ +import sys + +# Set n +n = 10 + +data = [] + +for i in range(n): + + # Number of elements + a = len(data) + + # Actual size in bytes + b = sys.getsizeof(data) + + print('Length: {0:3d}; Size in bytes: {1:4d}'.format(a, b)) + + # increase length by one + data.append(n) + + + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/04_dynamic_array_exercise.py b/codebase/python-ds-interview/02-array-sequences/04_dynamic_array_exercise.py new file mode 100644 index 0000000..6fc40a6 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/04_dynamic_array_exercise.py @@ -0,0 +1,121 @@ +class M(object): + + def public(self): + print('Use Tab to see me!') + + def _private(self): + print("You won't be able to Tab to see me!") + +m = M() + +m.public() + +m._private() + +import ctypes + +class DynamicArray(object): + """ + DYNAMIC ARRAY CLASS (Similar to Python List) + """ + + def __init__(self): + self.n = 0 + self.capacity = 1 + self.A = self.make_array(self.capacity) + + def __len__(self): + return self.n + + def __getitem__(self, k): + + if not 0 <= k < self.n: + return IndexError('k is out of bounds!') + + return self.A[k] + + def append(self, ele): + + if self.n == self.capacity: + self._resize(2*self.capacity +1) # Double the capacity - Amortized Analysis + + self.A[self.n] = ele + self.n += 1 + + def _resize(self, new_cap): + + B = self.make_array(new_cap) + + for k in range (self.n): + B[k] = self.A[k] + + self.A = B + self.capacity = new_cap + + + def make_array(self, new_cap): + + return (new_cap * ctypes.py_object)() + + +arr = DynamicArray() + +arr.append(1) +print(len(arr)) +print(f"capacity 1: {arr.capacity}") + +arr.append(2) +print(len(arr)) +print(arr[0]) +print(arr[1]) +print(f"capacity 2: {arr.capacity}") + +arr.append(3) +print(f"Length: {len(arr)}") +print(arr[0]) +print(arr[1]) +print(f"capacity 3: {arr.capacity}") + +print() +print("### How to use `sys.getsizeof()` to get an estimate of the memory usage of the `DynamicArray`? ###") +print() + +import sys + +# Assuming the DynamicArray class is defined as before +dynamic_array = DynamicArray() + +# Append some elements to the array +for i in range(100): + dynamic_array.append(i) + +# Get the size of the DynamicArray object in bytes +size_of_dynamic_array = sys.getsizeof(dynamic_array) +print("Size of DynamicArray:", size_of_dynamic_array, "bytes") + +print() +print ("### How to use `tracemalloc` to get an estimate of the memory usage of the `DynamicArray`? ###") +print() + +import tracemalloc + +# Assuming the DynamicArray class is defined as before +dynamic_array = DynamicArray() + +# Enable tracing +tracemalloc.start() + +# Append some elements to the array +for i in range(100): + dynamic_array.append(i) + +# Measure memory usage after appending elements +snapshot = tracemalloc.take_snapshot() +top_stats = snapshot.statistics("lineno") + +for stat in top_stats[:10]: + print(stat) + +# Disable tracing +tracemalloc.stop() + diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-assert.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-assert.py new file mode 100644 index 0000000..6c65157 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-assert.py @@ -0,0 +1,98 @@ +# def anagram(s1, s2): +# """ +# Problem: Anagram Check + +# Given two strings, check to see if they are anagrams. An anagram is when the two strings can be written using the exact same letters (so you can just rearrange the letters to get a different phrase or word). + +# For example: +# "public relations" is an anagram of "crap built on lies." +# "clint eastwood" is an anagram of "old west action" + +# **Note: Ignore spaces and capitalization. So "d go" is an anagram of "God" and "dog" and "o d g".** +# """ +# s1 = s1.replace(' ', '').lower() +# s2 = s2.replace(' ', '').lower() +# return sorted(s1) == sorted(s2) + + +# def test_anagram(): +# # Test the function for various inputs +# assert anagram('go go go', 'gggooo') == True +# assert anagram('abc', 'cba') == True +# assert anagram('hi man', 'hi man') == True +# assert anagram('aabbcc', 'aabbc') == False +# assert anagram('123', '1 2') == False +# print("ALL TEST CASES PASSED") + + +# if __name__ == '__main__': +# # Run the tests +# test_anagram() +# print("All tests passed!") + + +# from nose.tools import assert_equal + +# def anagram(s1, s2): +# """ +# Problem: Anagram Check + +# Given two strings, check to see if they are anagrams. An anagram is when the two strings can be written using the exact same letters (so you can just rearrange the letters to get a different phrase or word). + +# For example: +# "public relations" is an anagram of "crap built on lies." +# "clint eastwood" is an anagram of "old west action" + +# **Note: Ignore spaces and capitalization. So "d go" is an anagram of "God" and "dog" and "o d g".** +# """ +# s1 = s1.replace(' ','').lower() +# s2 = s2.replace(' ','').lower() +# return sorted(s1) == sorted(s2) + +# def test_anagram(): +# # Test the function for various inputs +# assert_equal(anagram('go go go','gggooo'),True) +# assert_equal(anagram('abc','cba'),True) +# assert_equal(anagram('hi man','hi man'),True) +# assert_equal(anagram('aabbcc','aabbc'),False) +# assert_equal(anagram('123','1 2'),False) +# print("ALL TEST CASES PASSED") + +# if __name__ == '__main__': +# # Run the tests +# test_anagram() +# print("All tests passed!") + +from nose.tools import assert_equal + +def anagram(s1, s2): + """ + Problem: Anagram Check + + Given two strings, check to see if they are anagrams. An anagram is when the two strings can be written using the exact same letters (so you can just rearrange the letters to get a different phrase or word). + + For example: + "public relations" is an anagram of "crap built on lies." + "clint eastwood" is an anagram of "old west action" + + **Note: Ignore spaces and capitalization. So "d go" is an anagram of "God" and "dog" and "o d g".** + """ + s1 = s1.replace(' ','').lower() + s2 = s2.replace(' ','').lower() + return sorted(s1) == sorted(s2) + +class AnagramTest(object): + + def test(self,sol): + assert_equal(sol('go go go','gggooo'),True) + assert_equal(sol('abc','cba'),True) + assert_equal(sol('hi man','hi man'),True) + assert_equal(sol('aabbcc','aabbc'),False) + assert_equal(sol('123','1 2'),False) + print("ALL TEST CASES PASSED") + +if __name__ == '__main__': + # Run Tests + t = AnagramTest() + t.test(anagram) + print("All tests passed!") \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-doctest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-doctest.py new file mode 100644 index 0000000..0e129db --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-doctest.py @@ -0,0 +1,26 @@ +def anagram(s1, s2): + """ + Problem: Anagram Check + + Given two strings, check to see if they are anagrams. An anagram is when the two strings can be written using the exact same letters (so you can just rearrange the letters to get a different phrase or word). + + For example: + "public relations" is an anagram of "crap built on lies." + "clint eastwood" is an anagram of "old west action" + + **Note: Ignore spaces and capitalization. So "d go" is an anagram of "God" and "dog" and "o d g".** + + >>> anagram('go go go', 'gggooo') + True + >>> anagram('abc', 'cba') + True + >>> anagram('hi man', 'Hi man') + True + >>> anagram('aabbcc', 'aabbc') + False + >>> anagram('123', '1 2') + False + """ + s1 = s1.replace(' ','').lower() + s2 = s2.replace(' ','').lower() + return sorted(s1) == sorted(s2) diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-unittest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-unittest.py new file mode 100644 index 0000000..e197b99 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/01-Anagram-Check/01-anagram-unittest.py @@ -0,0 +1,36 @@ +import unittest + +def anagram(s1, s2): + """ + Problem: Anagram Check + + Given two strings, check to see if they are anagrams. An anagram is when the two strings can be written using the exact same letters (so you can just rearrange the letters to get a different phrase or word). + + For example: + "public relations" is an anagram of "crap built on lies." + "clint eastwood" is an anagram of "old west action" + + **Note: Ignore spaces and capitalization. So "d go" is an anagram of "God" and "dog" and "o d g".** + """ + s1 = s1.replace(' ', '').lower() + s2 = s2.replace(' ', '').lower() + return sorted(s1) == sorted(s2) + +class TestAnagram(unittest.TestCase): + + def test_anagram(self): + # Test the function for various inputs + self.assertEqual(anagram('go go go', 'gggooo'), True) + self.assertEqual(anagram('abc', 'cba'), True) + self.assertEqual(anagram('hi man', 'hi man'), True) + self.assertEqual(anagram('aabbcc', 'aabbc'), False) + self.assertEqual(anagram('123', '1 2'), False) + + def test_anagram_with_spaces(self): + # Test the function with spaces + self.assertEqual(anagram('aabbcc', 'aab bcc'), True) + self.assertEqual(anagram('Hello World', 'World Hello'), True) + self.assertEqual(anagram('Python', ' Java '), False) + +if __name__ == '__main__': + unittest.main() diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-assert.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-assert.py new file mode 100644 index 0000000..0ef21aa --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-assert.py @@ -0,0 +1,57 @@ +from nose.tools import assert_equal + +def pair_sum(arr,k): + """ + Problem - Array Pair Sum + + Given an integer array, output all the ***unique*** pairs that sum up to a specific value **k**. + + So the input: + + pair_sum([1,3,2,2],4) + + would return 2 pairs: + + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + """ + if len(arr)<2: + return + + # Sets for tracking + seen = set() + output = set() + + # For every number in array + for num in arr: + + # Set target difference + target = k-num + + # Add it to set if target hasn't been seen + if target not in seen: + seen.add(num) + + else: + # Add a tuple with the corresponding pair + output.add( (min(num,target), max(num,target)) ) + + print(seen, output) + return len(output) + +class TestPair(object): + + def test(self,sol): + assert_equal(sol([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10),6) + assert_equal(sol([1,2,3,1],3),1) + assert_equal(sol([1,3,2,2],4),2) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + #Run tests + t = TestPair() + t.test(pair_sum) + print("All tests passed!") + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-doctest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-doctest.py new file mode 100644 index 0000000..6d7089d --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-doctest.py @@ -0,0 +1,24 @@ +def pair_sum(arr,k): + """ + ## Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + pair_sum([1,3,2,2],4) + + would return 2 pairs: + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + + >>> pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10) + 6 + >>> pair_sum([1,2,3,1],3) + 1 + >>> pair_sum([1,3,2,2],4) + 2 + """ + pass + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-unittest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-unittest.py new file mode 100644 index 0000000..583f794 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/02-Array-Pair-Sum/02-array-pair-sum-unittest.py @@ -0,0 +1,32 @@ +import unittest + +def pair_sum(arr,k): + """ + Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + + pair_sum([1,3,2,2],4) + + would return 2 pairs: + + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + """ + pass + +class TestPair_sum(unittest.TestCase): + + def test_pair_sum(self): + # Test the function for various inputs + self.assertEqual(pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10),6) + self.assertEqual(pair_sum([1,2,3,1],3),1) + self.assertEqual(pair_sum([1,3,2,2],4),2) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + unittest.main() diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-assert.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-assert.py new file mode 100644 index 0000000..8694307 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-assert.py @@ -0,0 +1,36 @@ +from nose.tools import assert_equal + +def finder(arr1,arr2): + """ + Problem - Find the Missing Element + + Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array. + + Here is an example input, the first array is shuffled and the number 5 is removed to construct the second array. + + Input: + finder([1,2,3,4,5,6,7],[3,7,2,1,4,6]) + + Output: + 5 is the missing number + + Solution + + Fill out your solution below: + """ + pass + +class TestFinder(object): + + def test(self,sol): + assert_equal(sol([5,5,7,7],[5,7,7]),5) + assert_equal(sol([1,2,3,4,5,6,7],[3,7,2,1,4,6]),5) + assert_equal(sol([9,8,7,6,5,4,3,2,1],[9,8,7,5,4,3,2,1]),6) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + #Run tests + t = TestFinder() + t.test(finder) + print("All tests passed!") + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-doctest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-doctest.py new file mode 100644 index 0000000..cc437bd --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-doctest.py @@ -0,0 +1,26 @@ +def finder(arr1,arr2): + """ + Problem - Find the Missing Element + + Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array. + + Here is an example input, the first array is shuffled and the number 5 is removed to construct the second array. + + Input: + finder([1,2,3,4,5,6,7],[3,7,2,1,4,6]) + + Output: + 5 is the missing number + + Solution + + Fill out your solution below: + + >>> finder ([5,5,7,7],[5,7,7]) + 5 + >>> finder ([1,2,3,4,5,6,7],[3,7,2,1,4,6]) + 5 + >>> finder ([9,8,7,6,5,4,3,2,1],[9,8,7,5,4,3,2,1]) + 6 + """ + pass diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-unittest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-unittest.py new file mode 100644 index 0000000..b21aa64 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/03-Finding-the-Missing-Element/03-find-the-missing-element-unittest.py @@ -0,0 +1,42 @@ +import unittest + +def finder(arr1,arr2): + """ + Problem - Find the Missing Element + + Consider an array of non-negative integers. A second array is formed by shuffling the elements of the first array and deleting a random element. Given these two arrays, find which element is missing in the second array. + + Here is an example input, the first array is shuffled and the number 5 is removed to construct the second array. + + Input: + finder([1,2,3,4,5,6,7],[3,7,2,1,4,6]) + + Output: + 5 is the missing number + + Solution + + Fill out your solution below: + """ + pass + +class TestFinder(object): + + def test(self,sol): + # Test the function for various inputs + self.assertEqual(pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10),6) + self.assertEqual(pair_sum([1,2,3,1],3),1) + self.assertEqual(pair_sum([1,3,2,2],4),2) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + unittest.main() + + +class TestFinder(object): + + def test(self,sol): + assert_equal(sol([5,5,7,7],[5,7,7]),5) + assert_equal(sol([1,2,3,4,5,6,7],[3,7,2,1,4,6]),5) + assert_equal(sol([9,8,7,6,5,4,3,2,1],[9,8,7,5,4,3,2,1]),6) + print('ALL TEST CASES PASSED') \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-assert.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-assert.py new file mode 100644 index 0000000..a49eba8 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-assert.py @@ -0,0 +1,27 @@ +from nose.tools import assert_equal + +def pair_sum(arr,k): + """ + Problem - Largest Continuous Sum + + Given an array of integers (positive and negative) find the largest continuous sum. + + Solution + + Fill out your solution below: + """ + pass + +class LargeContTest(object): + def test(self,sol): + assert_equal(sol([1,2,-1,3,4,-1]),9) + assert_equal(sol([1,2,-1,3,4,10,10,-10,-1]),29) + assert_equal(sol([-1,1]),1) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + #Run Test + t = LargeContTest() + t.test(large_cont_sum) + print("All tests passed!") + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-doctest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-doctest.py new file mode 100644 index 0000000..6d7089d --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-doctest.py @@ -0,0 +1,24 @@ +def pair_sum(arr,k): + """ + ## Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + pair_sum([1,3,2,2],4) + + would return 2 pairs: + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + + >>> pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10) + 6 + >>> pair_sum([1,2,3,1],3) + 1 + >>> pair_sum([1,3,2,2],4) + 2 + """ + pass + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-unittest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-unittest.py new file mode 100644 index 0000000..583f794 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/04-Largest-Continuous-Sum/04-largest-continuous-sum-unittest.py @@ -0,0 +1,32 @@ +import unittest + +def pair_sum(arr,k): + """ + Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + + pair_sum([1,3,2,2],4) + + would return 2 pairs: + + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + """ + pass + +class TestPair_sum(unittest.TestCase): + + def test_pair_sum(self): + # Test the function for various inputs + self.assertEqual(pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10),6) + self.assertEqual(pair_sum([1,2,3,1],3),1) + self.assertEqual(pair_sum([1,3,2,2],4),2) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + unittest.main() diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-assert.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-assert.py new file mode 100644 index 0000000..5257209 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-assert.py @@ -0,0 +1,43 @@ +from nose.tools import assert_equal + +def rev_word(s): + """ + Problem - Sentence Reversal + + Given a string of words, reverse all the words. For example: + + Given: + 'This is the best' + + Return: + 'best the is This' + + As part of this exercise you should remove all leading and trailing whitespace. So that inputs such as: + + ' space here' and 'space here ' + + both become: + + 'here space' + + ## Solution + + Fill out your solution below: + """ + pass + +class ReversalTest(object): + + def test(self,sol): + assert_equal(sol(' space before'),'before space') + assert_equal(sol('space after '),'after space') + assert_equal(sol(' Hello John how are you '),'you are how John Hello') + assert_equal(sol('1'),'1') + print("ALL TEST CASES PASSED") + +if __name__ == '__main__': + # Run and test + t = ReversalTest() + t.test(rev_word) + print("All tests passed!") + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-doctest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-doctest.py new file mode 100644 index 0000000..6d7089d --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-doctest.py @@ -0,0 +1,24 @@ +def pair_sum(arr,k): + """ + ## Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + pair_sum([1,3,2,2],4) + + would return 2 pairs: + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + + >>> pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10) + 6 + >>> pair_sum([1,2,3,1],3) + 1 + >>> pair_sum([1,3,2,2],4) + 2 + """ + pass + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-unittest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-unittest.py new file mode 100644 index 0000000..583f794 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/05-Sentence-Reversal/05-sentence-reversal-unittest.py @@ -0,0 +1,32 @@ +import unittest + +def pair_sum(arr,k): + """ + Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + + pair_sum([1,3,2,2],4) + + would return 2 pairs: + + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + """ + pass + +class TestPair_sum(unittest.TestCase): + + def test_pair_sum(self): + # Test the function for various inputs + self.assertEqual(pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10),6) + self.assertEqual(pair_sum([1,2,3,1],3),1) + self.assertEqual(pair_sum([1,3,2,2],4),2) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + unittest.main() diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-assert.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-assert.py new file mode 100644 index 0000000..7b8d653 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-assert.py @@ -0,0 +1,28 @@ +from nose.tools import assert_equal + +def compress(s): + """ + String Compression + + Problem + + Given a string in the form 'AAAABBBBCCCCCDDEEEE' compress it to become 'A4B4C5D2E4'. For this problem, you can falsely "compress" strings of single or double letters. For instance, it is okay for 'AAB' to return 'A2B1' even though this technically takes more space. + + The function should also be case sensitive, so that a string 'AAAaaa' returns 'A3a3'. + """ + pass + +class TestCompress(object): + + def test(self, sol): + assert_equal(sol(''), '') + assert_equal(sol('AABBCC'), 'A2B2C2') + assert_equal(sol('AAABCCDDDDD'), 'A3B1C2D5') + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + # Run Tests + t = TestCompress() + t.test(compress) + print("All tests passed!") + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-doctest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-doctest.py new file mode 100644 index 0000000..6d7089d --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-doctest.py @@ -0,0 +1,24 @@ +def pair_sum(arr,k): + """ + ## Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + pair_sum([1,3,2,2],4) + + would return 2 pairs: + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + + >>> pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10) + 6 + >>> pair_sum([1,2,3,1],3) + 1 + >>> pair_sum([1,3,2,2],4) + 2 + """ + pass + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-unittest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-unittest.py new file mode 100644 index 0000000..583f794 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/06-String-Compression/06-string-compression-unittest.py @@ -0,0 +1,32 @@ +import unittest + +def pair_sum(arr,k): + """ + Problem - Array Pair Sum + + Given an integer array, output all the ** *unique* ** pairs that sum up to a specific value **k**. + + So the input: + + pair_sum([1,3,2,2],4) + + would return 2 pairs: + + (1,3) + (2,2) + + NOTE: FOR TESTING PURPOSES CHANGE YOUR FUNCTION SO IT OUTPUTS THE NUMBER OF PAIRS + """ + pass + +class TestPair_sum(unittest.TestCase): + + def test_pair_sum(self): + # Test the function for various inputs + self.assertEqual(pair_sum([1,9,2,8,3,7,4,6,5,5,13,14,11,13,-1],10),6) + self.assertEqual(pair_sum([1,2,3,1],3),1) + self.assertEqual(pair_sum([1,3,2,2],4),2) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + unittest.main() diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-assert.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-assert.py new file mode 100644 index 0000000..48f259b --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-assert.py @@ -0,0 +1,25 @@ +from nose.tools import assert_equal + +def uni_char(s): + """ + Unique Characters in String + + Problem + Given a string,determine if it is compreised of all unique characters. For example, the string 'abcde' has all unique characters and should return True. The string 'aabcde' contains duplicate characters and should return false. + """ + pass + +class TestUnique(object): + + def test(self, sol): + assert_equal(sol(''), True) + assert_equal(sol('goo'), False) + assert_equal(sol('abcdefg'), True) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + # Run Tests + t = TestUnique() + t.test(uni_char) + print("All tests passed!") + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-doctest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-doctest.py new file mode 100644 index 0000000..ed979f3 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-doctest.py @@ -0,0 +1,18 @@ +def uni_char(s): + """ + Unique Characters in String + + Problem + Given a string,determine if it is compreised of all unique characters. For example, the string 'abcde' has all unique characters and should return True. The string 'aabcde' contains duplicate characters and should return false. + + >>> uni_char('') + True + >>> uni_char('goo') + False + >>> uni_char('abcdefg') + True + """ + pass + + + \ No newline at end of file diff --git a/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-unittest.py b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-unittest.py new file mode 100644 index 0000000..05a024e --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/Array-Sequences-Interview-Questions/07-Unique-Characters-in-String/07-unique-characters-in-string-unittest.py @@ -0,0 +1,22 @@ +import unittest + +def uni_char(s): + """ + Unique Characters in String + + Problem + Given a string,determine if it is compreised of all unique characters. For example, the string 'abcde' has all unique characters and should return True. The string 'aabcde' contains duplicate characters and should return false. + """ + pass + +class TestPair_sum(unittest.TestCase): + + def test_pair_sum(self, sol): + # Test the function for various inputs + self.assertEqual(uni_char((''), True)) + self.assertEqual(uni_char(('goo'), False)) + self.assertEqual(uni_char(('abcdefg'), True)) + print('ALL TEST CASES PASSED') + +if __name__ == '__main__': + unittest.main() diff --git a/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.c b/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.c new file mode 100644 index 0000000..fc90f3e --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.c @@ -0,0 +1,11 @@ +// my_library.c + +// Function to add two integers +int add(int a, int b) { + return a + b; +} + +// Function to multiply two doubles +double multiply(double x, double y) { + return x * y; +} diff --git a/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.h b/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.h new file mode 100644 index 0000000..b2040a9 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_library.h @@ -0,0 +1,3 @@ +// my_library.h +int add(int a, int b); +double multiply(double x, double y); diff --git a/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_python.py b/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_python.py new file mode 100644 index 0000000..5741f13 --- /dev/null +++ b/codebase/python-ds-interview/02-array-sequences/ctypes-make_array/my_python.py @@ -0,0 +1,62 @@ +print("### 1. How to us `ctypes` in Python? ###") +print() + +import ctypes + +# Load the shared library +my_library = ctypes.CDLL('./my_library.so') + +# Specify function return types and argument types +my_library.add.restype = ctypes.c_int +my_library.add.argtypes = [ctypes.c_int, ctypes.c_int] + +my_library.multiply.restype = ctypes.c_double +my_library.multiply.argtypes = [ctypes.c_double, ctypes.c_double] + +# Call the C functions from Python +result_add = my_library.add(10, 5) +result_multiply = my_library.multiply(3.14, 2.0) + +print("Result of add:", result_add) # Output: Result of add: 15 +print("Result of multiply:", result_multiply) # Output: Result of multiply: 6.28 + + +# how to use ctypes to create a C-style array in Python + +print() +print("### 2. How to use ctypes to create a C-style array in Python ###") +print() + +# import ctypes + +class DynamicArray(object): + """ + DYNAMIC ARRAY CLASS (Similar to Python List) + """ + + # ... (Other methods and constructor as defined in the initial code) ... + + def make_array(self, new_cap): + return (new_cap * ctypes.py_object)() + +# Creating an instance of DynamicArray +dynamic_array = DynamicArray() + +# Using make_array to create a new array +new_capacity = 10 +new_array = dynamic_array.make_array(new_capacity) + +# The new_array is a dynamic array with a capacity of 10. +# It can store Python objects, similar to a Python list. +# However, it's not directly accessible as a Python list, and you need to work with it using ctypes or other low-level approaches. + +# For example, you can store values in the new array using ctypes: +for i in range(new_capacity): + new_array[i] = i * 2 + +# Accessing elements in the new array: +for i in range(new_capacity): + print(new_array[i]) + +# Note: This new_array is a C-style array and not directly usable as a Python list. +# If you want a dynamic array similar to Python's list, you should use the DynamicArray class and its append method as described in the initial code. diff --git a/imgs/.DS_Store b/imgs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..0f837be84a4cd7f58f56c8cd2c84956669d56812 GIT binary patch literal 6148 zcmeH~J&pn~427Q;kXE9hq)bD(#oi!7Z~`uXU`iyA&=%X}==aKkUYFyKDi&zIBndhs+qa<2z;UgL2+mn9+~0wN#+ zA|L`2A`pi-&;R9wo=J})0wORC0{(p{bk~~Ny2hu2L$m 1: + return False + return diff_count == 1 + + def backtrack(index): + if index == len(inputArray): + return True + + for i in range(index, len(inputArray)): + inputArray[index], inputArray[i] = inputArray[i], inputArray[index] + if index == 0 or is_one_char_apart(inputArray[index - 1], inputArray[index]): + if backtrack(index + 1): + return True + inputArray[index], inputArray[i] = inputArray[i], inputArray[index] # Backtrack + return False + + return backtrack(0) +