More Python Code Smells: Avoid These 7 Smelly Snags

Sdílet
Vložit
  • čas přidán 31. 05. 2024
  • These are 7 code smells to avoid plus a bonus smell. I describe each smell using a Python example and then show you how to fix it. At the end of the video, I have a few general tips to help you avoid introducing code smells in the first place in your design.
    For the first Python code smells video, see: • 7 Python Code Smells: ... .
    The code I worked on in this episode is available here: github.com/ArjanCodes/2021-mo....
    💡 Here's my FREE 7-step guide to help you consistently design great software: arjancodes.com/designguide.
    🎓 Courses:
    The Software Designer Mindset: www.arjancodes.com/mindset
    The Software Designer Mindset Team Packages: www.arjancodes.com/sas
    The Software Architect Mindset: Pre-register now! www.arjancodes.com/architect
    Next Level Python: Become a Python Expert: www.arjancodes.com/next-level...
    The 30-Day Design Challenge: www.arjancodes.com/30ddc
    🛒 GEAR & RECOMMENDED BOOKS: kit.co/arjancodes.
    💬 Join my Discord server here: discord.arjan.codes
    🐦Twitter: / arjancodes
    🌍LinkedIn: / arjancodes
    🕵Facebook: / arjancodes
    👀 Channel code reviewer board:
    - Yoriz
    - Ryan Laursen
    - Sybren A. Stüvel
    🔖 Chapters:
    0:00 Intro
    0:31 Explaining the example
    2:45 What is a code smell?
    3:04 #1 Too many parameters
    5:03 #2 Too deep nesting
    10:01 #3 Not using the right data structure
    12:19 #4 Nested conditional expressions
    13:39 #5 Using wildcard imports
    15:33 #6 Asymmetrical code
    16:58 #7 Using self when it's not needed
    18:31 #8 (BONUS): Not using a main() function
    19:02 Tips for avoiding code smells
    #arjancodes #softwaredesign #python
    DISCLAIMER - The links in this description might be affiliate links. If you purchase a product or service through one of those links, I may receive a small commission. There is no additional charge to you. Thanks for supporting my channel so I can continue to provide you with free content each week!

