#pedagogy

1 messages · Page 9 of 1

worldly dewBOT
#

@silent goblet :white_check_mark: Your eval job has completed with return code 0.

001 | range(1, 1547839548609384096839408)
002 | range(1547839548609384096839407, 0, -1)
cedar ibex
#

no, it does just give a reversed range

#

nvm what I said earlier

silent goblet
#

anyway... I think we're supposed to talk about pedagogy and stuff

nova heath
#

Possible to pin?

misty dirge
#

!warn 461097636791844865 teaching people about range when you should be teaching people how to teach range

worldly dewBOT
#

:incoming_envelope: :ok_hand: applied warning to @silent goblet.

silent goblet
#

well it's pretty hard to teach range if you think it's a generator 🔥

blazing tundra
#

Shitposting publicly smh

misty dirge
#

let that be a lesson to all of you to watch your step.

keen moat
nova heath
fluid plume
#

lemme add a touch of pink and then not say anything else for the next hour

blazing tundra
silent goblet
#

Anyway, let's start discussing some teaching stuff

#

I don't think our previous messages are in range of this channel topic

#

After all, we should generate something useful here. Just to reiterate my point

fallow terrace
#

this is too much lmfao

silent goblet
fluid plume
silent goblet
#

it also makes the mistake of calling range a function 😩

silent goblet
misty dirge
#

What should one do when someone they're trying to help has been taught to create getter and setter methods (not properties)?

#

This is a tough one for me, because they might be penalized for going against the conventions of the course.

silent goblet
#

I think getters/setters/public mutable attributes are (usually) an antipattern, teach that 🙂

weak mortar
#

first

#

oh shit when was this channel made

#

and what is this for

misty dirge
weak mortar
#

people were talking about this

#

IM THE 300th MESSAGE LETS GO

silent goblet
#

this channel is about pedagogy 🙂

#

Now you might ask: Pedagogy? What is that?

gentle oriole
#

What are your tips for teaching people about python environments and stuff like virtualenvs?

weak mortar
#

i checked pins

fallow terrace
gentle oriole
misty dirge
weak mortar
keen moat
weak mortar
#

Eg. my matplotlib only works on a venv

#

advise em to use em

#

Nope

oblique stump
weak mortar
#

about the issue

ripe folio
#

DID SOMEONE SAY THE RANGE() FUNCTION

oblique stump
#

I like to walk through the basics of like "this is a venv, let's review the venv module and the 3 commands to use it, this is why you want to use a venv"

"if you're using PyCharm, press these buttons to add things to the PyCharm venv"

misty dirge
#

don't keep the range shitposting going sad_cat

blazing tundra
gentle oriole
silent goblet
silent goblet
oblique stump
# gentle oriole For something like pycharm I'm often conflicted between helping them install the...

It's one of my beefs with PyCharm and why I generally won't recommend it to someone who is brand new to coding.

I'll generally first help them get it installed, just so if they need to go or if I need to they at least won't be frustrated anymore. I then like to review what a venv is and then give them an article to read on their own time.

I don't really like to change to their PyCharm to the system interpreter because I've found that to be a can of worms in PyCharm specifically.

fallow terrace
#

My course uses camelCase for variables...

misty dirge
#

getting so anxious rn

#

(about these antipatterns in python courses)

misty dirge
keen moat
oblique stump
keen moat
#

And by the time they learn Python, dealing with venvs will be much easier

gentle oriole
#

Procedure?

fallow terrace
#

... what do they say it is?

misty dirge
#

it's not a pure function, I guess. are you taught that it's a subroutine?

#

I... guess?

oblique stump
silent goblet
#

In Python terms, it's a function. Conceptually, it's a procedure

oblique stump
#

If it's VSCode I will 1000000% tell them to just change interpreters if they're in a rush or not at a point where introducing venvs makes sense

misty dirge
#

tell them to do import types; print(isinstance(hi, types.FunctionType))

keen moat
misty dirge
#

sure

fallow terrace
gentle oriole
oblique stump
keen moat
#

yeah that's true. Maybe JetBrains Fleet will do something similar

fallow terrace
#

As much as I'm not a fan of IDLE now, I'll gladly recommend that to beginners

waxen fox
#

hmm, what is the best way to teach OOP to someone? i remember that someone in here (i think it was scoff) told me to make a vending machine class with a few methods and that helped me understand the basics, but i wonder if anyone has other go-tos for teaching OOP via say a prompt

#

i used IDLE until I got serious into proramming

silent goblet
#

I wrote my first commercial (freelance) project in gedit

#

🔥

tight panther
#

most of the pycharm venv issues can be fixed by just using the terminal it provides, which while less convenient than a proper one is probably still better than the default windows 10 one most users will use

silent goblet
# silent goblet Actually though, it's an interesting discussion of whether that's a good idea. T...

cc: @ripe folio
I think it makes sense to teach that int, str, range etc. are functions because the person at that point is already familiar with functions like print and input and maybe len, abs, something like that; but they don't know about classes yet. So while it would be technically incorrect, I think it's a good way to leverage existing knowledge. (just make sure to "reveal the truth" later in the course)

fallow terrace
#

Honestly, there are some nice web editors too. We use onlinegdb for school, and it works fine.

gentle oriole
#

Tbh I don't think VScode is too bad for beginners. I would almost recommend that over something like Mu or Thonny, as it's a bit more transparent and can work better when e.g. following a tutorial that asks you to run stuff in terminal to install stuff

oblique stump
silent goblet
#

repl.it is pretty nice. It

  • provides an isolated environment where you can install packages
  • doesn't require changing anything in your system
oblique stump
obsidian loom
silent goblet
#

range? yes. But if you're teaching Python 2 you should probably be fired lol

#

for someone starting out, that doesn't matter much

ripe folio
silent goblet
#

I think though that establishing the proper terminology as early as reasonable is a good idea.

ripe folio
silent goblet
tight panther
#

false positives?

silent goblet
#

squiggly lines

obsidian loom
oblique stump
#

beginners thinking that linter messages are actual error messages

silent goblet
#

I have seen quite a lot of beginners here thinking that the squiggly lines is actually a runtime issue

oblique stump
#

"It can't resolve the reference but I swear I've installed it"

gentle oriole
ripe folio
oblique stump
#

but also like... props to them for reading that. It bodes well after you explain what a linter is

obsidian loom
#

Well, I've never actually run into anyone who perceived warnings as errors, but they're usually simple enough to fix them regardless

#

I feel like it's one of those things that you kind of just roll with until one day it clicks

silent goblet
tight panther
obsidian loom
#

And I feel like it's helps a lot more than it hurts, imo it's a great way to start building good habits

tight panther
gentle oriole
silent goblet
#

yeah

gentle oriole
#

Sometimes I get carried away...

silent goblet
#

like we just now with range

obsidian loom
tight panther
#

Yeah, not hovering is definitely a thing some people don't do, and can't really fault pycharm there as the colors used are fairly clear with what they're trying to convey

gentle oriole
#

It would depend on your linter setup as to whether an unresolved import is shown as a warning or an error, I'm pretty sure I've seen it as both

silent goblet
#

Any tips on explaining functions?
Every time I explain what return does I'm trying to find a function the person has used, like abs or len or min or max, something like that, to re-implement it. It is really surprising to me that they don't get to use these functions before writing their own. I think it's a teaching mistake

obsidian loom
#

Same as variables and such

tight panther
#

I think that's generally one of the first thing one uses

silent goblet
#

like... what kind of language?

#

Haskell?

silent goblet
#

you can't re-implement it yourself

#

without using int

obsidian loom
#

Rust does something like that

#

As do Nim and F#

silent goblet
#

if someone has already learned Haskell or Rust or OCaml or Scala they are probably capable of figuring it out themselves 😄

#

unless I misunderstand you

#

ah

#

i c

#

I think it's actually much easier there. You can't not return something

obsidian loom
#

I do wonder how effective it would be to try using mathematical functions to explain programming functions

silent goblet
#

I have tried that as a seemingly obvious strategy

#

I think we also have a lot of people here who just haven't been taught them yet due to their age.

ripe folio
#

I usually use replacements of operators as examples

#

add() is a classical example

#
def add(a, b):
    return a + b
obsidian loom
#

Well, even something as simple as like f(x) = x * 2 and providing examples such as f(2) = 4

#

Because I think as long as someone can understand the correlation between input and output, then they should be on their way

silent goblet
gentle oriole
silent goblet
ripe folio
#

Simply saying that functions allow you to not repeat yourself clicks with a lot of people I'd say - it just makes sense that you would eventually want to group code together and call it multiple times.

sudden hazel
#

reimplementing something like len imo would be more confusing since then you'd have to use the dunders which are extra scary 🙂

silent goblet
obsidian loom
gentle oriole
silent goblet
#

Yep

#

I think it's sometimes easier to explain return if they already have some kind of project

#

or... functions in general

#

or maybe construct an artificial example with duplication.

#

Actually, I think saying that functions exist to reduce duplication is misleading. A function is a means of creating modularity (refactoring a program into a composition of small parts), and reducing duplication is only a side effect of modularity.

#

but maybe it's a reasonable white lie

obsidian loom
#

I might say that it doesn't even reduce duplication, and that in fact it kind of enforces it by making it easier

silent goblet
#

Real projects very often have functions that are only used once 🤷

sudden hazel
#

mhmm

gentle oriole
#

I think it's best to explain the (potential?) benefits of using functions. Which then could include things like making code more readable

#

And reducing duplication etc

