2:25 "But be careful, due to floating point rounding errors, rounding using python may not give you the same answer as rounding like you learned in school" Yea, rounding 2.6... to 3.6... is indeed new to me :D My favourite has gotta be ol' reliable print()
For zip(), don't forget it terminates at the end of the shortest iterable and you can pass the kwarg 'strict' to force it to accept only iterables of equal length (added in 3.10).
print() has actually so many useful kwargs. Every time I see something like outfile.write("\t".join(map(str, data)) + " ") in a code base when you could just do print(*data, sep="\t", file=outfile), I die a little inside. Other kwargs to note are end and flush. There may be more but these are the ones I use often
Another useful feature of slice is `slice(None)` which is equivalent to the colon operator, namely `x[slice(None)] == x[:]`. Typically, it's used when you want to pass an index around, but in some cases need the whole iterable. Also works with numpy arrays and pandas tables.
I have literally seen people reading a python file as text and calling exec on that, so __import__ does not really scare me... they should have watched this video ! thanks for the great content !
dict function is really cool, because you can create a dict in a function-like manner dict(first_name="Bob", age=20) instead of {"first_name": "Bob", "age": 20}. Also set is the only way you can create an empty set
Another cool method of dict is dict.fromkeys(iterable) ... that will create a dict where all the values are None. Why is that useful? It's useful if you want to remove duplicate items but maintain the order. (Building a set will result in an indeterminate order)
Already know them all. My favorite -- in the sense that I keep using it nearly every time -- is of course enumerate(). Now make one for the dunder methods/attributes!
wow that is one of the fatest speaking video you made. I had to pause at multiple times to digest the information. It was still a very good video, I hope you'll cover itertools, functools and other similar libs in an other video:)
I was really trying hard to keep it under 20 minutes and also to go fast because I'd say most of the builtins people already know about so I don't want to waste your time!
14:06 'is' and 'is not' must be doing something in addition to checking the id's, because: >>> [1, 2] is [1, 2] False >>> id([1, 2]) == id([1, 2]) True
This is a fun one! In the second case, the first [1,2] is not stored, so its refcount hits 0 and it is garbage collected before the == happens. When the second [1,2] is created the id of the first one gets reused, leading to the observed behavior. Make sure to never compare ids of objects that are no longer alive for exactly this reason!
Just to nitpick in your nice video: perhaps you should disable the ligatures or use a font without them. In particular think it is confusing that the "==" appears to be continuous. These kinds of font tricks may be useful and look nice for Haskell and its crazy operators, but IMHO it looks weird in python.
just say u don't like font ligatures instead of making up reasons on the spot for why they shouldn't be used on python I and many others use font ligatures in languages like C, Go, Rust, C++, JavaScript, Python, Odin, Zig, etc and it never caused any problems the only "issue" with font ligatures is complete programming beginners or people that have never used them before might (rarely but still) not know what the ligature might convert to.
5:45 since bin, oct and hex gave prefixed notations (0b, 0o, 0x) you could pass int(n, 0) to autodetect the base. Also, lowercase x is not the multiply sign ×.
This follows mathematical logic conventions as well! To deny that all of nothing is true, you would need to show there exists an element that is false. To deny that any of nothing is false, you would need to show there exists an element that is true!
This also follows a typical way you would implement a short-circuiting any/all: ``` def any(itr): for b in itr: if b: return True return False def all(itr): for b in itr: if not b: return False return True ``` Passing in an empty itr yields the quoted behavior.
Since Python 3.8, the 3 argument form of pow can also handle negative exponents if base and mod are coprime to eachother. This makes it easy to compute (powers of) multiplicative inverses.
18:45 love that i discovered this one recently, and I actually have a legit use case for it. since variables in python namespaces are accessed by hash table, dumping a bunch of variables I'll need to use from a specific dictionary (among many in a bigger dictionary) to the namespace and then deleting the dictionary is a neat way to access everything efficiently without keeping / using that large data structure and subscripting anything. sure, I could just define my own hash table instead, but doing this made for an easy refactor job and makes the code more readable in the end
Why not just create another dictionary though? I find it hard to believe that this would make it more readable, not to comment on its effect on LSPs' capability of understanding your code
@@higorhi72 the variables are all addresses and offsets of a x86 application, and all follow a standard naming scheme. they're used very frequently and doing it like this made it easy to refactor (I was already calling the variables like this, just not dumping them automatically in the namespace) without having to do lots of manual testing to make sure I didn't typo/miss anything (automated testing is pretty much impossible for this kind of project)
Great question because dict order used to not be guaranteed! Dictionary order has been guaranteed to be insertion order since 3.7, and they have been reversible since 3.8!
You missed `__build_class__`. Similar to `__import__`, it's more an internal implementation detail than something that the end user should ever access. But both of them can be overwritten by modifying the `builtins` module, allowing to actually *change the semantics* of those syntax structures.
How about all dunder/magic methods/attributes? You covered most of the types here, but didn’t bring it up for things like __len__. But there’s a lot more too, like __enter__ and __exit__, or __del__, all the math ones, and __new__.
I didn't know isinstance(False, int) was true! This is a very real possibility for a really subtle bug in code that handles different types differently. Ouch!
I use `dir` all the time…unfortunately, though not in set code. I regularly run into some instance of some undocumented class in a super complicated module, and I want to figure out what exactly they called a method I need, or see if there is anything useful, without spending ages trying to figure out all the parent classes. Especially useful when I’m outside my IDE for whatever reason
Re j not i. Complex numbers are used a lot in electronics and i already means current. So j was adopted as the next logical choice. If J see someone using i J know they dont have an electronics background.
Also, in quaternions it's normal to use i, j, and k for three different imaginary axis. In physics capital I often means fixed current and lowercase i time-varying.
2:26 Python uses banker's rounding, so even if there are no floating-point errors, you may get unintuitive results. For example, the result of `round(0.5)` is `0.0`, not `1.0`.
For memoryview, the fact that it allows multidimensional indexing is rather secondary. Its primary characteristics is that it doesn't own the underlying memory. In your example, if you were to return the memoryview out of the function, it would reference memory that is no longer associated with anything, leading to undefined behaviors.
@@RandomGeometryDashStuff you’re right, my example with bytearray was incorrect since bytearray is one of the classes that “knows” when a memory view is taken of them (and prevents you from resizing it as long as the memory view hasn’t called release). But in general memory view is non-owning. I’ve been using it for a while in C extensions to expose memory managed by C and there is no “native” way for the C-level code to know that you have a memory view pointing to that same memory. You could have the C code deallocate the memory, the memory view in the Python side would have no way of knowing.
Favourite: enumerate - use it all the time. Least favourite: bin, oct, hex - can't stand trying to use python for non-decimal numbers, it is so unpleasant; don't know if this is common in most languages. slice() is cool as hell, never knew about that one before.
Which languages are you used to? Python's numerals are mostly inherited from C. Forth and bc expose the IO base, and Ada and VHDL support specifying arbitrary base per literal, but I don't think I've ever seen a particularly pleasant form.
@@0LoneTech It gives you strings for things that are numbers. In general, "it just isn't made to handle non-decimal". Maybe there is a library out there already that is really good that I just don't know about. It doesn't come up often enough in my life to be a huge inconvenience.
@@fancypants6062 Thank you for that answer. It gave me some things to consider. What happens internally is that most numbers are represented in binary, or binary floating point. Those are the natively supported types. Decimal is the default base for textual IO, but not a property of the numbers themselves; base conversions do build or parse strings. Hybrid representations like BCD may be easier to convert for other bases, and Python internally does that for long ints, decimal.Decimal or fractions.Fraction. In particular, the base system itself is notation, not a property of numbers. In Haskell, one of the more mathematically inclined programming languages out there, the Num type class doesn't provide display forms; that's in Show and Read. The Integral type class provides the core function for converting to base forms, quotRem, similar to Python's divmod. Python's standard library does have an odd asymmetry in that int(str, base) can parse a variety of bases (up to 36) but format will only output the programmer's most popular ones (bodx). There do indeed exist many libraries for other options, including e.g. Kharosthi or Roman numerals, which do not use the base system.
Hey, I use dir somewhat often if I find myself in a jupyter notebook (no LSP) and need to quickly remember an attribute or module function. I could look up the documentation but dir is right there if I'm focused.
Warning with id() , it's only meant for internal use, you shouldn't think of memory addresses when using python. Also, id() can behave in unexpected ways, for example the object int(3) will give the same id as when making another int(3) , because of python optimizations that are applied on the considered "most used integers".
This is a bit subtle, but id is not just meant for internal use only. The part that is for internal use only is that id(x) gives the memory address of x, which is a CPython implementation detail. That id gives you a unique and stable integer as long as x is alive is very much part of the public API that you should feel free to use.
int(3) doesn't make a new int; it returns 3 from the small integer pool. Sharing all instances of small integers is possible because int is immutable. Similarly, after a,b=(1,2),(1,2), a is b because the compiler identified subexpressions.
The fact that potentially dangerous "id" made it into builtins and not stored in inspect or sys module is rather unfortunate. It's very hard to come up with valid use case for it in real code, not just for quick debug or experiments, and even there comparing with "is" is more reliable. One of the few builtins that are commonly in linter's exceception list to allow shadowing (and ban original for commit).
I prefer using list/set/generator comprehensions over filter and map purely because of readability. The main issue with filter and map is that it's easy to forget the order the arguments go in, whereas this is not an issue with the comprehension syntax
If I may add to this, I'd like to see Conda envs too, though actually more of a Conda equivalent of mCoding's "Automated Testing in Python with pytest, tox, and GitHub Actions". Better yet if it's about using pip/venv and conda together.
8:50 filter and map are uglier in terms of syntax, but can be much better than comprehensions depending on the use case. It should be emphasised that the two are not interchangeable, if a copy is desired, comprehension is better, but if a modification is done for a single iteration only, map and filter are better!
One can use a generator comprehension (x for x in ... if ...) or (f(x) for x in ...)to avoid the copy when using comprehensions as well, so I personally find them better whether a copy is desired or not.
@@mCoding I understand that the comprehension form is to Guido's taste, but for me filter and map involve less new names to typo and name the task more directly, particularly if I already have a named function to apply. But I also often prefer Haskell and find the demotion of reduce() counterproductive.
these languages and standard libraries are garbage. i'm not saying i could do better, but the weird caveats in each language are just mind boggling strange. Also, you never mentioned that this info is for python 3.7 and above
@@0LoneTech my guess is that binary is not garbage. each language built upon that adds human nuances that get exaggerated and confused easily. i like studying the weirdness as well, but i get tired of not having better tools. why do we still code like monkeys at typewriters?
@@nil0bject Then I guess you're in for some wonderful surprises once you do learn about machine language. In particular, look at the bit orders of fields in the RISC-V instruction set; and that's one of the most carefully designed ones out there, in sharp contrast to things like the recycled instructions used for prefixes of astonishingly long extensions in x86. James Sharman's 8-bit pipelined CPU series gives a neat look into one possible way to design instruction sets; he gets a quite fast result, but it's very heavy on large LUT front ends.
0:58 Why the HELL does your double equal sign NOT have a break in it???? I was confused af why you are doing an assignment in an asset statement? This is just bad design
I did not know that round had floating point errors. Huh. I always though it was rounded to the nearest even integer like with accounting. Why on Earth would they let binary bit impression affect things... Don't get it. Must be I'm missing something.
Are you sure about this? The issue with the rounding you do at school is that it introduces errors on average. So if you have 0.5 and 1.5 and round to zero decimals then you've made it 3. But the usual way to round (for anything serious) is 1 for 0.5 and 1 for 1.5 which is 2. The idea is that if you're doing it loads of times the number of evens and odds will even out. Which isn't completely true (because of Benford's Law) but it's much better than just rounding up every time.
Without the second argument, it does round to nearest integer, with even as tie breaker. The issue is twofold; firstly, the sample number does not precisely match a float (IEEE 754 binary64), and secondly neither do decimals (10**n for n
2:25 "But be careful, due to floating point rounding errors, rounding using python may not give you the same answer as rounding like you learned in school"
Yea, rounding 2.6... to 3.6... is indeed new to me :D
My favourite has gotta be ol' reliable print()
LOOL i was just about to comment this too
That's what we call a physical off by 1 error!
sorry but I don't see the bug happening, for me, "round(2.675 , 2)" gives 2.67
@@intron9 It also didn't happen to mcoding. He just wrote it out the wrong way.
@@intron9yes, but the expected result is 2.68 if you follow conventional rounding rules. .5 always rounds up.
For zip(), don't forget it terminates at the end of the shortest iterable and you can pass the kwarg 'strict' to force it to accept only iterables of equal length (added in 3.10).
There's also a zip_longest in the itertools module, BTW. May be useful for someone.
@@thiagoald1992 itertools contain many useful combinators.
print() has actually so many useful kwargs. Every time I see something like outfile.write("\t".join(map(str, data)) + "
") in a code base when you could just do print(*data, sep="\t", file=outfile), I die a little inside.
Other kwargs to note are end and flush. There may be more but these are the ones I use often
Another useful feature of slice is `slice(None)` which is equivalent to the colon operator, namely `x[slice(None)] == x[:]`. Typically, it's used when you want to pass an index around, but in some cases need the whole iterable. Also works with numpy arrays and pandas tables.
I was not aware of that, thanks.
Definitely simpler than additional if with list comprehension.
big respect. this is a wonderfully crafted video that's super well explained
I appreciate it! Thank you for your kind words.
I have literally seen people reading a python file as text and calling exec on that, so __import__ does not really scare me... they should have watched this video ! thanks for the great content !
really good video, I loved the dynamic functions part!
dict function is really cool, because you can create a dict in a function-like manner dict(first_name="Bob", age=20) instead of {"first_name": "Bob", "age": 20}.
Also set is the only way you can create an empty set
The association list form is also really useful: dict(zip(keys,values))
Somewhat inaccurately, you can use {*[]} to create an empty set.
@@吳政霖-b9t Ahaha that's new to me. It doesn't save any typing though ... len("{*[]}") == len("set()"), so using the latter is much more readable.
Another cool method of dict is dict.fromkeys(iterable) ... that will create a dict where all the values are None.
Why is that useful? It's useful if you want to remove duplicate items but maintain the order. (Building a set will result in an indeterminate order)
I’m going to list this video as mandatory watching for beginners. Great explanations!
Slice is amazing! Idk how i survived without this, especially operating with arrays
what
Fun fact: doing type(some_object)() will actually call the constructor, and make a new object of whatever type some_object is
Very nice. Have you considered, or have you already done, a video of all the dunder methods?
Seconded!
This was the best short summary. Thank you
Already know them all. My favorite -- in the sense that I keep using it nearly every time -- is of course enumerate().
Now make one for the dunder methods/attributes!
wow that is one of the fatest speaking video you made. I had to pause at multiple times to digest the information.
It was still a very good video, I hope you'll cover itertools, functools and other similar libs in an other video:)
I was really trying hard to keep it under 20 minutes and also to go fast because I'd say most of the builtins people already know about so I don't want to waste your time!
14:06 'is' and 'is not' must be doing something in addition to checking the id's, because:
>>> [1, 2] is [1, 2]
False
>>> id([1, 2]) == id([1, 2])
True
This is a fun one! In the second case, the first [1,2] is not stored, so its refcount hits 0 and it is garbage collected before the == happens. When the second [1,2] is created the id of the first one gets reused, leading to the observed behavior. Make sure to never compare ids of objects that are no longer alive for exactly this reason!
If you do need to handle possibly expired objects, weak references is the tool (weakref module).
I nearly knew about em all, but learned a lot nonetheless. loved this. thank you.
Just to nitpick in your nice video: perhaps you should disable the ligatures or use a font without them. In particular think it is confusing that the "==" appears to be continuous. These kinds of font tricks may be useful and look nice for Haskell and its crazy operators, but IMHO it looks weird in python.
Hey thanks for pointing that out, you're absolutely right about the ligatures. I'll make a note of that for future videos.
@@mCodingI disagree. It’s perfectly readable to me.
@@mCodingwhat? I love them!
It's weird and sometimes bad, like how != is not ≠ and 0x is certainly not 0×. You can read it, if you already know what it should mean.
just say u don't like font ligatures instead of making up reasons on the spot for why they shouldn't be used on python
I and many others use font ligatures in languages like C, Go, Rust, C++, JavaScript, Python, Odin, Zig, etc
and it never caused any problems
the only "issue" with font ligatures is complete programming beginners or people that have never used them before might (rarely but still) not know what the ligature might convert to.
thank you for your valuable video and sharing it with generocity
5:45 since bin, oct and hex gave prefixed notations (0b, 0o, 0x) you could pass int(n, 0) to autodetect the base. Also, lowercase x is not the multiply sign ×.
18:06 I stay out of the 38-th Chamber of Python.
"all() of nothing is True, but any() of nothing is False."
Only when talking about programming languages can you get this philosophically weird.
This follows mathematical logic conventions as well! To deny that all of nothing is true, you would need to show there exists an element that is false. To deny that any of nothing is false, you would need to show there exists an element that is true!
This also follows a typical way you would implement a short-circuiting any/all:
```
def any(itr):
for b in itr:
if b:
return True
return False
def all(itr):
for b in itr:
if not b:
return False
return True
```
Passing in an empty itr yields the quoted behavior.
That is necessary to satisfy basic properties like
all(X union Y) = all(X) and all(Y)
if you choose e.g. X to be an empty set.
Since Python 3.8, the 3 argument form of pow can also handle negative exponents if base and mod are coprime to eachother. This makes it easy to compute (powers of) multiplicative inverses.
Hey I didn't know that, that's awesome!
18:45 love that i discovered this one recently, and I actually have a legit use case for it. since variables in python namespaces are accessed by hash table, dumping a bunch of variables I'll need to use from a specific dictionary (among many in a bigger dictionary) to the namespace and then deleting the dictionary is a neat way to access everything efficiently without keeping / using that large data structure and subscripting anything. sure, I could just define my own hash table instead, but doing this made for an easy refactor job and makes the code more readable in the end
Why not just create another dictionary though? I find it hard to believe that this would make it more readable, not to comment on its effect on LSPs' capability of understanding your code
@@higorhi72 the variables are all addresses and offsets of a x86 application, and all follow a standard naming scheme. they're used very frequently and doing it like this made it easy to refactor (I was already calling the variables like this, just not dumping them automatically in the namespace) without having to do lots of manual testing to make sure I didn't typo/miss anything (automated testing is pretty much impossible for this kind of project)
If im exploring something in command like dirs(something) is my goto. Nice vid!
8:21 yeah, reversed works with dict, but dict keys order is not guaranteed, so I don't see this as a "useful feature". Or am I just wrong?
Great question because dict order used to not be guaranteed! Dictionary order has been guaranteed to be insertion order since 3.7, and they have been reversible since 3.8!
@@mCoding Thank you very much! That's the price I pay when I don't read changelogs. Ashamed =(
You missed `__build_class__`. Similar to `__import__`, it's more an internal implementation detail than something that the end user should ever access. But both of them can be overwritten by modifying the `builtins` module, allowing to actually *change the semantics* of those syntax structures.
It's not on the official list! Skipped!
Typo at 2:31? 2.675 does not round to a number greater than 3
How about all dunder/magic methods/attributes? You covered most of the types here, but didn’t bring it up for things like __len__.
But there’s a lot more too, like __enter__ and __exit__, or __del__, all the math ones, and __new__.
Yes, it's on my radar. The only barrier to making that video is that there's over 200 of them!!
My main objection is that builtins should live in suitable packages
How to import those without some builtin import? 🤔
I was waiting for this for a long time
I didn't know isinstance(False, int) was true!
This is a very real possibility for a really subtle bug in code that handles different types differently. Ouch!
"Map is lazy by default". Same bro, same.
I use `dir` all the time…unfortunately, though not in set code. I regularly run into some instance of some undocumented class in a super complicated module, and I want to figure out what exactly they called a method I need, or see if there is anything useful, without spending ages trying to figure out all the parent classes. Especially useful when I’m outside my IDE for whatever reason
Or worse, if they monkey-patched some methods into the class for some reason *shiver*
I felt that shiver
Re j not i. Complex numbers are used a lot in electronics and i already means current. So j was adopted as the next logical choice.
If J see someone using i J know they dont have an electronics background.
I think in Python they chose j because i is already the canonical index variable.
Current is still capital I, I hope...?
Also, in quaternions it's normal to use i, j, and k for three different imaginary axis. In physics capital I often means fixed current and lowercase i time-varying.
2:26 Python uses banker's rounding, so even if there are no floating-point errors, you may get unintuitive results. For example, the result of `round(0.5)` is `0.0`, not `1.0`.
My favorite is definitely set
Sets are fantastic
Nice video, very informative!
For memoryview, the fact that it allows multidimensional indexing is rather secondary. Its primary characteristics is that it doesn't own the underlying memory. In your example, if you were to return the memoryview out of the function, it would reference memory that is no longer associated with anything, leading to undefined behaviors.
memoryview does reference underlying object:
from sys import getrefcount
b=bytearray()
assert getrefcount(b)==2
m=memoryview(b)
assert getrefcount(b)==3
m.release()
assert getrefcount(b)==2
@@RandomGeometryDashStuff you’re right, my example with bytearray was incorrect since bytearray is one of the classes that “knows” when a memory view is taken of them (and prevents you from resizing it as long as the memory view hasn’t called release). But in general memory view is non-owning. I’ve been using it for a while in C extensions to expose memory managed by C and there is no “native” way for the C-level code to know that you have a memory view pointing to that same memory. You could have the C code deallocate the memory, the memory view in the Python side would have no way of knowing.
Favourite: enumerate - use it all the time.
Least favourite: bin, oct, hex - can't stand trying to use python for non-decimal numbers, it is so unpleasant; don't know if this is common in most languages.
slice() is cool as hell, never knew about that one before.
Which languages are you used to? Python's numerals are mostly inherited from C. Forth and bc expose the IO base, and Ada and VHDL support specifying arbitrary base per literal, but I don't think I've ever seen a particularly pleasant form.
@@0LoneTech I'm used to Python. That's why I don't know if there is anything else that is better for it out there haha.
@@fancypants6062 Could you articulate what's unpleasant about it then? Maybe we could find or design a nicer way.
@@0LoneTech It gives you strings for things that are numbers. In general, "it just isn't made to handle non-decimal".
Maybe there is a library out there already that is really good that I just don't know about. It doesn't come up often enough in my life to be a huge inconvenience.
@@fancypants6062 Thank you for that answer. It gave me some things to consider.
What happens internally is that most numbers are represented in binary, or binary floating point. Those are the natively supported types. Decimal is the default base for textual IO, but not a property of the numbers themselves; base conversions do build or parse strings. Hybrid representations like BCD may be easier to convert for other bases, and Python internally does that for long ints, decimal.Decimal or fractions.Fraction.
In particular, the base system itself is notation, not a property of numbers. In Haskell, one of the more mathematically inclined programming languages out there, the Num type class doesn't provide display forms; that's in Show and Read. The Integral type class provides the core function for converting to base forms, quotRem, similar to Python's divmod.
Python's standard library does have an odd asymmetry in that int(str, base) can parse a variety of bases (up to 36) but format will only output the programmer's most popular ones (bodx). There do indeed exist many libraries for other options, including e.g. Kharosthi or Roman numerals, which do not use the base system.
Hey, I use dir somewhat often if I find myself in a jupyter notebook (no LSP) and need to quickly remember an attribute or module function. I could look up the documentation but dir is right there if I'm focused.
Hey, you switched to Fira Code! Interesting.
wait is that VSCode?
LOL guess I’m not the only one who noticed he switched from Pycharm
It is Fira Code, I'm trying it out! I use both PyCharm and VS Code!
0:12 Is it accurate to call them global names? Aren't builtins a whole category unto itself by the LEGB rule?
OMG, super useful video
No ligature fonts please
Warning with id() , it's only meant for internal use, you shouldn't think of memory addresses when using python.
Also, id() can behave in unexpected ways, for example the object int(3) will give the same id as when making another int(3) , because of python optimizations that are applied on the considered "most used integers".
This is a bit subtle, but id is not just meant for internal use only. The part that is for internal use only is that id(x) gives the memory address of x, which is a CPython implementation detail. That id gives you a unique and stable integer as long as x is alive is very much part of the public API that you should feel free to use.
int(3) doesn't make a new int; it returns 3 from the small integer pool. Sharing all instances of small integers is possible because int is immutable. Similarly, after a,b=(1,2),(1,2), a is b because the compiler identified subexpressions.
yep, "integer interning", in cpython usually -5 to 255 ish
The fact that potentially dangerous "id" made it into builtins and not stored in inspect or sys module is rather unfortunate. It's very hard to come up with valid use case for it in real code, not just for quick debug or experiments, and even there comparing with "is" is more reliable.
One of the few builtins that are commonly in linter's exceception list to allow shadowing (and ban original for commit).
2:51 just sum the boolean values, True is equivalent to 1 and False equivalent to 0 so sonething like num_of_cs_gte_n=sum(c>=n for c in cs) is fine.
Yeah, I love doing that, but I have seen people complain about it
You can definitely do it that way too! I find explicitly listing 1 to be more readable, but I wouldn't complain if you did it your way.
Why do you prefer list comprehension over filter?
I prefer using list/set/generator comprehensions over filter and map purely because of readability. The main issue with filter and map is that it's easy to forget the order the arguments go in, whereas this is not an issue with the comprehension syntax
What best place to learn python with PHP programming background for a long time?
Can you make a video describing multiple inheritance with multiple variables using super class?
Already done! ua-cam.com/video/X1PQ7zzltz4/v-deo.html
Hey mCoding. Can you make a video on how to use venv, how to create, manage virtual environments? Thanks :D
This is on my list!!
If I may add to this, I'd like to see Conda envs too, though actually more of a Conda equivalent of mCoding's "Automated Testing in Python with pytest, tox, and GitHub Actions". Better yet if it's about using pip/venv and conda together.
Seems you forgot about copyright() ;)
19:00 How do they make locals immutable?
They don't, it just might not work if you do mutate it.
I see the hitchhikers guide to the galaxy reference, kudos to you good sir
8:50 filter and map are uglier in terms of syntax, but can be much better than comprehensions depending on the use case. It should be emphasised that the two are not interchangeable, if a copy is desired, comprehension is better, but if a modification is done for a single iteration only, map and filter are better!
One can use a generator comprehension (x for x in ... if ...) or (f(x) for x in ...)to avoid the copy when using comprehensions as well, so I personally find them better whether a copy is desired or not.
@@mCoding I understand that the comprehension form is to Guido's taste, but for me filter and map involve less new names to typo and name the task more directly, particularly if I already have a named function to apply. But I also often prefer Haskell and find the demotion of reduce() counterproductive.
03:37 no frozendict?
That's right, there's no frozen dict! (Yet?)
this would've been super helpful 4 years ago when i started learning *everything* about python, doing cybersecurity CTF challenges
Thanos has finally collected all the infinity Stones
discord gang 🤙🤙
???
Always appreciated!
these languages and standard libraries are garbage. i'm not saying i could do better, but the weird caveats in each language are just mind boggling strange. Also, you never mentioned that this info is for python 3.7 and above
3.7 is past its end of life already, so there's no point in commenting on about it.
Which language would you propose is not "garbage" then? I'd like to study its weird caveats.
@@0LoneTech my guess is that binary is not garbage. each language built upon that adds human nuances that get exaggerated and confused easily. i like studying the weirdness as well, but i get tired of not having better tools. why do we still code like monkeys at typewriters?
... because 0 isn't totally an abstraction that took humankind 300000 years to come up with...
@@nil0bject Then I guess you're in for some wonderful surprises once you do learn about machine language. In particular, look at the bit orders of fields in the RISC-V instruction set; and that's one of the most carefully designed ones out there, in sharp contrast to things like the recycled instructions used for prefixes of astonishingly long extensions in x86.
James Sharman's 8-bit pipelined CPU series gives a neat look into one possible way to design instruction sets; he gets a quite fast result, but it's very heavy on large LUT front ends.
thank you
0:58 Why the HELL does your double equal sign NOT have a break in it???? I was confused af why you are doing an assignment in an asset statement? This is just bad design
Just 71? :o
Next video All built-in C++ functions
Nice video, thank you😊
I did not know that round had floating point errors. Huh. I always though it was rounded to the nearest even integer like with accounting.
Why on Earth would they let binary bit impression affect things... Don't get it. Must be I'm missing something.
Are you sure about this? The issue with the rounding you do at school is that it introduces errors on average. So if you have 0.5 and 1.5 and round to zero decimals then you've made it 3. But the usual way to round (for anything serious) is 1 for 0.5 and 1 for 1.5 which is 2. The idea is that if you're doing it loads of times the number of evens and odds will even out.
Which isn't completely true (because of Benford's Law) but it's much better than just rounding up every time.
Without the second argument, it does round to nearest integer, with even as tie breaker. The issue is twofold; firstly, the sample number does not precisely match a float (IEEE 754 binary64), and secondly neither do decimals (10**n for n
@@0LoneTech I see. Thanks for your input.
Oh, I cannot believe that I've never seen @property. I've been overriding __getattr__ and __setattr__ for quite some time...
Just awesome! I forgot eval() 😀
Nice info about `__int__` etc. Going this path the `__call__` was missing.
there is no builtin `call` function
@@saadzahem Yes, in this view OK.
But still... "functions are callable, classes are callable, method is callable". Are instances callable?
@@robertkalinowski6770 If they have a __call__ method, yes.
@@robertkalinowski6770 If they have a __call__ method, yes.