Komentáře • 219

  • @ArjanCodes
    @ArjanCodes  Před 2 lety +18

    If you haven't seen the first code smells video, this is the link: czcams.com/video/LrtnLEkOwFE/video.html.

  • @moomoocow526
    @moomoocow526 Před 2 lety +57

    Regarding your first code smell: I feel that having meaningful, but possibly inaccurate, default values is smelly. A programmer who neglects to provide a car's fuel type by mistake should get an error, not an electric car. I would support using `None` or some enum value that represents an invalid value.
    For a developer using your code base as an API, the same amount of mental effort would be needed to determine whether a parameter can be excluded because the default is the correct value as would be needed to simply include the value.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +12

      It's a balance for sure. I believe the main issue in this code smell was the feature envy part. Default values do give an idea of what a developer expects as a reasonable input but you are right that choosing good default values is hard. If you succeed though, it really makes using an API or a function much easier.

    • @janekschleicher9661
      @janekschleicher9661 Před rokem +1

      I agree and the much more problematic issue is to provide a static default for a slowly changing dimension (here: the year). If the program runs over New Year's Eve, it will be very likely being wrong and that silently while probably passing all tests and even working locally correct in your local development setting on your computer. That's a very bad thing and really very ugly to debug (in my experience, you will need multiple seniors to spot that issue on running in production). It's also a problem that might only be on one the of the servers and not on another server (maybe because there was a restart triggered by docker/Kubernetes or by the AWS service, so it is a bug not only hard to spot, but completely out of our control when it happens in production and will be even different for the same deployment on different computers).
      And even worse: Very certain, all unit tests, all integration tests and all acceptance tests will pass, unless of course you are lucky and have one test exactly starting some ms before New Year's Eve and will trait it's fail very seriously, even though all consecutive tests are passing again.
      A complete production maintainance nightmare.
      Not sure if a linter might catch it (somehow I doubt it).
      Here, the correct implementation would be either to set a factory method for the default values (IIRC dataclasses support that) or probably get rid of a default value for a year, just as there is no default value for a year. (Yes I know, the current year, but this does not have a static value, it's slowly changing).
      @ArjanCodes Maybe it's worth to add a pop up ("should be a factory") that this is accidentially a huge code smell. I think, a lot of junior will follow here your example and as it is tricky to understand and to fall into this trap, this is solid potential to affect production systems doing something important.

  • @jamesrea6902
    @jamesrea6902 Před 2 lety +77

    Really good content, I would recommend this channel to anyone who wants to make their code cleaner.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +2

      Thank you James, glad you enjoy the videos.

  • @Fitri-mn1je
    @Fitri-mn1je Před 2 lety +2

    Really appreciated the time you invested in to create this content. Videos beyond basic stuff is hard to find.

  • @itnabigator
    @itnabigator Před 2 lety +26

    replacing 2021 with current year was quite unexpected :) a good refactoring to have a happy new year %)
    In code smell 4 you don't need else because of return early pattern.

    • @Glazer209
      @Glazer209 Před 2 lety +5

      Oof ya, saw that year default and was like “oh boy, that’ll be a fun bug to find next year”

    • @ufogrindizer5038
      @ufogrindizer5038 Před 2 lety

      @@Glazer209 That was my thought exactly, and so when I saw your comment here I was like: "oh boy! we really are a cult, or at least I understand why 'normal' people sees us as members of a different species" :)

  • @maxwell2201
    @maxwell2201 Před 2 lety

    Thank you so much for doing these videos! They are helping me IMMENSELY on my journey to become a better developer. I have to watch and rewatch a lot of them, but over time stuff starts to stick, and it makes a huge difference.

  • @voxelfusion9894
    @voxelfusion9894 Před 2 lety +6

    For example, one code smell I purged from my project recently was over-using
    from import thing1, thing2, thing3, thing4, thing5, ..., thing10
    It added a lot of useless noise and made it tedious to swap out objects for something else from the same method.
    This is a gui project with pyside6, so importing all those widgets was messy until I just used
    import PySide6.QWidgets as Qw
    To simply refer all things by prefixing Qw. rather than all those explicit imports.
    The video you made on pydantic also helped a lot, making the way I store data much, much clearer and easier. Before, I had been using a massive, deeply nested dictionary, and remembering how to spell all those key strings was so prone to bugs. It still gives me shivers.
    Thanks!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +2

      Glad to hear the videos helped you!

  • @huantian
    @huantian Před 2 lety +37

    I believe you don’t actually need to import Tuple from typing, you can just use the buuiltin tuple, at least in more recent versions of python

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +19

      You're absolutely right, I'll make sure to do that instead in future videos!

    • @burnere633
      @burnere633 Před 2 lety +11

      @@ArjanCodes I thought of exactly the same thing, but then remembered it's a 3.9 thing. If I may suggest, mention that some features are only available a subset of the currently-supported versions, as in the walrus operator, lest a newbie trips up while excitedly using it in an older version of Python.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +8

      Good idea, @Burner E!

    • @sadhlife
      @sadhlife Před 2 lety +3

      yea it felt kinda awkward when he nested a typing.Tuple type inside a builtin dict type. for now I'll suggest stick with typing types only as 3.9 is pretty far from becoming the default still
      another option would be to tell people to add the "from `__future__` import annotations" import at the top of their files, then it'll work everywhere from 3.7 and above, but still kinda cumbersome.

  • @iChrisBirch
    @iChrisBirch Před 2 lety

    I love your videos!! Coming from a barely intermediate level knowledge of software design and few years experience coding, these videos showing code the whole time and putting the theoretical ideas in practice are fantastic! I prefer to watch your refactoring videos over TV any day! Thank you very much for the awesome content!

  • @ArberAboow
    @ArberAboow Před 2 lety +1

    This channel is pure gem. Your way of explaining, speaking and use of examples as well as visualizations is simply awesome!
    Thank you und keep it up!

  • @Victorinoeng
    @Victorinoeng Před 2 lety +2

    Legend!!! What a great content, presented in such an easy to follow along. And with a sense of humor! Huge fan of the work you are developing!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Thank you Marcello, glad you like the videos!

  • @_mactast1c
    @_mactast1c Před 2 lety

    Excellent content, I think this is the only channel that I get excited when a new video appears. I’m looking forward to more of your podcast, left a 5 start review there as well!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Thank you Casey, glad you liked it!

  • @joshcousins9422
    @joshcousins9422 Před 2 lety

    Sick to see the progress your channel is making! Love the content, keep it up 💪🏻

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Thank you Josh, glad you like the content!

  • @abdullahmobeen8036
    @abdullahmobeen8036 Před 2 lety +11

    Great content! Impatiently waiting for a video on design patterns for production-level machine learning projects.

  • @mihaimyh
    @mihaimyh Před 2 lety +2

    I will love to see a video regarding managing application configuration in Python, like taking configuration values from environment variables, text files, etc.

  • @IterativeTheoryRocks
    @IterativeTheoryRocks Před 2 lety

    Marvellous videos. This is my favourite python channel.
    Regarding the refactoring to put the conditions that must be satisfied first, and returning an error if they are not satisfied, I have heard that called ‘guard conditions’ which makes sense to me.
    In python they may be a list of ‘try’ ‘except’ which if they all pass, then the function returns a value, if any of them fail, it returns an error or none or whatever.

  • @manonthedollar
    @manonthedollar Před 2 lety

    Wow, your channel is growing like crazy. I remember view counts being around 150 just a few months ago. Great work!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Indeed! It’s been a crazy month!

  • @rd94282
    @rd94282 Před 2 lety

    The first programming CZcams who can actually code!!! Wtf! 😂😂 love the videos, keep it up, I’m learning a ton!

  • @kurosakishusuke1748
    @kurosakishusuke1748 Před 2 lety

    Found many points to be learnt from your video. Definitely a great supplement for my current course aiming to become machine learning engineer.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Glad to hear you found the video helpful!

  • @AlejandroLamKhoa
    @AlejandroLamKhoa Před 2 lety

    This channel is a hidden gem for me as a data scientist who’d love to learn more about how to make my code cleaner and adhering to best practices. Thank you for the awesome content!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Glad to hear you like the content!

  • @wspek
    @wspek Před 2 lety

    Thanks Arjan, you explain well. Goed bezig. I received your content through the Python Weekly news letter.

  • @TheGustavoGamerBR
    @TheGustavoGamerBR Před 2 lety +10

    Hey man, I really appreciate your work with these videos. I would like to suggest a content about *args and **kwargs in the design patterns, since they can be used in class wrappers, are features utilized in big libraries (e.g., numpy, matplotlib) and barely has any documentation showing its use in real world development scenarios.

  • @wanhonglau779
    @wanhonglau779 Před 2 lety +2

    this is super cool content! would u consider making a session on how to write a good design doc?

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Glad you like it and thanks for the suggestion!

  • @fierce1340
    @fierce1340 Před 2 lety +2

    I love this channel. When will you put out a tutorial on how to smile pleasantly? LOL Your outro smile is so friendly!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Thanks Scott. I’ll think about your suggestion ;).

  • @AR-ly5zt
    @AR-ly5zt Před 2 lety +1

    Hey Arjan, fellow developer here, this is a very nice list of refactors and is cool to already have an idea on what you are going to suggest while you are describing the problem.
    Keep it coming! It's very valuable content

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Thanks so much, glad you liked it!

  • @Pirake123
    @Pirake123 Před 2 lety

    Awesome stuff Arjan!

  • @DonGioification
    @DonGioification Před 2 lety

    Awesome video, I learnt a lot. Thanks mate

  • @Vdherrlichkeit
    @Vdherrlichkeit Před 2 lety

    Excellent content again. Great work.

  • @mauisam1
    @mauisam1 Před 2 lety +3

    I know comments are important for YT, but I can't help but say Thank you again. I know it takes a lot of work to produce at YT video and your hard work is much appricated! I installed pylance and black by the way.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Thank you very much, Sam. I’m happy the videos are helpful and I’m sure you’ll enjoy the combination of Pylance and Black.

  • @miguelvasquez9849
    @miguelvasquez9849 Před rokem

    these videos are awesome for improving code cleanliness. I have a doubt, I noticed that the line at 14:57 was very long, is it not recommended to use the 80 characters?

  • @joaovictorpereirarocha33

    Excellent content, Arjan! Thanks a lot. I really appreciate if you make a video about SOLID principles using Python examples, can you make it?

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Glad you like it! I did a video about SOLID principles a while ago: czcams.com/video/pTB30aXS77U/video.html.

  • @djangodeveloper07
    @djangodeveloper07 Před 2 lety

    interesting videos and got great ideas to improve my code. please keep adding such videos. it shows me how bad i am in coding :p

  • @presstv
    @presstv Před rokem

    nice video, great job buddy🙂👏👏

  • @JacekAdamczyk
    @JacekAdamczyk Před 2 lety +1

    I'm still a beginner, but your videos are gold! Thank you!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      You’re most welcome! Happy you like it.

  • @gustavorangel729
    @gustavorangel729 Před 2 lety +4

    Video on when to use class methods would be great! Thank you!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +2

      Thank you for the suggestion!

    • @Talon_24
      @Talon_24 Před 2 lety

      Cool thing is that class methods can use other class methods or static methods

  • @zacky7862
    @zacky7862 Před 2 lety

    Very usefull! My favorite python teacher now :)

  • @billywang3829
    @billywang3829 Před 2 lety

    I love your content because I targets the niche of people who know Python, aren't beginners and want to take their knowledge to a more polished level

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Thanks Billy, that is exactly the type of audience I’m aiming the content for.

  • @BLSchaf
    @BLSchaf Před 2 lety

    This content is so good!

  • @coxinitus
    @coxinitus Před 2 lety +1

    Hi Arjan! I want to know your pov about the projects structure and how could be managed locally or within docker container. Thx you are making awesome videos!

  • @BRLN1
    @BRLN1 Před 2 lety

    @ArjanCodes - I do have question regarding your "Bonus". What is the purpose or benefit of enclosing main code inside a separate function ``main()`` which in turn is then called from inside the ``if __name__ == "__main__": ...``-condition; given that I otherwise could have just pasted its content directly into the code-block of the aforementioned condition?

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +3

      The reason for using a separate main function is that this limits the scope of any variables you declare to that function body. If you put the code directly under the if statement, any variables you declare there are going to be available in the entire module (in this case, registry for example). This may lead to unexpected problems: shadowing warnings, or accidentally using a variable you didn’t intend to.

    • @gavin.burnell
      @gavin.burnell Před 2 lety

      @@ArjanCodes but surely a major use case of that if statement is to ensure that your module's test code executes when you run the module as a top level script, but not when you import it from another script. If you are importing the file as a module, the if statement never executes and those variables never exist within the module namespace. On the other hand, if you're running the file to test the functionality then if your test codes tramples over your module namespace then probably you've got bigger problems to solve :-) I guess my attitude is that a main() function possibly indicates someone who is happier in C and then I start looking for Cmells in the code! I would agree that if you have real non-testing functionality inside that if statement then you probably want to put a lot of it into some functions, but I'm not sure I'd agree that main() is the best choice of name since it dopesn't have any specail meaning in Python unlike C.
      Other than that quibble, I like you smells videos and know some grad students whp could usefully profit from watching them!

  • @Maric18
    @Maric18 Před 2 lety

    my biggest gripe with the python conditional oneliners is that the if is in the middle, while the normal python if is sturctures if condition: a else b
    a
    ?thing_if_a_true
    :thing_if_a_false
    is so much easier to read and is still fine to read if nested

  • @fashionvella730
    @fashionvella730 Před 2 lety

    just watch your videos for fun but that fun making me more better
    software developer

  • @estebanmejia9989
    @estebanmejia9989 Před rokem

    It's a good idea to import a class only to use it as a type of a variable?

  • @bencedanko7334
    @bencedanko7334 Před 2 lety +1

    these videos are absolutely fantastic, everything is so well articulated and you have so much knowledge (and wisdom) to impart, if you were to ever create more guides or even write a reference book I would buy it on the spot

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Thank you so much! I’m working on a more complete design course at the moment, stay tuned!

  • @uwuwgrhdhwj
    @uwuwgrhdhwj Před 2 lety +1

    Another good video. Can you do one on ABC? And your take on using them on OOP or another style you prefer

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +3

      Thank you, and yes, I’ll certainly cover ABCs in more detail in the future.

    • @uwuwgrhdhwj
      @uwuwgrhdhwj Před 2 lety

      @@ArjanCodes thanks! Looking forward for ABCs

  • @rbettsx
    @rbettsx Před 2 lety +1

    Great stuff. Clean and concise. 1 suggestion. Your video is nicely paced as a whole. It comprises a number of 'chapters', one for each smell. You take corrective action for each one. If you held for a beat or two on the *correction* , I think it would be easier to understand, and have a better rhythm. I've noticed this tendency not to 'take a breath' in some of your other films? No criticism of your content - it's really helpful.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Hi Robin, glad you’re enjoying it! It’s a challenge to find the right pace on CZcams as in general videos need to move pretty fast here in order to not lose viewers. But I’ll surely experiment with this more.

  • @aminramazanifar9743
    @aminramazanifar9743 Před 2 lety

    Thanks for the great video.
    One opinion about using return in the middle of the method:
    It reminds me of using goto which we were told not to use. Imagine placing a breakpoint to debug the code and because of a return, it never gets there and can be confusing. A single return at the end of the method is probably a good idea.

    • @IterativeTheoryRocks
      @IterativeTheoryRocks Před 2 lety

      I disagree.
      As for why, its hard to explain in a comment!
      But returning early once a condition is met (or error condition is met) is a better style for me. I guess it comes down to which is most ‘pythonic’.

  • @ewerybody
    @ewerybody Před rokem

    15:27! WORD!! EXACTLY!!
    I don't get this shortening/renaming obsession 🙈
    I mean I've been there once ... but I genuinely like original module names much more now.

  • @muntakim.data.scientist

    Subscribed ❤️

  • @gianluke
    @gianluke Před 2 lety +1

    By using a stateful default value you introduced a new smell. Then by removing year=2021, you introduced a bug that proves why having a stateful default value is a bad idea (the launch year of those models will change every year).

  • @curtnorris4458
    @curtnorris4458 Před 2 lety

    Thanks for publishing such excellent content!
    Question about the bonus code smell though. You mention that having variables declared in the if __name__ == '__main__' block could lead to name clashes and shadowing at the module level, but shouldn't that not be the case? If you import that module into another, the if block won't be executed.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +3

      Hi Curt, thanks! What I meant is name clashes within the module file itself. Any variables that you use directly under that if-statement are going to be accessible everywhere in the module file and that may lead to issues such as shadowing. Indeed, what’s under the if statement will only get executed if used as a main file. That means, you’ll have different scopes depending on the use case. If you accidentally use a variable defined under the if statement, the code will work when used as a main file, but not when used as a module (or in that case, the variable will be dynamically created leading to other possible bugs).

    • @curtnorris4458
      @curtnorris4458 Před 2 lety

      @@ArjanCodes ah, that makes sense. I misinterpreted what you were saying then. Thanks for clarifying!

  • @Hubert4515
    @Hubert4515 Před 2 lety +1

    cool video! thanks

  • @MuhammadFahreza
    @MuhammadFahreza Před 2 lety

    Hi Arjan, do you mind to share your black code formatting configurations?

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      I don’t think I changed all that much in the settings, except perhaps the minimum line length. I’ll do a video in the future covering extension settings and setup tips for VS Code.

  • @Tomlm6060
    @Tomlm6060 Před 2 měsíci

    Grea video, very insightful, thanks!
    Ruff is also a nice tool to detect code smells. Any thoughts on that? :)

  • @RoamingAdhocrat
    @RoamingAdhocrat Před 2 lety

    I consider myself a fairly capable hobbyist/opportunist programmer and this really helped me.

  • @Aang139
    @Aang139 Před rokem +1

    I think for #4 i would have broken it all into if elif else. Swapping between if return and return if though much easier than before is still hard to read, compared to destinct cases and returns

  • @jam7221
    @jam7221 Před 2 lety

    Would love to see a video where you design a small system using a design tool of your choice, and then a follow up video where you implement it.

  • @lukajeliciclux3074
    @lukajeliciclux3074 Před 2 lety

    Phenomenal video.

  • @FalcoGer
    @FalcoGer Před rokem

    i like to just import the module and then use the namespace.
    import pwn
    elf = pwn.ELF('/path/to/bin')
    instead of
    from pwn import a,b,c,d,e, ELF, and some more stuff i need
    elf = ELF('/path/to/bin')
    makes everything more clear, which code is using what library right there in the code.

  • @MellexLabs
    @MellexLabs Před 2 lety +1

    Hi Arjan great video!
    Maybe it's me being used to coding in C# and explicitly defining a type for everything, but something made me cringe when I saw you returned a tuple from a function... I would've probably made a dataclass or a named tuple to return the values. I try to be explicit when coding hopefully not leaving things up for interpretation, but hey I did say I come from a more statically typed language. I would like to know your thoughts on that. Thanks!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Hi Malcolm, thanks - glad you liked the video! I’m actually more experienced in statically typed languages as well (I coded in Java and then C# for over a decade). Python is a bit different. It relies more on duck typing and data structures such as tuples and dicts. So this is me trying to adapt to that world :).

    • @MellexLabs
      @MellexLabs Před 2 lety

      Ok good to know your background. The way you wrangle python is very good... I guess that's why your videos are so popular and done really well.
      I am trying to understand the duck typing thing... I think it will make a great video topic and you could also explain the pitfalls of allowing duck typing to happen.
      I will add it as a discussion topic on discord.

  • @marverickbin
    @marverickbin Před 2 lety

    My main struggle knowing which classes I need to create to solve a problem.

  • @ewerybody
    @ewerybody Před rokem

    13:11 the dots that appear at line 110: is that pylint? 😃
    I guess it's suggesting to remove the else and indentation because the code underneath wouldn't be evaluated after return anyway.
    The else block still seems smelly: I'd make it return the connection error when there are no vehicle models and finally return ONLINE at the root.

  • @johnnyt.2523
    @johnnyt.2523 Před 2 lety +1

    I actually wanted to switch back to Java because of the way python was written. Hadn't seen your videos!!! Please make a tutorial on the way you are writing Python for the new ones or/ and anyone please link me a video that does that.

  • @akshaysharma6160
    @akshaysharma6160 Před 2 lety

    Hi Sir, I really like your videos , but nowdays since we use sqlalchemy alot. Could you please create a video on good practices while working with ORM classes and objects.🙏

  • @init1508
    @init1508 Před 2 lety

    what a guru thank u sensei

  • @wisanuupatumphun7831
    @wisanuupatumphun7831 Před 2 lety

    Wow, never knew we can use a tuple as a key of dictionary! Cool!

  • @terriplays1726
    @terriplays1726 Před 2 lety

    Wildcard imports, my nemesis: I’m a physicist working on simulation and the most popular simulation code in my field uses them all the time! They use wildcards imports of all their modules, and in these modules most standard python libraries are also wildcard imported! Trying to figure out from where a certain function was actually imported is a nightmare. Also, they seem to be allergic to return function output, everything has to be created before calling a function and passed as an input parameter to have in place calculations performed on it.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Oh boy… that sounds like fun.

  • @Micaeljm
    @Micaeljm Před 2 lety +1

    Using the "current" year as a default value is, in my opinion, usually a bad idea. 4:07
    For example, on your code, you're creating all VehicleModelInfo instances without providing a year (4:48), which today might work perfectly fine, but next year it won't, since it'll then be 2022 instead of 2021. So basically, your code now has an "expiration date", after which it breaks, no longer works as intended, and will start failing tests.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      You’re right. Perhaps a better choice for a default value would simply be ‘2021’ (int) in this case.

  • @joshuamcdonald5850
    @joshuamcdonald5850 Před 2 lety

    crushing it as usual (y)

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Thanks Joshua, glad you liked it!

  • @Tferdz
    @Tferdz Před 2 lety +1

    13:35 you don't need the else (guard clause)

  • @CrapE_DM
    @CrapE_DM Před 2 lety +1

    Why is a lack of defaults a smell? Because there's so many parameters?

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Yes, the smell is ‘too many parameters’. Defaults are a possible solution to that.

  • @jeju3267
    @jeju3267 Před 2 lety

    I love it

  • @fantasdeck
    @fantasdeck Před 2 lety

    I tend to avoid and statements in conditional logic when one of the conditions has a higher likelihood of negating the need to check subsequent conditions that take longer to compute. But, I'm talking about millions of entries for NLP stuff.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      I’m not sure but do most compilers/interpreters not optimize this such that if the first part of an and results in false, the rest is not even evaluated?

    • @fantasdeck
      @fantasdeck Před 2 lety

      @@ArjanCodes Not sure. I assumed that the and waited for both results before computing a Boolean value. Is there an optimization in the machine language that simply returns False if, say, the leftmost horn of a conjunction returns False?

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Not sure either. From pure efficiency of evaluating Boolean expressions it makes sense, but if those evaluations have side effects, this optimization breaks things (even though having side effects in conditions is a code smell imho).

  • @DanielRodriguez-lu3uu
    @DanielRodriguez-lu3uu Před 2 lety

    I love these Smells Codes sessions. #arjancodes I tried to find the design/guide, I could not, seems to be a broken link

  • @ewerybody
    @ewerybody Před rokem

    14:54 now this f-string line is uber convoluted and kinda hard to grasp whats going on. I'd always say: If there is more code in your formatting than formatting: give up the urge to inline and create short variables that you tuck into your string. You will also thank yourself whenever you step over that line when debugging.

  • @The1enzo2
    @The1enzo2 Před 2 lety

    This sum Quality vídeo right here

  • @KiraleosAkis
    @KiraleosAkis Před 2 lety

    You should override the default __str__() and __repr__() implementations instead of writing your own to_string() function.

  • @ehsisthatsweird
    @ehsisthatsweird Před 2 lety +2

    Checking for None without `is (not) None` is a bad practice imho.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      I had the ‘is not None’ in the first version when I wrote the example, but then decided to remove it for brevity. Indeed, it might be better to leave it in as being explicit here is not such a bad thing. I think Go actually prohibits this kind of expression.

  • @phill4337
    @phill4337 Před 2 lety

    There are some code smells that are particular to certain people. For example, many coders love to smell ass. They also smell *like* ass. These two facts are loosely coupled. Those devs interface is usually open for modification

  • @sbypasser819
    @sbypasser819 Před 2 lety

    I hate python, but i watch your videos to learn programming tactics.

  • @user-no9bw6xt5k
    @user-no9bw6xt5k Před rokem

    after you changed the list to dict you needed to delete the find_model_info because the dict do all the work to find the info

  • @angtranhai6457
    @angtranhai6457 Před 2 lety

    Nice.

  • @infiltr80r
    @infiltr80r Před 2 lety

    I love the walrus/assigned expression operator but it's not universally supported. Cython won't compile with it and likely never will.

  • @random_act
    @random_act Před 6 měsíci

    Aren't using an asterisk for the imports is eight code smell here.

  • @tbtitans21
    @tbtitans21 Před 2 lety

    I like the video in general but the walrus operator is what I would consider when I want to intentionally obfuscate my code 😂

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Indeed, I also mentioned this in the video.

  • @olexandrklymenko
    @olexandrklymenko Před 2 lety

    I’ve noticed a “code smell” in your example: it’s using len function to check whether a sequence is empty))

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Why would that be a code smell?

    • @olexandrklymenko
      @olexandrklymenko Před 2 lety

      @@ArjanCodes It was a joke)) It’s not actually a code smell, it’s just a nit pick.

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      No worries! But I’m curious: what would be your preferred solution?

    • @olexandrklymenko
      @olexandrklymenko Před 2 lety

      @@ArjanCodes rather than “if len(collection) == 0” I prefer “if not collection”. Or instead of “if len(collection) > 0” I use “if collection”

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      There’s another comment on this same video suggesting the exact opposite and always make conditions explicit and not dependent on truthy values. I kind of agree with this. The Go language even forbids this kind of thing to force you to write conditions that clearly indicate what you mean. For example, ‘if collection’ could mean that you only want to do something if the variable is not None, or that you only want to do something if the list contains items. Assuming one or the other might lead to unexpected bugs.

  • @jeancerrien3016
    @jeancerrien3016 Před 2 lety +1

    Wow, this doesn't smell!
    Using current year will lead to different operation depending on when you execute the code. Seems like a bug.
    If you have 'if foo: return bar', then no else is need (cf. @13:14). This lets you remove one level of indentation.

    • @FelixFranz
      @FelixFranz Před 2 lety

      I was thinking the same thing, when he suddenly started typing datetime. If the design requirements would explicitly call for that, okay. Otherwise this side-effect can lead to quite a data-mess that slowly starts snowing up around mid January 😈

    • @FelixFranz
      @FelixFranz Před 2 lety

      Great channel, keep it going like this! The example and explainer code always feels like directly pulled from some company repo. Good depth and complexity, while still easy to grasp it in full.
      Also your pacing is quite at the sweet spot to quickly get to the point, but leaves enough room to get ideas and opinions by yourself.

    • @FelixFranz
      @FelixFranz Před 2 lety

      Oh and you fill quite a gap I experienced a while ago when starting with Python. Ido have quite some coding experience and wanted to go full-on "pythonic". Though I lack strong fundamentals in software design. During my journey I could often find just abstract docs about the pythonic and no real-life examples to guide my way.
      Thanks you do a really good job in both regards!

  • @monochromeart7311
    @monochromeart7311 Před 2 lety

    Moi arrived 1st to process the stench of the snake script!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Enjoy 😉

    • @burnere633
      @burnere633 Před 2 lety

      Correction: stench created by those who don't know how to compose in the snake script.

  • @soberhippie
    @soberhippie Před 2 lety

    The VehicleInfoMissingError should be raised by the find_vehicle method. You'd have less code and you'd get rid of a None, which is quite evil

    • @ArjanCodes
      @ArjanCodes  Před 2 lety

      Good suggestion. I had to make a few compromises in the example code to make sure all the smells fit it, this was one of them.

  • @frogstud
    @frogstud Před 2 lety

    I love my code: Simple and Clean™

  • @vraymond2048
    @vraymond2048 Před 2 lety +1

    like 👍 & comment before starting the video 😁

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      Thanks! Hope it doesn’t disappoint 😊

  • @RoamingAdhocrat
    @RoamingAdhocrat Před 2 lety

    The seven deadly code smells: Pride, Lust, Gluttony, Dopey, Sneezy, Bashful, Doc

  • @andrewmenshicov2696
    @andrewmenshicov2696 Před 2 lety

    droppin a like cuz i forsaw few smells and he almost convinced me he'd ignored them 😆

  • @DanielFenandes
    @DanielFenandes Před 2 lety

    The else in line 112 at 13:30 is redundant

  • @draufunddran
    @draufunddran Před 2 lety

    On line 79 you forgott to change the comment from saying "list" to saying "dictionary"... Thats why i always asume that comments are wrong. It even happens to the best people.

  • @danilkister1650
    @danilkister1650 Před 2 lety

    Code review: main() should be called run_main(). Functions are verbs!

    • @ArjanCodes
      @ArjanCodes  Před 2 lety +1

      In general I agree, but ‘main’ is such a standard entry point for an application that I prefer to keep that name for clarity.

  • @user-zv5nc7xp8l
    @user-zv5nc7xp8l Před 2 lety

    When I see that 'stinky code', I understand that my code should smell like a bum)

  • @mattseaton5832
    @mattseaton5832 Před 2 lety

    I would hate for this guy to be reviewing my code

  • @fashionvella730
    @fashionvella730 Před 2 lety

    instead of tuple using concatination of brand+model as a key make more sense

  • @grimonce
    @grimonce Před 2 lety

    Yea, wallrus operator, not really a fan of that...