tight panther
#

I think teaching the abstraction they provide is the first thing that should be shown

silent goblet
#

at least at that immediate moment

obsidian loom
#

Hmm, I do wonder how helpful it would be to first teach someone bitwise operations and such

#

I should clarify I don't mean in the context of programming

#

I just mean very simple circuits

#

I'm just thinking about how a lot of the operations are actually abstractions of other operations

ripe folio
#

If you're learning about circuits then yes, in the scope of programming languages then no

obsidian loom
#

And how their usefulness as abstractions proves to be highly beneficial

tight panther
#

Well, that's the point, they are abstraction so you don't have to think about what they're doing. I don't think that information would be too useful at the start to someone who wants to learn programming

obsidian loom
#

Hmm... Well, I believe my reasoning is justified but I'm also thinking that maybe my examples isn't totally accurate

silent goblet
#

yeah, I think that goes for most of those languages

silent goblet
obsidian loom
silent goblet
#

I think the teaching materials for Haskell, Rust, Scala etc. are already (usually) aimed at people who are familiar with programming, because they're pretty complex languages.

nova heath
#

One thing I really like about having this channel is the ability to discuss project-based learning vs guided teaching

#

For example, in a 1-1 tutoring situation with someone beginning to program, how much input should the educator give, vs prompting the tutee to look up online what they need to do

#

Such as coming in with no programming experience, then being promoted to search "how to make X in python", compared to showing them the basic steps of how to make X, and letting them put it together themselves

#

There's sides for both, mostly due to time constraints in teaching sessions, but I've seen much more rewarding learning experiences once the student starts picking up how to structure their Google questions, and how to quickly skim through potential solutions

misty dirge
#

I'm back, sort of. Are you all talking about pedagogy or no?

cosmic aspen
#

Paper and pen sim also ok

silent goblet
#

you can also bring real hardware ICs 🤷

#

but that might be needlessly confusing if they haven't had physics classes or something

misty dirge
cosmic aspen
misty dirge
pallid crystal
cosmic aspen
#

Had propositional logic and truth tables in HS too but not in that special high school by taught by a boring former priest and some programming in GWBasic that was taught by a com eng that taught bit operations

misty dirge
cosmic aspen
misty dirge
pallid crystal
#

any logic propositions

pallid crystal
#

i should've generalised the variables too

misty dirge
pallid crystal
#

yes. there seemed to be emphasis on the one way nature of "implies", as though previous students didn't get it or something

rare oracle
#

Same

pure heron
#

that's interesting, that came very naturally to me. I've never really seen why people struggle with that - a Python for loop has a "body" that runs repeatedly, once for each value in the object provided to in, with each item assigned to the variable name you've chosen for the corresponding run of the body

pure heron
rare oracle
#

i understood more while loops than for loops

#

im still a beginner and have learned more since then but yeah i got stuck at that part

pure heron
#

that's interesting - for loops and while loops are so similar - the body fires 0 or more times, depending on the particular iterable/condition given. I would have thought they'd be about equally easy to learn

#

it's just that the while body runs until the condition becomes false, and the for body runs until the collection runs out of values

#

I guess it's a little bit tricky that for includes a "hidden" variable assignment on each iteration

rich mural
#

I'd almost think for loops would be easier to understand. It feels like it'd be more intuitive with a loop that repeats a fixed number of times, or once per item in a list, whereas while loops are more dynamic.

#

But I guess not.

silent goblet
#

@ruby saffron This is a discussion channel, not a help channel. If you want help with a Python question, please see #❓|how-to-get-help

#

Unless you're a teacher who's stuck on a solution for the homework they gave, which is possible, I guess 🙂

silent goblet
#

What are some actually useful examples when teaching inheritance? All the classic "Dog extends Animal" and "Circle extends Shape" are kind of nonsensical

#

I'm having trouble coming up with an example because I myself use inheritance (implementation inheritance) pretty much never

#

And should inheritance be taught early? Or maybe it's actually not that important, and could wait until later?

rich mural
#

Maybe something that needs to be able to read data from multiple sources

#

So you can have like a file implementation, a REST implementation, a console i/o implementation, etc.

#

Not sure what specifically, but that feels like it'd get the practical utility of inheritance across

rich mural
#

Or at least not super-beginner

silent goblet
#

for which you don't really need to do anything in Python, as we have duck typing

#

(or you can use an ABC, but it feels like a weird thing to first teach with inheritance)

rich mural
#

I dunno, I think interface inheritance is the most common and useful type of inheritance.

#

And for the use case I described I'd absolutely use an abc

silent goblet
rich mural
#

It's particularly useful when you have an interface with multiple methods.

silent goblet
rich mural
#

I mean, the point is getting across the concept of inheritance, not specifically to teach abc, but if abc is the best way to teach the general concept, you might as well.

#

And people like examples with real-world utility.

#

The core idea is to be able to use something specific in a more general context without having to care about the specifics.

#

I think making the code structure explicit with an abc helps illustrate that.

#

Then maybe you can go on to elaborate on how it's not always necessary in Python thanks to duck typing and you have to decide on a case by case basis how to implement it.

#

Honestly, I dunno, maybe it's best to learn OOP in a language like Java or C# where everything is explicit.

#

Then you can go back to Python with OOP as a tool to use when it's appropriate.

silent goblet
#

is implementation inheritance really so useless that there isn't even a good example?

rich mural
#

Or well, actually, implementation inheritance can often be replaced with composition.

#

Implementation inheritance is kind of inherently messy

#

You tend to slap it on when you want to customize something that wasn't meant to be customized

#

And it might work, but it's often not nice

#

It generally means a class with only abstract methods

#

And no fields

#

There are explicit language constructs for it in many languages

#

In Python you would define them explicitly with an ABC

#

So it's basically like a blueprint for a certain behavior with no associated implemention details

#

And you subclass it to specify an actual implementation of the blueprint

silent goblet
#

It seems like teaching "interface inheritance" is a bit messy in Python because you'd need to involve some more advanced tool like Protocol or ABC.

I think the more important thing here is subtyping/polymorphism, and (interface) inheritance is just one way of achieving it. So maybe the thing that should be taught first is polymorphism? There are lots of good examples here

silent goblet
rich mural
#

If you understand polymorphism, I think a lot of other OOP stuff becomes much more intuitive

#

It's all just different variants of polymorphism

silent goblet
#

I wonder if polymorphism is better taught with a language that doesn't have inheritance at all

#

like Haskell, Rust, Go

rich mural
#

Well, Rust has traits

neon pasture
#

Maybe just start with duck typing for polymorphism, and explain inheritance later

silent goblet
rich mural
#

I mean, it's polymorphism

#

You "inherit" an API

rich mural
#

Which might help illuminate some of the subtler nuances.

silent goblet
#

"Inheritance was really popular in the 1990s, but now it's mostly hijacked to express interface implementation 😄 "

rich mural
#

You just generally don't want to use inheritance to add unplanned customization

#

You should architect your design with explicit "plugin points" from the beginning and not stray too far from that

#

And you can share behavior with composition instead of inheritance in most cases

cosmic aspen
#

BankAccount as base class with deposit and withdraw methods and ownership info plus account no ...savings and checking to inherit from BankAccount

#

Translate to Python

rich mural
#

I mean, these types of examples are fine, but they feel a little artificial

cosmic aspen
#

True but we aim to teach

rich mural
#

Yeah, indeed, but I think it might be even better to find an example that simultaneously gets the point across and feels like something you might actually use in a real project.

