#๐Ÿ”’ Getting good at Python in a weekend with exercism.org?

175 messages ยท Page 1 of 1 (latest)

junior sand
#

I found the free resource www.exercism.org and started doing the exercises. I have done a dozen or so, and there are a few hundred. Will completing all exercises give me a good grasp of the language?

I am a mid-level programmer without a formal education. I have experience with web development and have started learning systems programming.

I joined a team this week that is working on a Python app. I plan on spending my weekend doing all of the exercises (I am sure it will take me the entire weekend working nonstop). I am just curious if anybody has any experience with exercism.org, particularly their Python course, and what level of understanding (in terms of the Python language, excluding tooling and ecosystem) I can expect to be at after completing the entire course.

low whaleBOT
#

@junior sand

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

pearl knoll
junior sand
#

Thanks @pearl knoll, have you done those exercises yourself?

pearl knoll
#

I mostly wanted to check out the site

#

I mostly used Codewars when I was learning

junior sand
#

Are you working with Python professionally now?

pearl knoll
#

Yes

junior sand
#

What makes a good Python programmer in your opinion (speaking only about knowing the language itself)? How would you say your knowledge of the language has improved and what were the realizations along the way. Understanding the language features does not seem hard, but perhaps there are some aspects I should pay extra attention to along the way.

pearl knoll
#

it's all about being resourceful. You don't have to know how to do everything, but you're good at finding out the answer when you have to

#

I have a task on the back burner that I've never done before and I'm not really sure where to start, but I'm sure once I actually sit down and tackle it, I'll find a way

junior sand
#

What are your goto places when you need to know whether to use setDefault or get on a dictionary for instance? Do you go to cPython, do you use your typings and IDE, or do you use python.org?

pearl knoll
#

Don't memorize "when should I use A and when should I use B". Learn what each one does and make the decision for yourself. One is a hammer and one is a screwdriver. You should eventually know which is right

#

I haven't touched the actual python docs in ages

junior sand
#

Thanks. My IDE (Neovim) gives a signature but no explanation. I use int, list, dict but I noticed now that there is also int, List, Dict from typing. What is the best wayt to get good hover documentation when doing . on an object such as a dictionary or list?

pearl knoll
#

I use sublime and pycharm which both provide that pretty well

#

if I type dict.

junior sand
#

I get that too, but let me show you what I see when I hover

pearl knoll
junior sand
#

That's pretty muc hwaht I see too, but no the help text.

#

I need to fix that.

#

My employer bought be a PyCharm license. Perhaps I should start using it.

pearl knoll
#

I use help and __doc__ a lot

junior sand
#

Their Vim plugin is terrible though

pearl knoll
#

!e

print(dict.get.__doc__)
low whaleBOT
junior sand
pearl knoll
#

and dir to list out the methods

#

!e
print(dir(dict))

low whaleBOT
# pearl knoll !e print(dir(dict))

:white_check_mark: Your 3.13 eval job has completed with return code 0.

