|
14 | 14 | * [Coding style guidelines](https://github.com/LambdaSchool/CS-Wiki/wiki/CS-Coding-Style-Guidelines)
|
15 | 15 | </p></details></p>
|
16 | 16 |
|
| 17 | +<p><details><summary><b>Why is there such a debate between OOP and functional programming, and why should we care?</b></summary><p> |
| 18 | + |
| 19 | +There are a lot of [programming |
| 20 | +paradigms](https://en.wikipedia.org/wiki/Programming_paradigm) and they all have |
| 21 | +their strengths and weaknesses when it comes to solving different types of |
| 22 | +problems. |
| 23 | + |
| 24 | +People can be quite opinionated about their favorites, but it's important to |
| 25 | +remember that no one language or paradigm is the right tool for all jobs. And, |
| 26 | +additionally, that virtually all problems can be solved in any of the |
| 27 | +declarative or imperative paradigms. (Some might produce cleaner, more elegant |
| 28 | +code for a particular problem.) |
| 29 | + |
| 30 | +Paradigms are the hardest thing to learn because you often have to take all the |
| 31 | +knowledge you have about solving a problem in another paradigm and throw it out |
| 32 | +the window. You have to learn new patterns and techniques to be effective. |
| 33 | + |
| 34 | +But we encourage this kind of learning because most popular languages are to |
| 35 | +some degree _multi-paradigm_, and the more techniques you know from more |
| 36 | +paradigms, the more effective you are in that multi-paradigm langage. |
| 37 | + |
| 38 | +</p></details></p> |
| 39 | + |
| 40 | +<p><details><summary><b>In regard to the code challenge solution, why is the '+' operator being used to concatenate strings? I thought we were supposed to use the join() method in Python? </b></summary><p> |
| 41 | + |
| 42 | +Using `join()` to join large numbers of strings is definitely faster in Python |
| 43 | +than using the `+` operator to do it. The reason is that every time you `join()` |
| 44 | +or use the `+` operator, a new string is created. So if you only have to |
| 45 | +`join()` once, versus using `+` hundreds of times, you'll run faster. |
| 46 | + |
| 47 | +That said, if you want to use the `join()` approach, you'll have to have all |
| 48 | +your strings in a list, which uses more memory than just having the two or three |
| 49 | +that you need at a time to use `+`. So there's a tradeoff. |
| 50 | + |
| 51 | +Another tradeoff might be in readability. It might be easier to read the `+` |
| 52 | +version. That's worth something. |
| 53 | + |
| 54 | +Finally, if `+` is fast enough for this case, it might not be worth the time to |
| 55 | +bother with making a list of strings to `join()`. |
| 56 | + |
| 57 | +* [Speed comparison with different ways of concatenating strings](https://waymoot.org/home/python_string/) |
| 58 | +</p></details></p> |
| 59 | + |
17 | 60 | ## Python
|
18 | 61 |
|
19 | 62 | <p><details><summary><b>Are there any helpful VS Code extensions that are recommend for using with Python?</b></summary><p>
|
@@ -198,6 +241,112 @@ quickly
|
198 | 241 | Pylint or Flake8. The latter seems to be a bit more popular.
|
199 | 242 | </p></details></p>
|
200 | 243 |
|
| 244 | +<p><details><summary><b>Can you dynamically add new methods/properties to class through other functions? Or must all properties/methods be declared at once?</b></summary><p> |
| 245 | + |
| 246 | +You can add them dynamically at runtime, but you have to add them to the class itself: |
| 247 | + |
| 248 | +```python |
| 249 | +class Foo(): |
| 250 | + pass |
| 251 | + |
| 252 | +f = Foo() |
| 253 | + |
| 254 | +Foo.x = 12 # Dynamically add property to class |
| 255 | + |
| 256 | +f.x == 12 # True! |
| 257 | + |
| 258 | +def a_method(self): |
| 259 | + print("Hi") |
| 260 | + |
| 261 | +Foo.hi = a_method # Dynamically add method to class |
| 262 | + |
| 263 | +f.hi() # Prints "Hi" |
| 264 | +``` |
| 265 | + |
| 266 | +This is not a common thing to see in Python, however. |
| 267 | +</p></details></p> |
| 268 | + |
| 269 | +<p><details><summary><b>Following this flow: 1) class Dog is created with attributes size and weight. 2) New instance called Snoopy of class Dog is created. 3) Class Dog gets the method bark() dynamically added to it. Question: will Snoopy now have access to bark() method?</b></summary><p> |
| 270 | + |
| 271 | +Yes. |
| 272 | +</p></details></p> |
| 273 | + |
| 274 | +<p><details><summary><b>If a subclass inherits from two superclasses with a method of the same name, which method will the subclass use?</b></summary><p> |
| 275 | + |
| 276 | +The answer to this is twofold: |
| 277 | + |
| 278 | +1. Lots of devs and shops frown on multiple inheritance, so maybe just don't do |
| 279 | + it. |
| 280 | + ([Discussion](https://softwareengineering.stackexchange.com/questions/218458/is-there-any-real-reason-multiple-inheritance-is-hated)) |
| 281 | + |
| 282 | +2. As for the order in which methods of the same name are resolved, check out |
| 283 | + the [MRO Algorithm](https://en.wikipedia.org/wiki/C3_linearization) which is |
| 284 | + what Python uses. |
| 285 | +</p></details></p> |
| 286 | + |
| 287 | + |
| 288 | +<p><details><summary><b>How to handle multiple inheritance and why/when to do it in the first place?</b></summary><p> |
| 289 | + |
| 290 | +```python |
| 291 | +class Base1: |
| 292 | + pass |
| 293 | + |
| 294 | +class Base2: |
| 295 | + pass |
| 296 | + |
| 297 | +class Derived(Base1, Base2): # Multiple inheritance |
| 298 | + pass |
| 299 | +``` |
| 300 | + |
| 301 | +Sometimes multiple inheritance can lead to elegant solutions when a subclass |
| 302 | +needs attributes from multiple, otherwise-unrelated parent classes. |
| 303 | + |
| 304 | +However, [a lot of people find it's not worth the |
| 305 | +trouble](https://softwareengineering.stackexchange.com/questions/218458/is-there-any-real-reason-multiple-inheritance-is-hated)) |
| 306 | +and opt for other solutions, like composition. |
| 307 | +</p></details></p> |
| 308 | + |
| 309 | +<p><details><summary><b>Why use tuples instead of lists?</b></summary><p> |
| 310 | + |
| 311 | +* Tuples are immutable. There's a school of thought that says bugs can be reduced if you make as many things immutable as you can. |
| 312 | +* Tuples are faster than lists to access. |
| 313 | +* Some tuples (containing primitive types), can be used as `dict` keys. |
| 314 | +</p></details></p> |
| 315 | + |
| 316 | +<p><details><summary><b>What's the difference between __repr__ and __str__?</b></summary><p> |
| 317 | + |
| 318 | +Generally speaking, ```__repr__``` is the string a dev would want to see if they |
| 319 | +dumped an object to the screen. ```__str__``` is the string a user would want to |
| 320 | +see if the object were `print()`ed. |
| 321 | + |
| 322 | +The output of ```__repr__``` should be _valid Python code that can reproduce the |
| 323 | +object_. |
| 324 | + |
| 325 | +```python |
| 326 | +class Goat: |
| 327 | + def __init__(self, leg_count): |
| 328 | + self.leg_count = leg_count |
| 329 | + |
| 330 | + def __repr__(self): |
| 331 | + return f'Goat(leg_count={self.leg_count})' |
| 332 | + |
| 333 | + def __str__(self): |
| 334 | + return f'a goat with {self.leg_count} legs' |
| 335 | +``` |
| 336 | + |
| 337 | +In action: |
| 338 | + |
| 339 | +```screen |
| 340 | +>>> g = Goat(4) |
| 341 | +>>> str(g) |
| 342 | +'a goat with 4 legs' |
| 343 | +>>> g |
| 344 | +Goat(leg_count=4) |
| 345 | +>>> Goat(leg_count=4) |
| 346 | +Goat(leg_count=4) |
| 347 | +``` |
| 348 | +</p></details></p> |
| 349 | + |
201 | 350 | ## Coding
|
202 | 351 |
|
203 | 352 | <p><details><summary><b>What are some ways to learn a new language?</b></summary><p>
|
@@ -231,4 +380,3 @@ Also, it's easier to stay motivated if you spend 10 minutes getting a first
|
231 | 380 | version going, even if it's missing 99% of its features, and then starting to
|
232 | 381 | iterate on that.
|
233 | 382 | </p></details></p>
|
234 |
| - |
|
0 commit comments