(I do work in fintech so it's actually not super super far from some of the business logic I've had to implement, but I don't think this is a typical case where you would want to use inheritance for the vast majority)

cosmic aspen
#

Lol and i mentioned banking

rich mural
silent goblet
#

oh, I think I found a somewhat useful example

#

Exceptions

rich mural
#

Yeah, that's a challenge with teaching OOP in general, because it's inherently a tool used to manage complexity in larger codebases.

#

You just don't need OOP for a small project.

coarse quest
#

Omg, I just came here from #changelog, omg, omg, I'm in love with this channel already

cosmic aspen
silent goblet
#

damn it, I wrote a message and Discord just dropped it...

silent goblet
# silent goblet Exceptions
class ParseError(ValueError):
    def __init__(self, message, pos):
        self.message = message
        self.pos = pos
        super().__init__(message, pos)
  • this reuses ValueError's args attribute and __str__ method, so you can go whenever you raise ValueError and replace it with a more specific ParseError
  • you get extra fields (and maybe some extra logic later) specific to parsing
pine quartz
#

Perhaps another example would be to take existing subclasses in the stdlib and reimplement them - defaultdict and Counter for example.

silent goblet
#

well, defaultdict breaks LSP in a bunch of ways 🙂

#

However, there is a talk where Raymond Hettinger explains how inheritance is used in Python. And he claims that you can give up on LSP if you think it's cool

#

Liskov Substitution Principle

#

Basically, a supertype (parent class or interface) defines some properties that must be true about it. Such as:

for all k in a_dict.keys(), a_dict[k] gives a value
for a value not equal to any value in a_dict.keys, a_dict[k] raises KeyError
#

LSP states that subtypes (subclasses or implementers) should preserve these laws

rich mural
#

If you have some code that works with a supertype, it should work with the subtype, basically.

silent goblet
#

yeah

#

The issue most of the times though is that these laws are implicit, not stated.

rich mural
#

How is this related to programming pedagogy?

misty dirge
#

How useful are the "gang of four" design patterns? Should a software engineering course that uses Python include them? Should any software engineering course include them?

neon pasture
#

I would argue people should at least know about them, considering how ubiquitous they are, even if some of the more elaborate ones are perhaps not all that needed for most modern applications.

misty dirge
#

Personally, I think the distinction between a lot of the patterns is often far-fetched. And since the authors mostly had C++ in mind, I don't think a lot of them really apply to Python.

misty dirge
#

the course was Java-oriented, however.

neon pasture
#

yeah, memorising them is a bit pointless, as is going over all of them. But one should at least know that such things exist and where to find an explanation of them. They are pretty needed in java and C++ (though in new C++ you can also probably do without), and I have run into a few scenarios in python where they do help, but they are indeed not universally applicable.

misty dirge
#

I'm looking at the list of creational patterns. For Python, I think they can all be distilled to "you can make class methods for specific instantiations", whether that be some pre-processing of the arguments before passing the results to __init__, calling __init__ with the same arguments each time, etc.

#

and forget about the singleton pattern, obviously.

neon pasture
#

I agree. Maybe you could justify an abstract factory, but that's quite specific.

misty dirge
#

AbstractBeanFactoryFactory
Interface

#

Ongoing topic: How useful are the "gang of four" design patterns? Should a software engineering course that uses Python include them? Should any software engineering course include them? Feel free to continue this topic or start a new one.

rich mural
#

I wouldn't be surprised if detailed descriptions of all of them are easy to find this way.

misty dirge
#

I wouldn't be surprised if conflicting descriptions of all of them are easier to find.

rich mural
#

Really? Do you have any examples of that?

real cloak
#

New channel?

silent goblet
rich mural
#

You could include examples of design patterns in an SE course

#

But not all of them

silent goblet
#

with tasks like "come up with a project where you use patterns X, Y, Z" which get the point of patterns 180° wrong

neon pasture
#

what is IMO pretty useful are architectural patterns, things like MVC, client server, ... But yeah, design patterns only make sense if the student runs into a situation where they can be useful, which can be a bit hard to architect.

misty dirge
stone juniper
cedar ibex
#

I've always found the word pattern not really fitting of the smaller ones like the Singleton one

sleek stratus
#

how should I explain to a beginner how or works?
they tried doing like string != 'a' or 'b' or 'c' etc

amber hill
#

Not empty values are "truthy", so you can sorta consider this to be True or True or True

#

since or is short circuiting, the first one is returned

#

so, its the same as string != 'a'

oblique stump
#

I think the or-gotcha is a good opportunity to explain how logical statements work. Computers will interpret your instructions literally, and even though Python is easy to write/read, it's still you providing a set of instructions.

So it can be a good way to explain how those expressions work in Python and some alternatives

silent goblet
#

I think it's kind of hard to explain in a meaningful way without explaining everything about short-circuiting, truthy values, and how or and and work

rich mural
amber hill
#

truthiness and falsiness is pretty weird

rich mural
#

So maybe you could illustrate that in this case by putting in brackets

oblique stump
#

I've found adding in brackets around the expressions helpful for explaining

rich mural
#

((string != 'a') or ('b')) or ('c') is how Python will read it, in fact

amber hill
#

wait a min... i was wrong then

#

ah yes, operator precedence 😅

sleek stratus
#

thank all :D

misty dirge
#

The or gotcha might also be a good time to explain that even though Python uses English words in the language's core vocabulary, it is not intended "be like English"

#

In other words, Python is not COBOL

pure fog
wintry pilot
silent goblet
#

They are really abstract/artificial

#

And especially the lack of examples from real libraries that thousands of people use is really worrying.

#

So the website looks really academic, and it doesn't comment on which patterns are used when in which language.

silent goblet
#

And some examples are just bad code

silent goblet
# silent goblet And some examples are just bad code

Let's pick on this example:
https://refactoring.guru/design-patterns/iterator/python/example#example-0--main-py

  1. You don't need to inherit from Iterator or Iterable to become an iterator or an iterable. Just implement the right methods. I think this is the more common usage.
  2.  _position: int = None
     _reverse: bool = False
    

What is the purpose of these being class variables? And why do you lie by setting an `int` class variable to `None`? 3.py
def init(self, collection: WordsCollection, reverse: bool = False) -> None:
A website about design patterns should really know better than this flag! Have two classes. (or as I explained below, `__reversed`) 4.py
AlphabeticalOrderIterator


Now let's pick on `WordsCollection`
5. ```py
    def __init__(self, collection: List[Any] = []) -> None:

5.1. This should be a List[str], or rather Sequence[str].
5.2. This is one of the rare cases where mutable defaults are actually going to cause a lot of trouble, because the add_item method is mutating this object!
6. Overall, this WordsCollection does not have any purpose. It is just a
7. py def __iter__(self) -> AlphabeticalOrderIterator: def get_reverse_iterator(self) -> AlphabeticalOrderIterator: Instead of AlphabeticalOrderIterator, these could just use iter(self._collection) and reversed(self._collection)
8. In Python, get_reversed_iterator is spelled as __reversed__. That way, you can use the reversed function on the object.
9. py def add_item(self, item: Any): The Any should really be a str. I would also add -> None for consistency.

  1. Overall, this combination of two classes doesn't add anything that list didn't already have. It also doesn't demonstrate how iterators are already widely used in Python, in the standard library or in popular third-party libraries.
wintry pilot
#

Fair points, I didn't actually notice the language-specific code examples but that definitely looks a little weird

neon pasture
#

honestly, talking about the Iterator pattern in a language where iterators are part of the language itself makes about as much sense as talking about the inheritance pattern or the class pattern.

silent goblet
#

The GoF book itself acknowledges that Smalltalk and C++ have different sorts of patterns. Some patterns are needed in C++ that are not really a problem in Smalltalk.

misty dirge
#

Topic: Getters and setters methods and for i in range(len(...)): are two common non-pythonic patterns that come up in Python courses due to the influence of other popular languages. What other examples are there, and what do we do about it?

#

side note: I think iterating over range-len is fine if you're implementing an in-place sorting algorithm for educational purposes (as if there's ever another time that one would need to implement a sort).

misty dirge
#

ah, give me an example so I can get angry about it lemon_hyperpleased

pure fog
#

hypothetical and stylized, but conceptually not far from what i've seen in help sessions and #software-architecture:

class DataCleaner:
    def __init__(self, x):
        self.x = x

    def clean(self):
        if self.x is None:
            self.x = 0
        elif abs(self.x) > 100:
            self.x = min(100, max(-100, self.x))

cleaner = DataCleaner(123)
cleaner.clean()
print(cleaner.x)
#

my usual response is "why isn't this just a function that takes x and returns the cleaned version? why do you need an object with internal state? seems like unnecessary complexity and abstraction, not to mention you have now introduced mutable state which is always messier."

#

usually their response is "omg i just didn't think of that, my code is so much simpler now."

#

sometimes i have to write it out to make it clear what i mean, def clean_data(x): ... etc

silent goblet
tardy inlet
#

Hi

silent goblet
#

I don't necessarily agree with 100% of the video, but I think the message is goot

wintry pilot
silent goblet
#

or a functional language 🙂

#

I guess in general it's a good idea to get to know different paradigms

pure fog
#

To be clear, I think using classes as "data containers with names" is a great idea

#

I also think "mutable objects with message passing" can be a nice way to structure certain kinds of programs

#

Problems arise when you start mixing those two concepts, or when you don't have a clear understanding of their differences to begin with

#

That they are essentially two separate concepts and separate design patterns, that happen to use the same language features

silent goblet
#

ok it's different

#

One common pattern nowadays seems to be "procedural programming with classes", where you have an anaemic model (maybe even coupled to an ORM) and "services" (transaction scripts?) that operate on those dumb containers.

#

And sometimes these cases would really benefit from extracting at some cases into a graph of objects, or at least building some kind of domain, and not acting on dumb records that are specific to a certain API or maybe a database structure.

#

anyway... I'm starting an off topic rant

spark oak
silent goblet
#

hm, I didn't consider that documentation is part of the topic here

#

but looking back it kinda makes sense

noble aurora
#

yes, jupyter notebooks are great for this

silent goblet
#

personally running a notebook would be a lot of effort to me because I haven't set it up 🙂

#

but maybe there are some online solutions?

noble aurora
#

yeah, google colab

#

the free tier is plenty good enough for anything school related

spark oak
pure fog
#

maybe start with "structs" and the build into "classes" if needed

waxen fox
#

oh, I've thought of one!

code structure like this:

def main():
  ...

if __name__ == "__main__":
  main()

you shouldn't jam everything into a main function tbh

plush quarry
shy quarry
#

hog

wintry pilot
waxen fox
wintry pilot
rich mural
fleet pulsar
#

what I do think matters is blindly shoving in if __name__ == "__main__" just because that's similar to other languages

#

There aren't many cases where you'd genuinely need to do this, and even then there are alternative options, such as a separate module that contains the actual logic and imports things from other modules, and I feel like this is ignored far too often

rich mural
#

Sure, I mean, you use it when you want to be able to execute the file as a script from the command line.

hallow pelican
#

Its useful for running most ASGI/WSGI servers since you can usually run a development server from within the file, but in production you're running it with a real runner like gunicorn or unicorn so it needs to import from the file

misty dirge
#

Topic: Sets are a powerful feature, but often aren't taught to novices. How important is it that one understands hashing to use sets, and in that light, when should they be taught relative to other container types?

rich mural
#

Particularly in a language like Python, it's easy to introduce dictionaries early, and they are of course immensely useful. And once you've introduced dictionaries, it feels pretty trivial to explain sets.

#

I think it's probably a good idea to explain hashing and immutability at the same time, since keys must be hashable, and you can get into serious trouble if you use mutable keys.

noble aurora
silent goblet
#

But yeah

misty dirge
#

Somehow it didn't occur to me that hashing is also fundamental to dicts, though I don't think beginners wonder about that very much, since dict keys in beginner code are almost always strings

silent goblet
#

It would just be overwhelming

misty dirge
#

But then at the same time, most set elements in beginner code are going to be strings

#

also, this

class HorribleHashable:
    def __eq__(self, other):
        print('Arbitrary side effect!')
        return False
    def __hash__(self, other):
        return 420
noble aurora
stone juniper
#

you could say they remove duplicates and they have handy methods like intersection
if they're savvy enough to wonder why you can't do that with lists, it's probably fine to get into hashtables

pure fog
#

"a list is a sequence of slots, each slot works the same as a variable"

#

which means that the student should have a clear understanding of "variables as labels attached to data" - pretty much all of the weird behavior in python around mutability is a natural, perhaps even obvious, consequence of that model

stone juniper
#

maybe we should be teaching sets first, and then lists can be like "wOW they're like sets but with order!"

fleet pulsar
#

On a similar note, it's important to properly introduce tuples and lists

#

Because IME, a fair amount of beginners see tuples as just worse lists

#

I feel like the semantic difference is often overlooked, which leads to people who weren't familiar with programming before viewing them as versions of each other when it's really not the case; yes, lists are effectively mutable tuples, but their roles are very different, and it's python specifically that has tuples as just an immutable sequence, it's not really the case in most statically typed langs

misty dirge
#

I think an important distinction is that (unless you have a really weird program design) everything in a list is usually of the same type, and there isn't really an expectation that the length of the list will be especially significant. Whereas with tuples, there's some expectation that the whole tuple represents a specific thing, and each element represents a different property of that thing.

#

like if you have coordinates, talking about tuples as (x_coordinate, y_coordinate) makes sense. Or you could even have a Dog tuple of (name, breed, weight), where each element represents that property consistently. No one would ever do that with lists.

fleet pulsar
#

Yeah, tuples tend to have structure with each component having its own meaning, while lists (homo- or heterogenous, regardless) give all elements the same meaning - an item in a container, one of many

misty dirge
#

that said, this distinction is obvious to experienced developers. I don't really know how to convey it to a beginner, since these distinctions sound kinda pointless unless you've encountered a situation where it matters

#

Interestingly, if you want to have a "list-like" tuple (the length and order having no special significance, like lists), the type annotation is tuple[contained_type, ...]

fleet pulsar
#

I think the general order should be something like (tuples <-> lists) -> dicts -> sets, as sets are the most niche of the containers, but they should definitely be taught

stone juniper
#

if the purpose of tuples isn't apparent to beginners, why teach them first?

noble aurora
#

from a beginner perspective, tuples are completely useless

fleet pulsar
#

I'd argue that the purpose isn't apparent because they're introduced as worse lists

#

Instead of appealing to their immutability and sequence API, tuples should be mentioned as the backing mechanism behind returning multiple values from a function or a point-like structure

#

Whether or not they should be taught before lists is something I'm unsure of, I think they should be taught alongside one another, but as completely separate concepts

#

Though lists do definitely carry a lot more value for a beginner

#

I think if tuples are taught properly, their value will be a lot easier to understand for people new to programming and will become apparent (albeit maybe not very useful) nearly immediately

#

And using unpacking assignments extensively would help that, imo

white bough
oak breach
#

i think its different - tuples are more than just immutable lists
frozensets on the other hand are just immutable sets

stone juniper
#

frozen sets don't fulfill the same important place that tuples do, they're more like an edgecase if you need something that has O(1) membership lookups in one place and to be hashable in another place

white bough
#

Also meta-question (feel free to remove it after answering, or before if this question is not allowed)

Can we post something to previous discussion points if we missed it, as long as we link to the point by replying to it?

stone juniper
#

you can talk about anything pedagogy-related that you wnt to

#

the topics are just meant to stimulate conversation

white bough
#

Ok thank you, wasn‘t sure and didn‘t want to disrupt the conversation by doing it.

(If wanted I can delete this and the other message to keep the channel on topic, just dm me a „please delete“ or so)

stone juniper
#

no worries

pure fog
#

imo tuples should be the first collection type you learn, as a way to represent ad-hoc "records"

#

start with numbers, booleans, None

#

move to strings, but postpone discussion of strings as a special case of sequences. just start with the basic mechanics

#

then tuples: here's how you group data together

#

maybe you introduce lists really early on just so people can make lists of things

#

and along the way you introduce functions, method call syntax, []-getter syntax, etc. then you circle back and explain variables-as-labels, and finally lists-as-collections-of-unnamed-variables.

#

don't emphasize that "tuples are worse lists" until the student says "wait, can't i use a tuple for that? what do i need a list for?"

stone juniper
#

i think you should do names before functions, otherwise their first instinct is to assign names inside functions

#

and you can explain switching around labels without function scopes

pure fog
#

maybe you use functions as a segue into talking about variables?

#

because without mutable collections it's otherwise hard to demonstrate how names work

#
  1. basic data types: numbers, bools, None
  2. strings (and bytes, for completeness?)
  3. tuples as "records"
  4. functions and methods
  5. variables and name binding; lexical scoping
  6. lists
  7. other mutable collections
  8. classes
stone juniper
#

why lists so late?

pure fog
#

well that's what i had proposed above

stone juniper
#

and where do various control flow elements fit in?

pure fog
#

idk 😆 somewhere along the way

#

part of the problem w/ teaching i think is that the best progression differs depending on how the student is learning

#

if you're in a classroom type of setting with a well-defined progression you can build concepts a lot more gradually

#

(which is why i think there is so much value in a well-designed course)

stone juniper
#

@fervent steppe please respect the channel's topic

buoyant tinsel
#

From a mathematical pov it would be best to start witha sets theoretically first

fervent steppe
stone juniper
#

and yet, not on topic

oblique stump
pure fog
stone juniper
#

well I learned programming after set theory

pure fog
stone juniper
#

so that also depends on the student

buoyant tinsel
pure fog
buoyant tinsel
#

Sure, why not? Banana, apple, orange..

pure fog
#

are you going to teach set theory before trig?

stone juniper
#

while i'd like set theory to be introduced earlier in math courses, i'm not sure that translates to programming
the two don't really use sets in the same way

buoyant tinsel
#

Categories are just as easy to explain as counting

pure fog
#

but largely useless for applications without a lot of abstract theory, except as a notational convenience

buoyant tinsel
#

Depends on the examples and problems you're hinging everything on

oblique stump
#

I don't get along with set theory at all and if that was a blocker to some of my calculus courses or lin alg courses, I would probably not be an engineer in a computation-heavy field like I am today.

pure fog
#

thoughts on a progression like this?

  • basic data types: numbers, bools, None
  • if/else/elif
  • strings (and bytes, for completeness?)
  • while and for
  • function usage and method call syntax
  • tuples as "records", maybe also named tuples
  • try/except and raise
  • lists as "sequences" (very light introduction)
  • dicts as "mappings" (very light introduction)
  • function definitions with def
  • variables and name binding; lexical scoping
  • lists in detail as sequences-of-anonymous-bindings
  • dicts in detail as lookup tables + as an extension of lists
  • classes in moderate detail (don't be afraid to explain how self works, it is de-mystifying in my experience)
  • higher-order functions and lambda
  • revisiting tuples: where do they fit in?
oak breach
#

i like this

stone juniper
#

what will you iterate over if you try to teach loops before lists?

white bough
#

If you take a lay-person and tried to teach him the structures, it would be easy for them to understand a list (shopping list, inventory list) and wuite natural that you can add or take from that list.

Same thing with a set when you compare it to a set of cards or better a whatever collectors set (collectors do not care about duplicates)

Explainijg a tuple would then be easy to generalize as a list that cant be changed after you created it.

Tuples may are more inportant and come before in a programming mindset, but people new to it would have a harder time understanding it than as special form of a list (which would be easy to then gradually lead to the real definitin)

stone juniper
oblique stump
#

It's interesting you introduce try/except before function definitions. I don't mind it tbh.

buoyant tinsel
pure fog
pure fog
stone juniper
#

iterating over strings is a bit of an edgecase, since what you get are strings

silent goblet
pure fog
#

true. you could do lists earlier, but the whole list was inspired by that conversation above, avoiding the tuples-are-worse-lists attitude

buoyant tinsel
#

Strings.. why so complicated!?

white bough
neon pasture
#

i do think it makes sense to go with lists early, just because it makes it obvious why we need this whole language for what's essentially a fancy calculator

pure fog
pure fog
#

and yes you can thread that list together a bit. you can teach 1 control flow mechanism and 1 data type at the same time

neon pasture
#

also lets you explain for loops pythonically

stone juniper
white bough
neon pasture
#

rather than having to do the degenerate py for _ in range(10): print(range)

pure fog
neon pasture
#

but overall, I don't think tuples as immutable-lists is a useful thing to teach

oblique stump
buoyant tinsel
#

When I taught python to mythe mom, it was nice to use those weird tv show quizzes as starting point

neon pasture
#

try: except: can be nice for the basic "if user inputted not a number, ask again"

buoyant tinsel
#

'how many 1s do you write when you write all numbers from 1 to 1000?'

#

Etc

#

Just let the pc count!

stone juniper
#

try/except can feel unmotivated before functions
i remember my first reaction was "why wouldn't I just write a program that doesn't create errors?"

neon pasture
#

I think the traditional int(input()) example may help with that

oblique stump
stone juniper
#

lol fair enough

white bough
pure fog
buoyant tinsel
#

What about else?

#

Would you mention it or just people find out on their own?

white bough
#

This may not be good for python but explaining controll flow can be easy with a flow diagram, where try/except would be hard to fit.

Bur again probably not good for python as then explaining that learned behavior away again in favour of the best practice(try/except) can be harder

buoyant tinsel
#

Flow diagrams are very useful

white bough
buoyant tinsel
#

try/except/else

#

for/else

white bough
# buoyant tinsel try/except/else

Ahh sorry though you were replying to me.

The „special“ cases of „else“ I would not explain at that point especially as I even see or use them really not often.

Only saw code with that a handfull times and it was always for try/except/else I never saw a real world example of for/else.

buoyant tinsel
#

At least we software people have that standard.. chemistry and other recipe-fields like baking would benefit from a standard like that

#

So I think many people would benefit in general from knowing about diagrams and flow charts

#

Maybe those also could bridge the gap between what they're interested in and python code

#

Not jump right into the code but draw it out on a whiteboard

white bough
#

Coming from chemistry and medicine actually, it scared me when I started learning that there seems to be little visual aids used and if they are sometime more complex than the code itself (still have problems with UML and havent even found a good resource learning it)

fleet pulsar
pure fog
buoyant tinsel
pure fog
#

ohhh. else would go with try/except. loop/else is arcane trivia and would be taught later, if at all

fleet pulsar
# fleet pulsar ez, just save the fact that any iterable can be unpacked for later ;)

On a serious note, that's the exact reason why I'm vouching for teaching them as separate concepts, without explaining that both share a good portion of API - show that they have vastly different intended purposes and applications instead of simply saying it, and only then reveal that they're actually similar under the hood. I think that way, the question "why not just use lists?" will be more rare than it is now

buoyant tinsel
stone juniper
#

cooking recipes drive me crazy with how useless they are

white bough
pure fog
#

another argument for teaching tuples early @fleet pulsar . x, y = a, b is just tuple unpacking

white bough
buoyant tinsel
neon pasture
#

there is a standard diagram language, it's just way too complicated for just about any practical usecase

pure fog
#

i use subsets of UML for ad-hoc diagrams

#

i don't know the formal semantics though

stone juniper
#

cant say i've ever found UML useful
i think someone's ad hoc attempt is usually better

silent goblet
neon pasture
#

it's a common pattern in CS "this thing is way too informal and vague" -> "lets specify it properly so that everyone knows what it means" -> "oops the spec is now 700+ pages" -> "everyone just whatever"

silent goblet
white bough
fleet pulsar
neon pasture
#

it is quite hard to explain why tuples over just... small lists. It's really just convention most of the time

fleet pulsar
#

I think by first showing a problem and then solving it with tuples it'll be easier to explain and reinforce their idea

#

The fact that they have structure is important

buoyant tinsel
#

Tuple unpacking as path into the tuple/list debate.. could work

#

But requires functions first, so when to introduce those?

misty dirge
#

is tuple unpacking really a thing? any time the star operator is used for packing, the type of the resultant sequence is a tuple. but any iterable can be unpacked.

fleet pulsar
#

That's a good question honestly, I remember a long while ago someone proposed teaching functions before loops, and I think that makes sense if done right

buoyant tinsel
#

Also, annotations?

neon pasture
#

annotations are a skip until way later

fleet pulsar
neon pasture
#

in the end, you need to teach functions variables number strings for while list tuple dict builtin-functions in some order to get a good foundation

fleet pulsar
#

So iterable (tuple, precisely) unpacking via (x, y) = point

misty dirge
worldly dewBOT
#

@misty dirge :white_check_mark: Your eval job has completed with return code 0.

1 2 3
fleet pulsar
#

I'm aware that any iterable works, yeah

stone juniper
#

easy to break for mutable collections though

buoyant tinsel
#

That's why functions

#

Motivation to get into tuples

silent goblet
#

still, "why not just have a list"

neon pasture
#

multiple returns is IMO a pretty good justification. And just say "yes, you could just return a short list, but it is convention to return a tuple instead"

#

because well, that's the only reason

buoyant tinsel
#

Maybe some mutability hiccup for additional pepper?

white bough
#

Tuples in that context help you to not mess up and accidentally append something.

Could be an explanation

pure fog
#

how about this? grouping together all the control flow, moving def earlier, then you can motivate tuples right after that

  • basic data types: numbers, bools, None
  • function usage and method call syntax
  • strings (and bytes, for completeness?)
  • if/else/elif
  • while and for
  • try/except and raise
  • function definitions with def
  • tuples as "records", maybe also named tuples
  • lists as "sequences" (very light introduction)
  • dicts as "mappings" (very light introduction)
  • variables and name binding; lexical scoping
  • lists in detail as sequences-of-anonymous-bindings
  • dicts in detail as lookup tables + as an extension of lists
  • classes in moderate detail (don't be afraid to explain how self works, it is de-mystifying in my experience)
  • higher-order functions and lambda
  • revisiting tuples: where do they fit in?
misty dirge
#

Tuples to stop you from doing something you didn't intend to do? what is this, Java?

neon pasture
#

I would move for after lists

white bough
neon pasture
#

and just have learners do while loops for doing things multiple times

pure fog
#

fair enough

misty dirge
#

@pure fog do you use the staff Notion page? I wrote something like this for a project that we didn't end up pursuing

pure fog
#

what about having variables so "late" after def? i kind of wanted to at least touch on lexical scoping before getting to lists

buoyant tinsel
#

Dicts aren't extensions of lists

pure fog
misty dirge
#

(that is, itemizing a potential learning path for all the language features)

pure fog
buoyant tinsel
#

I would introduce dicts via globals and vars

neon pasture
#

a list is just a dict where keys are sequential integers

pure fog
stone juniper
neon pasture
#

it's really a question of "what to do with variables"

misty dirge
#

I know you know that, of course

buoyant tinsel
#

No seriously, you have global vars, ask 'how to get all the things you assigned?.

neon pasture
#

do you go with full blown labeling objects semantics from lesson 2? Do you go for a half-assed explanation at lesson 2, then revisit it later?...

pure fog
buoyant tinsel
#

Easy as py

oak breach
#

js too, i think?

misty dirge
neon pasture
silent goblet
neon pasture
#

oh wait, I misread your msg

silent goblet
#

you can add arbitrary keys to an array

misty dirge
#

keys to an array. what?

silent goblet
buoyant tinsel
#

Instead of printing a single variable, print globals and you get dicts, vars, strings, ints, print..

weak mortar
silent goblet
misty dirge
silent goblet
#

ah

white bough
#

Would you ever (for beginners) explain the „tuples as dict-keys“ possibility?

misty dirge
pure fog
#

that's javascript @misty dirge

weak mortar
# silent goblet

Hm I'd say that would be because Arrays are basically Object types.

neon pasture
silent goblet
neon pasture
silent goblet
#

As a beginner, I would be pretty confused about tuples if they were lists... but with some conventions around them? also you can't mutate them? why?

pure fog
#
  • basic data types: numbers, bools, None
  • intro to variables
  • function usage and method call syntax
  • strings
  • if/else/elif
  • while loops
  • try/except/else and raise
  • function definitions with def + light intro to lexical scoping
  • tuples as "records" that group data together, maybe also named tuples
  • variadic args and kwargs in functions
  • lists as "sequences" (very light introduction)
  • dicts as "mappings" (very light introduction)
  • for loops
  • variables and name binding semantics
  • lists in detail as sequences-of-anonymous-bindings
  • dicts in detail as lookup tables + using the same concepts about name bindings as with lists
  • classes in moderate detail (don't be afraid to explain how self works, it is de-mystifying in my experience)
  • higher-order functions and lambda
  • revisiting tuples: where do they fit in?
  • bytes, strings, unicode, ascii, and utf-8
neon pasture
#

does it make sense to teach args and kwargs before lists?

pure fog
#

maybe args, because they appear as tuples inside the function

#

kwargs, probably not. because you get a dict

stone juniper
buoyant tinsel
#

Variadic args.. you're obsessed with those, aren't you 🤣

pure fog
#

im not! i just remembered them, and they come up pretty frequently. but they are probably too early in the sequence.

white bough
#

Dicts are dictionaries like in the real world, if you want to know the explanation to a word, you take the dictionary go to the back, find your word, get an page number -> go to that page and get the value to your word. There cant be too entries with the same word.

This somewhat also explains hash-maps

pure fog
#

could probably move variadics down after classes even

neon pasture
#

I would probably drop them from a beginner course entirely tbh, maybe stick them somewhere at the end just do people know what they mean when they see them

silent goblet
weak mortar
#

Why while loop if far above and for far below? I mean while could be at the bottom too no? Introducing loops, and yade yadi yada.

neon pasture
#

because for really only makes sense with lists

weak mortar
#

Yeah that is why we can put while below.

neon pasture
#

most simple programs do need a looping construct of sorts

buoyant tinsel
weak mortar
#

Loops together seem better (imo)

neon pasture
#

not having a looping construct really limits how much programming you can actually teach

silent goblet
#

||haskell be like||

weak mortar
stone juniper
#

unless you want to get into recursion immediately

neon pasture
silent goblet
#

🤔

buoyant tinsel
#

Of ffs, stupid auto completion on my phobephone

silent goblet
#

you could skip loops and teach recursive functions then!

neon pasture
pure fog
white bough
silent goblet
weak mortar
neon pasture
#

strings I think are important just because they are a bit more "concrete" than just "fancy calculators"

pure fog
#

not just strings, but i mean string encodings etc

stone juniper
#

you need strings if you want to take user input at all anyway

neon pasture
#

yeah, that's probably not needed

#

encoding hell is hard to do correctly

buoyant tinsel
neon pasture
pure fog
#

i am in favor of teaching strings-as-opaque-blobs-of-text

neon pasture
#

same

white bough
neon pasture
#

there are 3 basic control flow structures -> sequence (do one thing, then another), selection (do one thing, or another thing), iteration (do one thing multiple times), and you need all 3 to actually write an imperative program, and teaching python on anything but imperative programming seems janky at best

buoyant tinsel
buoyant tinsel
fleet pulsar
pure fog
#

yep, i've been revising it based on the ongoing conversation 🙂

fleet pulsar
#

That might be a good thing to pin eventually

pure fog
#

sounds like stelercus was working on something more formalized. i will keep it in my notes at least

misty dirge
#

that's why my name was green for a few months.

buoyant tinsel
#

I don't think such a program should be pure text

#

Best would be something interactive like a jupyter notebook you can also introspect

#

Apropos interactive, do you know code wars? I heard some podcasts where it was mentioned

#

Learning python as a skill in a game

#

And there's another more rpg-like learning game

#

What was the name...

#

Codecombat

real oar
#

Does anyone know if there is a library for github api?

#

such as github cli

stone juniper
real oar
#

alr

fallow terrace
rich mural
#

But dict keys and set elements must be both

silent goblet
#

You can use a mutable object as a key.

#

Such as a class or a function, for example

rich mural
#

I mean, you can, but you shouldn't.

silent goblet
#

Why?

rich mural
#

Because if the mutation changes the hash value, it will create an inconsistent data structure

silent goblet
rich mural
silent goblet
#

Yeah

rich mural
#

But the most common case is that all or almost all state in an object is taken into account when you calculate the hash, and especially a beginner should think of it that way until they know what they're doing.

silent goblet
#

For built-in types and other "value" types, yes

#

But, for example, all custom classes by default are hashable and mutable, unless you redefine equality

rich mural
#

I mean, generally speaking, when you want to use a custom class as a hash key, you tend to want to take all state into account.

#

But yeah, I dunno, I guess that in itself is kind of an advanced topic

#

I guess I'd just advise a beginner to avoid using non-"value" types as keys unless it's absolutely necessary

silent goblet
#

Yeah, I think hashing is a kind of an advanced detail

#

Or rather, kinda hard to explain without implementing a simple hash set

#

Like, the one with buckets

rich mural
#

Yeah. The CS50 intro to CS course actually has you implement a hash table in C, not super early in the course, but it is programming 101, and I think it's a good time to do it.

#

And once you've done that you know exactly what you're dealing with in Python.

silent goblet
#

I would rather not inflict C on python beginners :)

rich mural
#

CS50 covers Scratch -> C -> Python in that order. You basically start with the fundamental concepts of programming logic, then you look at how bare metal memory and low-level concepts work, then you go up an abstraction level and finish up with Python, with a decent understanding of how it works one level down. I think it's a really good way to go about it, tbh.

silent goblet
#

In my first year at university, we learned python and C in parallel

rich mural
#

My intro to programming at uni was in C as well. I don't think it's a terrible idea to lay the foundations related to memory early on, but you have to consider the motivation of the student as well.

#

Python is nice because you can get cool stuff up and running quickly and easily.

silent goblet
rich mural
#

Yeah, that's fair, you're much more reliant on your personal motivation than with a more structured course.

green warren
#

I first learned programming (self taught) with BASIC. It's far too old-fashioned and I wouldn't recommend that (unless Visual Basic is your goal for some reason). After I knew some of the basic ideas of programming, I self-learned some beginner C. I think it's extremely useful to be introduced to pointers, references, etc. early. But in my own case, it wasn't the very first thing I learned, and I'm not sure if it should be. Something like Python might be good for initial steps.

buoyant tinsel
#

Difference is, python can also be useful for everyday tasks that doesn't require a project plan

#

People who don't aspire to be programmers and aren't really interested in the details still can benefit

keen moat
#

I started learning to program in HS, didn't learn any C or anything about pointers until 2nd year in uni. Can't say it's something that hindered me as a programmer, since I just didn't need it, although understanding pointers is definitely useful sometimes.

rich mural
#

I don't think it necessarily needs to be pointers, but understanding the duality of objects and references is something you benefit greatly from early on in pretty much any language. Python doesn't have pointers and direct memory access, but it does have the name/object duality which is kind of analogous.

#

The model varies somewhat from language to language, but I think basically all languages have some way of representing indirect referencing of values.

#

Imperative languages anyway.

green warren
#

I've used the Python model to fake pointers and create things like tree structures. It helps to understand what's really happening.

rich mural
#

Yeah, Python still supports indirection even though pointers aren't a first-class language construct

green warren
#

Absolutely. Indirection is the key concept and applies in whatever language you use.

pure fog
#

my first programming languages were Excel, Stata, and R! moving to Python felt like absolute freedom, the programming language just got the hell out of my way and let me write the code that i wanted to write

rich mural
#

I started with C, but the language that really made things click for me was QBasic

noble aurora
#

I had Java first in school, and my teacher told me to make attributes private so my coworkers couldn't change them 🥴

rich mural
#

Encapsulate your code from everyone else in order to maximize job security.

agile hedge
#

yo guys, anyone got a resource I can refer to learn how to structure and best practices for building asyncio api wrapper libs?

misty dirge
silent goblet
pure fog
misty dirge
#

What is that

green warren
silent goblet
#

my first programming environment was GameMaker 8

green warren
#

Actually I think my earliest QBasic programs were games. Had some maze exploration game.

misty dirge
#

Let's take one from the pinned message. Topic: How much does learning some amount of assembly matter as a developer?

#

I had to write an assembly program that performed division and put the result and the remainder in two registers. That was interesting, I guess

#

though I think those who argue that writing non-trivial programs in assembly gives you some special insight that contributes to your programming skill in other ways are just... wrong.

stone juniper
#

yeah I think it's the same as any other language; it's important only if you need to write something in it
and you rarely need assembly

misty dirge
#

I don't know that it's the same as any other language per se, since assembly closely represents what code in other languages becomes when the abstraction is actualized.

stone juniper
#

sure, but does that matter? if you know what a python function does, you can use it whether or not you know how it bottoms out in machine instructions

misty dirge
#

I don't think it matters, no.

stone juniper
#

learning assembly definitely forces you to think in a new way, but im not sure that way matters for much beyond writing assembly

green warren
#

I think it's another one of those things that's useful to try at least once, on something simple, just to get an idea of what's happening behind the scenes.

misty dirge
#

On a similar note, I enjoyed the unit on lisp in my undergrad because it forced me to realize what assumptions I was making about what a programming language is.

green warren
#

Oh yeah, I had a similar experience with Scheme

misty dirge
#

is Scheme inspired by lisp in some way?

green warren
#

It's a dialect. Strict Scheme is supposed to have no side effects, and be purely functional.

fallow terrace
waxen fox
# misty dirge Let's take one from the pinned message. **Topic: How much does learning some amo...

I have never been a developer and I'm only a hobbyist, so I'm not sure if my opinion matters as much as others. Though, just in general, I don't think it really matters for being a developer. People will say "you're only a true programmer if you know [low level language goes here]!", but there isn't really a concept of a true programmer. I think (personally) Assembly gives you insight and it would probably be fun to learn on the side to enter something new, but it doesn't matter in terms of being a developer.

waxen fox
misty dirge
white bough
#

I think we are about 4 xkcd comics deep now

misty dirge
#

we also had someone in #internals-and-peps a few months ago (might have been over a year, honestly) who said that if you don't select the right sorting algorithm for every case, you're just a "code monkey".

waxen fox
white bough
#

But seriously what would be even a single advantage ( advantage for using in python) that you could get from assembly? Anything tangible? I would be happy if there is even one.

waxen fox
# white bough But seriously what would be even a single advantage ( advantage for using in pyt...

Knowledge, I suppose

I personally wouldn't really view learning a language strictly from the viewpoint of learning it for a career. There are a lot of Python hobbyists out there who don't want to become data scientists and what not. I'm not really sure about the benefits of Assembly in the workplace because I've never been in that environment but speaking personally, it's a lot of fun to learn about the lower levels and the "behind-the-scenes" that makes the "black magic" work 😄

wintry pilot
#

It really helps to understand how some stuff works at a low level, but you don't necessarily need assembly to do that

waxen fox
#

And as for the original question, you can get away without lower level knowledge being a developer iirc

white bough
#

I understand, but which knowledge especially would help lead to you understanding stuff in python better and maybe even write better code?

A really stupid and on purpose unrealistic counter point, if knowledge alone is the bonus, why stop with low level languages? why not Electrical Engineering? medicine?

This came out weirder than intended, I tried rewriting it, but can't seem to find the right words, hope you trust me that this isn't meant as confrontational as it sounds, just that I struggle at this time to form the sentence (in a second language)

||should probably go to sleep anyway||

waxen fox
#

It's just not at the top of my head rn

misty dirge
waxen fox
#

Another topic while we're here: what is your go-to prompt for teaching OOP? (i.e. make a Person class)

potent cobalt
#

The goto prompt when I did my undergrad was a Car class, which I liked. Simple to explain to someone, and easy to expand on having other classes inside your class, such as Engine. A class inside a class always perplexed a lot of students and I felt like the Car example worked pretty well when I was tutoring
Make, Model, Year, Price, Engine
Start(), Drive()

waxen fox
#

Oh, that sounds like a good example, and it also helps people understand inheritance.

potent cobalt
#

Yea, easy to branch of into that later on using the same example

waxen fox
#

The first OOP "prompt" I got that I found to work well was a prompt to create a vending machine class with different methods (some of them were class methods, etc.) and that helped well and I got to implement some dunders too

waxen fox
#

Ah, I know Animal is also the go-to example for "type theories" per se afaik

#

like contravariance, covariance and what not

noble aurora
#

yep, Cat, Dog, and feed (🥺)

waxen fox
misty dirge
waxen fox
#

I see

weak mortar
#

how can i make this? guys what the fook i wanna make it when the Bot has Admin rights then it should execute else it should not

waxen fox
weak mortar
#

WTF

#

If you dont know the answer then dont talk please, this is Important.

oak breach
oak breach
waxen fox
#

also I've forgotten the meaning of polymorphism somehow 😅 is it just subclasses having the same methods as parent classes?

worldly dewBOT
#

:incoming_envelope: :ok_hand: applied warning to @weak mortar.

waxen fox
#

sorry, parent classes having the same methods as subclasses

noble aurora
#

polymorphism is just being able to deal with multiple types

#

subclasses inherit all the methods of the parent class, so if all you need in a function is the methods a parent class has, you can also use the child class, because it inherits all the methods

#

at least, you should be able to, 🥴

waxen fox
noble aurora
waxen fox
#

o

#

that makes sense lol, i always thought it'd be more complicated

misty dirge
young kraken
#

Basically, polymorphism is about overwriting parents method by children, right?

stone juniper
#

it's about how a single object can belong to multiple classes

fleet pulsar
#

there are different types of polymorphism, but in the context of OOP it's usually closely tied to virtual methods, yeah

silent goblet
silent goblet
worldly dewBOT
#

@silent goblet :white_check_mark: Your eval job has completed with return code 0.

001 | 8
002 | 10
buoyant tinsel
#

Tbh, I very much dislike the classic Cat, Dog, Person attempt for explaining OOP

silent goblet
#

I personally hate artificial examples like that as well

#

it's really hard to find a useful example of implementation inheritance because it's rarely actually the right tool

#

the best example I could find without overcomplicating stuff (like introducing abstract classes) is making your own exception

buoyant tinsel
#

Whenever I go down that road it feels wrong and more suitable for prototypes or composition

#

I think most important and relevant are protocols in python, dunders

#

And that's also where you might want to overwrite methods

#

Subclassing buildins, showing what's possible and giving people a sense of the limitations

rich mural
# waxen fox that makes sense lol, i always thought it'd be more complicated

It's just basically any code that's generic in the sense that it can operate on multiple types. You don't need OOP and inheritance to achieve polymorphism, you can do it with plain Python duck typing. Like:

class Foo:
  def print():
    print("foo")

class Bar:
  def print():
    print("bar")

def baz(printer):
  printer.print()

baz(Foo())
baz(Bar())

Polymorphism = "multiple forms"

rich mural
# white bough But seriously what would be even a single advantage ( advantage for using in pyt...

I think an advantage of familiarity with assembly is that when you are trying to squeeze every little drop of performance out of some code, it can be useful to be able to analyze what kind of assembly a given piece of code will eventually compile to. Granted, Python is not known as a language you would use when you need maximum performance, but it's actually pretty common to write code that calls into C (and other compiled language) modules, or even to write such modules yourself, and when you do, it's normally precisely because you need something to be super duper fast and/or memory-efficient. So in those cases I think assembly knowledge can be quite relevant.

rich mural
#

So you have to reach to come up with an example.

silent goblet
#

I already mentioned exceptions

silent goblet
# silent goblet I already mentioned exceptions

I think it's a reasonably balanced example. It is something very common in libraries/applications, and it's simple enough. There's also a nice tree of built-in exceptions somewhere in the official docs

rich mural
# silent goblet I already mentioned exceptions

Yeah, I'm not saying it's a bad idea, I just think that the reason why inheritance examples tend to be so artificial is that it's not easy to come up with a good realistic example because implementation inheritance has such limited utility.

#

But exceptions may be the... exception.

silent goblet
#

Often with catastrophic examples such as Prism extends Triangle

rich mural
silent goblet
#

So the course authors are just bad programmers?

rich mural
#

It sounds like a good idea when you first learn about OOP, and maybe a lot of uni professors have not actually had to deal with it a lot in production scenarios.

#

I mean, yeah, a lot of the time.

green warren
#

Also deep inheritance hierarchies were all the rage in the 90s when OOP was really taking off. I think it took some time to learn that classifying everything into hierarchies does not result in maintainable code.

rich mural
#

And inheritance is one of those things that work, just not very well or as good as alternatives, and create these insidious long-term issues rather than just straight up breaking upfront.

rich mural
#

It's like, everything's fine and dandy until one day you realize you need to change something in a deep base class and all of a sudden you're like "Oh NO"

green warren
#

Also, the real world is not cleanly modelled by hierarchies, so designing software around the idea is bound to lead you into compromises that end up not really making sense.

rich mural
#

Well, not too often anyway

green warren
#

Hell, even trying to organize a bunch of files into folders leads to problems. You always end up thinking that something should really be in multiple places.

silent goblet
#

Yeah, and then you create a dumpster package like utils or helpers 😬

green warren
#

And yeah, geometric examples of inheritance are notoriously bad. Like no, a Circle is not an Ellipse, and not the other way around either.

#

Ah, utils, the place where everything goes 😄

silent goblet
green warren
#

What's the radius of an Ellipse, then?

silent goblet
green warren
#

A Square is also a Rhombus, and most Rhombuses are not Rectangles (unless they happen to be Squares).

#

But both Rhombuses and Rectangles are Parallelograms. Sounds complicated.

silent goblet
green warren
#

So Ellipse just breaks the Circle interface? What was the point of inheritance, then?

silent goblet
#

IHNFC

#

code reuse! maybe

green warren
#

Inheritance needs to support Liskov substitution or else it is fake and likely to lead to errors.

#

And there's almost no code reuse between Circle and Ellipse. All the formulas are different.

silent goblet
green warren
#

I can imagine there being a PlaneFigure abstract base class, and then all these other shapes underneath it. But the individual shapes probably don't have any inheritance relationships between them.

#

Ellipses don't have to be oriented along the axes, of course.

#

And it also wouldn't make sense to ask a Circle where its major and minor axes are.

#

Maybe you could have a ConicSection class, of which Ellipse is a subclass. But then Circle is not a class, it's just an instance of Ellipse whose foci happen to be the same. 😛

rich mural
#

That's why interfaces tend to be much more useful than inheritance. You can slap as many of those as you want on whatever you want and you won't have to worry about growing the inheritance graph.

green warren
#

yep

silent goblet
#

I think

#

Or maybe just in a very unexpected way.

#

After all, the library does work and some people like it

green warren
#

I like the example of using Vehicle -> Car, Truck, Bus, etc. Because you can see a lot of OOP principles here. They are composed of various parts, some of which may be interchangeable. They do things, like drive on roads. And they take care of the complicated details of doing those things internally.

#

I think OOP is kinda hard to make sense of with things like geometrical figures, both for the reasons we've been discussing, and also because an Ellipse doesn't really do anything, it just sits there. The contrived example is to make it calculate its area or perimeter. But those are just pieces of data. A class is not just a collection of pieces of data.

ripe folio
noble aurora
#

what constraints?

green warren
#

If a Circle is an Ellipse just because you can get a Circle by choosing a degenerate set of values (i.e., setting the major and minor semiaxes the same length, or putting the foci at the same point), then why not extend this idea to other cases of degeneracy? I could assert that a PairOfIntersectingLines is a Hyperbola. In fact I could assert that literally any geometrical figure is a degenerate case of another geometrical figure, if I am creative enough with defining the parameters and equations.

#

We don't even have to think about conic sections. Maybe a Triangle is a Quadrilateral where two of the corners are coincident. This rabbit hole can go as deep as you like.

fallow terrace
#

eVeRyThInG Is A lInE

#

But yeah, I don't think the geometric shapes are the best idea

rich mural
#

My life is a line

fallow terrace
#

As overused as the vehicles and animals are, they logically work

wary ridge
#

Hello

rich mural
#

Yeah, I mean, I very much doubt you'd usually actually use an inheritance hierarchy like that in an actual project. I've only ever seen them used as examples in OOP classes and tutorials

oak breach
#

oop can work well in games

green warren
#

I've read that deep inheritance is counterproductive in games, too

oak breach
#

yeah complicated inheritance trees just make it harder to change stuff later on

rich mural
#

Which is more of a compositional than inheritance-based pattern

green warren
#

But it's got very clear discussions about exactly why a certain pattern is bad, and what the most useful replacements are.

#

And I think it applies beyond gaming for sure.

oak breach
#

oh yeah i think this is a great resource
craftinginterpreters is by the same author

white bough
#

Please no more cats and cars for OOP, it is so abstract and explains only the most basic idea, and that even just barely.

If you use cars/cats/your-hamster follow it up by some easy real world examples!

Learning python I got frustrated by only finding ultra abstract examples and if I ever see a tutorial with „animal.speak()“. I will literaly go crazy.

The same thing for the previous mentioned design patterns. If you do an abstract example, do at leadt one real world afterwards. Look around also that you do not give an example everyone else already gave.

Looking for examples and only finding ones that are for web design is frustrating if you do not have any interest in web and everyone used that example, because I guess it was easy to copy paste?

Best to include multiple real world examples for different subparts of programming

rich mural
white bough
#

Sorry web backend, was a typo (meant django, flask,…)

white bough
sage jasper
#

do you have a link to that?

white bough
#

Sadly I cant find it currently.

Will look again when I am on desktop, will also post an example of what I think would be a good example of OOP.

||please dont force me to format code on the phone 😄 ||

sage jasper
#

i agree in that there's only so much to see and learn when the examples are all based on OneClass

white bough
#

And all use a method that ends in „print“

Which also shows a real bad practice as an easy example.

stone juniper
#

my first introduction to classes was also RPG characters

sage jasper
#

but tfw i know nothing about d&d or games in general lol

#

ty though

white bough
#

Thats the problem with that example, but it shows a general way to do examples that bridge the way between what people know and stuff in python.

Dont see my post as, „to this“,more as „do it like this but for your audience“

rich mural
#

Certainly if the reader has played an RPG before

white bough
#

Thats why I think people making tutorials should not be afraid to make them tailored to a special audience. Currently we have thousand tutorial that are written to be ultra general, but having a lot of tutorial with each for a special audience, gives the learner the chance to find the one fitting them.

rich mural
#

Harder to figure out where to point out resources for us teachers, though.

#

But yeah, OOP is a dilemma when it comes to teaching programming and this kind of article will be useful for some people at least.

green warren
#

I think the main dilemma is really the whole issue we were discussing with inheritance, and how it's not that great of a model of the world. Inheritance is still useful in OOP, but mostly in more abstract ways that are hard to explain in a beginner example.

rich mural
#

It's not just inheritance though, it's hard to find good resources to explain OOP in general

green warren
#

I kind of think "abstraction/encapsulation" is a more useful concept to focus on. This D&D article does this pretty well, it shows you that there is a bunch of data and operations on that data that ought to be associated with a particular concept. The point of abstractions is to make it easier to reason about the code (as well as helping you keep from repeating yourself).

silent goblet
#

What about something from a standard or a commonly used library?

#

Like pathlib

oak copper
stone juniper
#

ok so let's put 5e after for-loops but before classes

buoyant tinsel
white bough
# silent goblet Like pathlib

please not pathlib it does a few things that I really would not like to see repeated. The same things make it also more higher concept

Edit: Like calling Path() but not getting a Path-object back

buoyant tinsel
#

If you can get a newbie to try and work with a GUI framework, there's a LOT of inheritance everywhere

#

Buttons, Events, Windows..

#

But it can be extremely daunting and frustrating to make first contact with one like pyqt

silent goblet
#

Like smalltalk integers

#

I do dislike / a bit tho

#

But I think I got used to it

white bough
#

You get a WindowsPath object for example on windows, yes it is a subclass, but still weird to get a subclass when calling the constructor of the parent class

white bough
silent goblet
#

subclassing == bad :)

misty dirge
#

I think the fact that we're struggling to think of effective ways to teach inheritance goes to show that its ideal uses cases are few and far between, though I think there are times where it's really effective for reducing boilerplate

#

||unless you use it in Java, where it just adds boilerplate, since propagated boilerplate is 90% of all Java code bases.||

#

within the staff, we've been thinking of ways to rearchitect our infraction system, and it's very likely that a replacement system would use inheritance, with a base class for infractions and subclasses for each one.

buoyant tinsel
misty dirge
#

well, I was never asked to make a GUI during my entire undergrad

buoyant tinsel
#

See

#

But that's also where lambdas actually have a real world application

stone juniper
#

i think tkinter is a decent way to practice intermediate OOP

buoyant tinsel
#

So maybe that could be an idea how to combine and teach those concepts in practice

misty dirge
#

I use lambdas often enough in data science shrug2

#

I suppose GUIs are a fine way of teaching OOP, though if the best example we can think of is one that isn't applicable to a lot of developers, is it worth teaching?

stone juniper
#

even if OOP inheritance usually isn't a good overall pattern, you still need to understand it to understand code you come across

buoyant tinsel
#

Yeah, at least having seen it once and know how it works in principle is valuable

#

Same with lambdas.

#

Don't have to like either

#

There's another concept all over GUIs that I only learned in theory in CS, FSMs

#

I think if I had to build a GUI in uni it might have helped understanding how all fits together

stone juniper
#

maybe, but GUIs tend to have lots of little stumbling blocks everywhere

#

and most of your time would likely be spent on visual tweaks

#

you'd also have to throw in event loops

#

so maybe a good final project

cosmic aspen
#

Very true :D ...

buoyant tinsel
#

event loops.. then we're at async.. oh man 🥴

cosmic aspen
#

So much of GUi thou is tied to libraries ... and they tend to be OS specific at times...what to teach when the libraries are in flux

buoyant tinsel
#

Hm.. maybe it's possible to teach those things with the basic ability to debug, look at things step by step

#

Teach how to look for source code on github, run a debugger, check documentation and let them figure them out concepts like OOP that way

cosmic aspen
#

You can build fron the ground up a gui library like in the DOS era . Build a windowing system from scratch or a gui with active areas but this isnt practical ...it was thou back then in the 90s

cosmic aspen
# buoyant tinsel Yeah.. maybe a good way

I have built several simple DOS era GUI that way with active areas and a event loop but not much in terms of OOP lol in several 90s era languages like BASIC,Pascal and C...a graphics editor and a graphics shell

buoyant tinsel
#

I never built a GUI framework, just used a couple of frameworks.. tkinter, qt, panda3d (a bit more than just a gui)

#

They all use OOP quite excessively

#

matplotlib also comes to mind

#

Although I prefer the imperative API..

#

Alternatively, there's networking like twisted - OOP, lambdas, event loop.. and a huge brick wall to bash your head in

cosmic aspen
silent goblet
buoyant tinsel
cosmic aspen
#

It was a bit more fun doing gui back then more freedom but more work and the big pixel and color palette limitations makes you do less tweaking

#

Easier to be pixel perfecf with less pixels

buoyant tinsel
#

And the memory limitations require you to get creative, I guess?

cosmic aspen
#

Yes

#

Inline asm

green warren
#

I built a GUI in Perl once. I think I hate both GUIs and Perl.

cosmic aspen
#

And memory peek and poke even in basic

cosmic aspen
buoyant tinsel
#

Same here

green warren
#

This was back before Python really caught on

#

Like 2002 I think

buoyant tinsel
#

I was a pure gamer back then lemon_fingerguns

green warren
#

I was a co-op at IBM. Mostly writing Perl. I think I've totally forgotten Perl by now, and good riddance.

silent goblet
#

I've always heard that Perl is horrible. I'm really curious what's so bad about it despite it being popular. Maybe I should learn it one day

green warren
#

Perl loves to use a bunch of obscure punctuation symbols instead of words.

buoyant tinsel
#

I wished code combat and code wars were a thing back then, I might've seen the light earlier

green warren
#

I think basically everything Perl does has been subsumed by PHP, Python, Javascript and Ruby. I guess there must be some holdouts still using it, but I wouldn't know who.

neon pasture
#

companies who have millions of cgi scripts probably, there really isn't much to do with perl these days. Though some things are written in it, such as squitch

#

I am glad my uni removed it from the curiculum though. That would be miserable.

cosmic aspen
winter spear
#

Perl is best known for its regex which is now the default for a lot of things

#

Like vim and grep are use perl flavor

silent goblet
cosmic aspen
#

Our Uni once taught BIoPerl for a bioinformatics course hopefully they moved to BioPython ....Perl is or was big in bioinformatics since it is good in text processing and pattern matching which is much of Bioinfornatics with all the DNA text generated with the various DNA and RNA sequencing projects

pure heron
winter spear
pure heron
winter spear
#

I know it was meant for me

pure heron
#

Indeed 🙂

winter spear
#

I wish there was a regex standard

#

It's super annoying have to remember grep from vim from python. Especially vim bc it's my main editor and love the substitute command

pure heron
#

actually, now that you mention it - vim uses its own regex flavor, which is totally distinct from POSIX BREs, POSIX EREs, and PCREs

winter spear
#

It's apparently super close to pearl. I've never used perl

pure heron
#

no, it's very, very different from Perl. Of the 3, it's most similar to POSIX BREs.

#

In a Perl-compatible regex or a POSIX ERE, (a|b) is grouping and alternation. In a vim regex or a POSIX BRE, you'd need \(a\|b\)

winter spear
#

First Google hit said it was closest

#

¯\_(ツ)_/¯

pure heron
#

it has many of the same features, but very different syntax

winter spear
pure heron
#

Right - the manual says what I said:

Vim's regexes are most similar to Perl's, in terms of what you can do. The difference between them is mostly just notation

#

it has many of the same features (I can think of only 1 or 2 features that Perl has that vim doesn't), but the syntax is very different, like my example with the grouping and alternation illustrated.

#

we're off topic, anyway - but my point is just that, as far as teaching goes, Perl regexes have certainly been influential, but regexes predate perl by decades, and Perl's regex flavor has been adopted by some other tools and languages, but it's far from ubiquitous.