['__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__ior__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__ror__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
junior sand
#

That's very helpful

#

Do you have something to evaluate that expression inline inside the editor somehow? I don't want to print and run everytime.

pearl knoll
#

why not?

#

I usually have a few scratch files open

junior sand
#

Maybe that's a good idea.

#

Thank you for the help. Any other practical tips you see yourself doing on a daily basis that you can share? ๐Ÿ™‚

pearl knoll
#

Depends on what stage of my work I'm at

#

I usually start out by writing a bunch of helper functions

#

or just a brief proof of concept of what I want to do, and then I refactor

#

I work in game dev doing pipeline development. My backburner task is our animator wants a geocache (lightweight animation file) of our characters animations for reference. I haven't worked with geocache before, but I'm sure I'll find some good documentation, and I'll start with basic proof of concept like "get a properly exported geocache"

#

then I'll expand it to allow for character selection, and animation selection, etc

junior sand
#

We use poetry, podman, pytest, FastAPI, pydantic, flake8

pearl knoll
#

I'd recommend learning those then if that's what you're using

junior sand
pearl knoll
#

yeah, the confidence of knowing I've solved similar things in the past means I know I'll be able to solve this too

#

I expect to hit some walls for sure, but a strong programmer can get over them

junior sand
#

that's where i want to get to, where the language is not what is keeping me from solving the problem. but tbh i don't find solving these exercism.org exercises especially fun, i prefer working on real problems. but i know that solving the exercises will get me there faster

pearl knoll
#

the problems feel more "real worldly" (to some degree)

junior sand
#

i would do that if there were some help text that would also explain the language, but im not even there yet

#

i just have to get through these exercises i think somehow ๐Ÿ™

pearl knoll
#

yeah exactly, you kinda need some base understanding to tackle those

junior sand
#

the exercises so mundane in a way that i ahve a hard time concentrating fully

#

at the same time, i need to do them (i.e., wirte them) to get the language in my fingers

pearl knoll
#

yeah, it's a necessary evil early on

junior sand
#

otherweise i could just read the text and understand, but i would forget

#

What is the difference between list and List (Titled)?

#

Dict is a variable from typing, but it gives me exactly the same intellisense as dict the built-in Python class

#

It seems I can write def someFunction(arg1: dict) and get the same result as if I were to import Dict from typing.

pearl knoll
#

List is what you must use for the typing hint

#
def foo(data: list):
    ...
junior sand
#

list gives me the same typing hint.

pearl knoll
#

this is fine if you want to say the parameter will be a list

#

but if you want to indicate what it is a list of

#
from typing import List

def foo(data: List[int]):
    ...
junior sand
#

It seems to work for me. Here is the hover doc I get when I use list[str]:

```python
(parameter) current_cart: dict[str, Unknown]

current_cart: dict - the current shopping cart.

vale moat
pearl knoll
junior sand
#

I am on 3.12

vale moat
junior sand
#

Is this correct?

def add_item(current_cart: dict[(str, int)], items_to_add) -> typeof current_cart: 
    """Add items to shopping cart.

    :param current_cart: dict - the current shopping cart.
    :param items_to_add: iterable - items to add to the cart.
    :return: dict - the updated user cart dictionary.
    """

    return current_cart

I know the return value is wrong, but is there a way to do something like that to avoid typing the return value again? Or can I make a top-level type without the typing package?

pearl knoll
junior sand
#

Or should it be dict[str, int]?

pearl knoll
#

if it's modifying the cart in place, it might not even be necessary to return the cart

junior sand
#

How does one make a type of dictionary of same key-value pairs?

pearl knoll
#

I'm not sure what you mean by that?

junior sand
junior sand
pearl knoll
#

that's what classes are

junior sand
#

That makes sense! Does Python have interfaces like those in typescript?

pearl knoll
#

I'm not familiar with typescript

#

What sort of interface are you looking for?

junior sand
#

Here is what the computer says:

No, Python does not have a native "interface" concept like TypeScript. Instead, Python uses a different approach called duck typing and provides tools like Abstract Base Classes (ABCs) to achieve similar goals.
#

But that's easy enough to do I think so interfaces in the TypeScript sense are not needed. Classes are also much more powerful and general purpose I think.

#

TypeScript is a superset so it knows nothing about JavaScript

vale moat
#

Because it's kinda annoying to make an init and all that bloat for a class in Python, there are conveniences like dataclasses

#

!e

from dataclasses import dataclass

@dataclass
class Item:
  value: float
  quantity: int
  name: str
  description: str | None = None

item1 = Item(
  value=10.0,
  quantity=5,
  name="banana"
)

print(item1)
low whaleBOT
junior sand
#

That looks a lot more like a convenient interface from TypeScript

#

Do the dataclasses allocate memory?

vale moat
#

If you want to be "Pythonic", then duck typing means you pass a function "whatever" as long as it does what you expect, like have a run() method.

#

In which case you can make a protocol for the typehint

junior sand
#

What is understood by being "Pythonic"? I want to impress my colleagues ๐Ÿ™‚

pearl knoll
#

It typically means the way you approach certain tasks

#

!e

shopping = ['milk', 'eggs', 'bread']

for i in range(len(shopping)):
    print(shopping[i])
low whaleBOT
pearl knoll
#

this wouldn't be considered pythonic, even though it's a valid solution to printing out every item in a list

#

!e

import this
low whaleBOT
# pearl knoll !e ```py import this ```

:white_check_mark: Your 3.13 eval job has completed with return code 0.

001 | The Zen of Python, by Tim Peters
002 | 
003 | Beautiful is better than ugly.
004 | Explicit is better than implicit.
005 | Simple is better than complex.
006 | Complex is better than complicated.
007 | Flat is better than nested.
008 | Sparse is better than dense.
009 | Readability counts.
010 | Special cases aren't special enough to break the rules.
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/L5JVBLNZR46ZTQ2BS72MMWWEZ4

junior sand
#

That's very interesting. I would have done it the non-pythonic way.

pearl knoll
#

!e

shopping = ['milk', 'eggs', 'bread']

for item in shopping:
    print(item)
low whaleBOT
pearl knoll
#

we would typically iterate the list directly

#

and even if we need the index, we use enumerate

#

!e

shopping = ['milk', 'eggs', 'bread']

for i, item in enumerate(shopping):
    print(i, item)
low whaleBOT
junior sand
#

enumerate is interesting

#

I learnt about it today

#

In JavaScript it is possible to do just i, item in shopping.

#

Isn't shopping an ordered list, and if so, doesn't each item have an index already?

pearl knoll
#

yes, we could just access any index with something like shopping[0]

#

but if we want each item and its index, we need range or enumerate

junior sand
#

Got it.

#

I don't understand computer science well enough to understand why a list by itself does not have an index. I read that list is a hasmap/hashtable. My understanding is that a hashtable is just a way to look up values quickly, and hashmaps here I guess refers to the underlying implementation in the cPython code for an ordered list, which is unrelated to whether items in a list has an index or not not?

pearl knoll
#

Where did you read that a list is a hashmap?

junior sand
#

Oh, you are right, and I am wrong

pearl knoll
#

dict is, but not list

junior sand
#

list is a dynamically allocated array

#

it is an iterator that requires calling next to get the next value and it does not store the index I guess.

pearl knoll
#

list isn't an iterator

#

it's an iterable

#

you can't call next on a list

junior sand
#

My lack of understanding again

#

So enumerate is what calls the iterator on the list, which is an iterable?

pearl knoll
#

!e

print(dir(list))
low whaleBOT
# pearl knoll !e ```py print(dir(list)) ```

:white_check_mark: Your 3.13 eval job has completed with return code 0.

['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
pearl knoll
#

if we look at the methods of list, we can see that it implements __iter__

#

this is the method responsible for returning the iterator that will be used in a for loop (among other things)

#

!e

class CustomLooper:

    def __iter__(self):
        return iter([1, 2, 3])



for i in CustomLooper():
    print(i)
low whaleBOT
junior sand
#

!e

print(list.__iter__)
low whaleBOT
junior sand
#

Is there a way to print the implementation of the __iter__ constructor for list?

pearl knoll
#

like the actual code?

junior sand
#

Yes

pearl knoll
#

Not from within python

#

list is implemented in C, so technically its methods are just stubs. You'd have to find it in the C repo for python

junior sand
#

(btw, why is list spelled in lowercase if it is a class. I thought all classes in Python use CamelCase)

pearl knoll
#

also this is PascalCase and this is camelCase

junior sand
#

Thank you

#

What does <slot ...> mean?

#

<slot wrapper '__iter__' of 'list' objects>

pearl knoll
#

it's because it's a method that's actually implemented in C

#

!e

class CustomLooper:

    def __iter__(self):
        return iter([1, 2, 3])


print(CustomLooper.__iter__)
low whaleBOT
pearl knoll
#

we would get a different result from printing a method from a non-C class

#

!e

class CustomLooper:

    def __iter__(self):
        return iter([1, 2, 3])


print(CustomLooper.__iter__)
print(CustomLooper().__iter__)
low whaleBOT
pearl knoll
#

you're more likely to see "bound method"

junior sand
#

I got it.

  • Bound is a method on an instance.
  • Function is a raw method on a class (perhaps does not need to be part of a class)
  • Slot is a pointer, or some interface to the cpython code.
pearl knoll
#

yup exactly

junior sand
#

Speaking of cpython. Our team was looking at some code that made requests using requests. A colleague thought the code was slow so we tried to benchmark it. I suggested declaring the test fixtures outside the function declaration (in this the function that got called when a request was made against the FastAPI endpoint), either at the top-level of the module or in the subpackage inside the __init__.py file. My thinking was that perhaps that would allow us to move the memory allocation from the stack to the heap and be able to amoritize the cost of the initial memory allocation for the declared variables we were working with. It did not work.

#

How does one take a methodic approach to writing performant code in Python?

tender forge
junior sand
#

Is there a way to investigate what is actually going on "under-the-hood"?

pearl knoll
tender forge
#

Heck no tag for it

pearl knoll
junior sand
#

Yes, I think that was our bottleneck

pearl knoll
#

If speed is your absolute priority, you wouldn't be using python

junior sand
#

It consumed 10 ms and our source code consumed 10 ms.

junior sand
#

So, either our source code was already optimized by Python in some magic way, or we did not manage to optimize it ourselves.

vale moat
#

Fixtures are mostly helpful if multiple functions use it. And in that case if there are no side-effects, you could make it module level f.e.

#

So you don't have to call it separately for each test

junior sand
#

We tried hitting the endpoint in a loop but the cost of the declaration at module level did not amortize the initial cost to initialize the variables from what we could see.

#

Sorry for the off-topic discussion. I should probably get on with learning basic Python/programming instead. ๐Ÿ˜„

low whaleBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.