Solving A Common Issue With The Strategy Pattern // In Python

  Рет қаралды 47,644

ArjanCodes

ArjanCodes

Күн бұрын

Пікірлер: 126
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Here's an older video I did about the Strategy pattern: kzbin.info/www/bejne/jYKbk4Garbd4frc
@devilslide8463
@devilslide8463 3 жыл бұрын
You are giving most valuable materials on KZbin regarding programming. Thank you !
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Wow, thank you so much!
@digitig
@digitig 2 жыл бұрын
For O-O programming (especially Python, of course), absolutely. This is a great channel. For functional programming - Elm, Ocaml, F# - I have to do a bit more work. But the issues are pretty much the same even with that paradigm.
@ferchiew7027
@ferchiew7027 3 жыл бұрын
I came across one of your videos and I realized it was just what I needed. I'm 17, and code for fun as a hobby. I understand code, can code but can't code clean, I code with a lot of coupling (which I learned from you), probably due to the fact I have never followed a course. I've watched almost all of your videos in less than two weeks and you are helping me so much. I tried to implement the strategy pattern on one of my projects and came across with this issue where I needed different arguments for the same method in different implementations. I couldn't find a way to do it clean, and here it is. Just what I needed. Perfect timing. Thank you very much, you produce excellent videos with top quality and on top of that you have the ability to follow a logical learning path! I'm really grateful :)
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Glad to be of help! I started coding when I was 12 or 13 years old, it’s been a wonderful learning experience ever since!
@superscatboy
@superscatboy 3 жыл бұрын
I highly recommend watching any talks you can find given by Uncle Bob. They may not help on a specific technical level, but they''ll surely influence your philosophy of programming as a whole, and that's half the battle when it comes to writing clean code.
@althayrL
@althayrL 3 жыл бұрын
Thanks a lot Arjan! I'm a data scientist and started making the transition from crappy jupyter notebook, experimental code to production grade code about a year ago. Your videos on design patterns were the first ones to finally make these core software design concepts click in my head (SOLID, design patterns, ...).
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thank you, and glad to hear you find the videos helpful!
@karusster
@karusster 3 жыл бұрын
I love how much work/time you put into setting up these examples to make them realistic enough. It's so much easier to absorb theory when it's done in the context of solving an obvious, relatable problem.
@SiddiqNx
@SiddiqNx 3 жыл бұрын
I watch your videos even though I don't code a single line of Python. Because it's so easy to follow and I learn so much from your videos. Thank you for your efforts.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks so much! I’m happy you can see through the Python layer and still find some use out of the content.
@merlijn3578
@merlijn3578 3 жыл бұрын
Hi Arjan. When I came across your channel I though to myself, hmm, I recognize this guy. That's when I realised I followed your "Gameprogrammeren" course in my bachelor. Since then I've finished my master's in Software Engineering, and started working at a startup. Funnily enough, I'm going to the same teacher for a refresher on the advanced patterns, as the one who taught me to program. If that isn't going full circle, I don't know what is! Thanks for your educative content, keep up the great work!
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Hi Merlijn, will do and welcome back ;). Great to hear that you've finished your master in the mean time. Teaching that game programming course was one of the most enjoyable things I did at the university. I like talking about programming, and games provide a great basis for explaining things like OO programming.
@ozoniuss1463
@ozoniuss1463 3 жыл бұрын
I'm currently working on a project, and this video was exactly what I needed to structure a section properly. Your content is so great, keep it up!
@nijataliyev1470
@nijataliyev1470 3 жыл бұрын
This is absolute 100% useful, gold material you have created for the humanity Arjan. Not only material, you also took into consideration the question I asked in your discord channel and covered it here. I am extremely thankful to you Sensei.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thank you! And glad to hear it was helpful.
@GlobusTheGreat
@GlobusTheGreat 3 жыл бұрын
Hehe I've been doing some Entity Component System stuff where the whole idea is separating data from behavior, it's nice to have a reminder of what classes let us do: COMBINE data and behavior... because that actually makes sense sometimes (especially with strategy pattern!). Love it!
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks, glad you liked it!
@davidhall2698
@davidhall2698 3 жыл бұрын
I just came across this video while in my design pattern journey. This was exceptional, it compared other solutions and gave reasons why they were not as beneficial.
@SeanChitwood
@SeanChitwood 2 жыл бұрын
A little late to the game, but I really liked this. Showed potential pitfalls that I've seen when dealing with strategies. I might have used a factory to create the strategies rather than an initializer, then I could make the strategies Callables rather than classes. Each Callable returning a Recomendation that has a value of BUY, SELL or HOLD. But that is nitpicking the setup of the example rather than a difficulty with the information in the video.
@pinakadhara7650
@pinakadhara7650 Жыл бұрын
Amazing video! I went through this exact journey in a production grade project. You examples are very relevant to real world scenarios.
@ArjanCodes
@ArjanCodes Жыл бұрын
Thank you!
@mmihailicenko
@mmihailicenko 3 жыл бұрын
Wanted to ask if you considered to talk on the topic of test automation software architecture (page object model, etc)? Thank you for the quality content, it’s a gem of a channel ;)
@dankprole7884
@dankprole7884 Жыл бұрын
The other strategy pattern video made me realize I was already using it. This one showed me what I was doing wrong! 👍
@ArjanCodes
@ArjanCodes Жыл бұрын
Glad it helped! ❤
@PanduPoluan
@PanduPoluan Жыл бұрын
Ahhh this video now makes me understand what 'coupling' really is. Thanks!
@ArjanCodes
@ArjanCodes Жыл бұрын
Thanks so much Pandu, glad the content is helpful!
@XRay777
@XRay777 3 жыл бұрын
Looks like a combination of Command and Strategy to me. Fits pretty well with the use case. Good choice!
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks! And indeed, the Command and Strategy patterns are pretty close.
@anindyasundarmanna6683
@anindyasundarmanna6683 3 жыл бұрын
This is gold! Love your videos Arjan! Take care.
@ashleyspianoprogress1341
@ashleyspianoprogress1341 2 жыл бұрын
Great explanation. I'd love an entire series on design patterns.
@djl3009
@djl3009 3 жыл бұрын
Nice and clean solution -- especially helped by the convenience of dataclasses. Great stuff!
@charetjc
@charetjc 3 жыл бұрын
I love this format digging into the practical details behind the strategy pattern. I ran into unspoken issues with dependency inversion that turned me off to the whole concept. Will look at your dependency inversion videos next, and would love to find a video for "common" issues with dependency inversion and different ways to handle them. I suppose my biggest gripe with dependency inversion is given a chain of classes/objects where each subsequent object is a compositional part of the previous, I find the objects with outermost scope must create the dependent objects for its dependencies which introduces broader and tighter coupling than I had when objects only cared about their immediate dependencies. Now some object far removed must know about objects that form implementation details of a dependent object and a mess ensues.
@VanNguyen84
@VanNguyen84 3 жыл бұрын
Really nice to wake up on Sat morning to this. Thank you! Can I ask what VS code them you are using, it is so pleasant to look at..
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Glad you liked the video! I think this is actually the default VS code theme (at least I don't remember changing it, haha).
@sanjitdasgupta7148
@sanjitdasgupta7148 3 жыл бұрын
I'm glad I found this channel. This is a goldmine of information !
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Glad you like the content Sanjit!
@ramirotell
@ramirotell 2 жыл бұрын
This channel is pure gold! thanks for sharing with us this knowledge!
@ArjanCodes
@ArjanCodes 2 жыл бұрын
Thanks, glad you like the content!
@tobiasbergkvist4520
@tobiasbergkvist4520 3 жыл бұрын
Pure functions can also use data through closures - so it wouldn't really be a problem: def make_min_max_trading_strategy(min_price: float = 32000., max_price: float = 33000.): def should_buy(prices: list[float]) -> bool: return prices[-1] < min_price def should_sell(prices: list[float]) -> bool: return prices[-1] > max_price return { 'should_buy': should_buy, 'should_sell': should_sell } Returning a dict here might not be the best for type checking, but this is how you could do something like this using pure functions. And an upside here, is that all the input parameters to make_min_max_trading_strategy are actually inaccessible/opaque to the user of the strategy.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
That's a nice option, thanks for sharing, Tobias! I must admit I haven't look that closely at closures in Python until now, though I do regularly use them when I write code in Typescript.
@astronemir
@astronemir 2 жыл бұрын
At this point you're using a class with less accessibility, why? It's not very pythonic to make options inaccessible. And they are accessible, just in a more cumbersome way.
@thichquang1011
@thichquang1011 3 жыл бұрын
In the first two examples the should_{buy,sell} methods should be static methods (self unused), so basically just using classes as modules, so the issue could have been spotted from there also. I think that this kind of issue comes with the fact that your workflow is to go with classes from the very start. Another approach is to go with the main function, put parameters at the top, let patterns emerge and then refactor into classes ; that way I feel like I can better predict where parameters should go at refactoring time not to introduce coupling, but I also often fail though ^^ Btw, great content as always, thank you
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks! The reason I'm sticking to classes is because I want to follow the definition of the original design pattern as closely as possible. I'm working on several video ideas at the moment to explore other ways of achieving the same thing as these patterns do, but with more Pythonic concepts.
@thichquang1011
@thichquang1011 3 жыл бұрын
@@ArjanCodes That would be great indeed, very much looking forward those videos ! And yes I just realized that in those design patterns videos the python language is a secondary thing, and it might be better like this as I even saw someone commenting about watching this without having any python knowledge
@Phate777
@Phate777 3 жыл бұрын
Good video as always. Also I really like that you keep repeating what patterns you use. In that way it is way easier to remember them
@cetilly
@cetilly 3 жыл бұрын
Really, really loved this topic. Particularly funny to see your dismay over BTC.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks Chuck!
@ajitk100
@ajitk100 3 жыл бұрын
Your examples are good but would be a good idea to show in UML what all classes and files your example has. A pictorial representation is easier to remember and one will understand your code much better
@lukanya3124
@lukanya3124 3 жыл бұрын
Hey Arjan, I have a request. Could you make a video about advanced logging sometime please? Your videos have thought me the most of all the programming tutorials I have watched up until now. Alvast bedankt!
@VincentSaelzler
@VincentSaelzler Жыл бұрын
Super clean solution!
@ironosenshicas
@ironosenshicas 3 жыл бұрын
I watched your video on while loops and I disagreed with your opinion. But I am glad I kept watching because your other video's are really good. I don't even use python as my main language but the principles cary over to other languages.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Fair enough - the while-loop video contains a few too many inaccuracies, live and learn I guess. I might have a go at it again in the future.
@presstv
@presstv 2 жыл бұрын
Amazing video. I enjoyed it Arjan🙂👍
@ArjanCodes
@ArjanCodes 2 жыл бұрын
Glad you liked it, Iraj!
@markusjohansson4949
@markusjohansson4949 3 жыл бұрын
I guess one could also use partial application (for example by using functools->partial) and pass functions around with certain parameters fixed when they are fed from the main function to the Tradingbot.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Yes, that’s also a good option. I haven’t looked into it in detail, but if you want to add proper typing to this, this might be cumbersome (I’m not a fan of Callable…).
@rogertunnell5764
@rogertunnell5764 3 жыл бұрын
@@ArjanCodes I'll start by saying I prefer your OOP approach, but I'm trying to become more adept at functional programming so here's a run at it. I'm not a fan of callable either, especially with complex or numerous arguments. In these cases I create a class that inherits from Protocol and define the __call__ method using the expected type signature. (Way more DRY than re-writing long Callable type hints every time a function is passed as an arg) Then use the Protocol subclass as your type annotation in the composite. from typing import Protocol from functools import partial class PriceDependent(Protocol): def __call__(prices: list[float]) -> bool: """callable that depends on prices ex. should_buy, should_sell""" def min_max_should_buy(min_price: float, max_price: float, prices: list[float]) -> bool: #price logic here return True def min_max_should_buy(min_price: float, max_price: float, prices: list[float]) -> bool: #price logic here return False def min_max_strategy(min_price: float, max_price: float) -> Tuple[PriceDependent, PriceDependent]: def should_buy(prices: list[float]): return functools.partial(min_max_should_buy, min_price, max_price) def should_sell(prices: list[float]): return functools.partial(min_max_should_sell, min_price, max_price) return should_buy, should_sell class TradingBot(exchange: Exchange, should_buy: PriceDependent, should_sell: PriceDependent): """Do trading bot stuff. Not re-implementing for brevity, same for exchange""" def main(): exchange = Exchange() exchange.connect() min_price = 32_000.00 max_price = 34_000.00 should_buy, should_sell = min_max_strategy(min_price, max_price) trading_bot = TradingBot(exchange, should_buy, should_sell) trading_bot.run('BTC/USD)
@guyindisguise
@guyindisguise 3 жыл бұрын
​@@rogertunnell5764 You defined `min_max_should_buy` twice, I guess one of them should be `should_sell` instead of `should_buy`. Thanks to your solution I learned about typing.Protocol :) Pretty neat solution, is that how data and behaviour is coupled in FP in general?
@indra0704
@indra0704 Жыл бұрын
Nice example!
@ArjanCodes
@ArjanCodes Жыл бұрын
Thanks! 😃
@MrSpikegee
@MrSpikegee 3 жыл бұрын
Thanks that was simple yet entertaining
@ArjanCodes
@ArjanCodes 3 жыл бұрын
You’re most welcome!
@robertbrummayer4908
@robertbrummayer4908 3 жыл бұрын
Hey Arjan, once again an excellent video. Great job!
@minhajabidin
@minhajabidin 3 жыл бұрын
Amazing content especially how you make why and when clear.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thank you!
@davidoh6342
@davidoh6342 2 жыл бұрын
Ah! This is so beautiful! I have one follow up question. What if all the parameters have common & enforced method. Like, param_to_string_json in order to get a deserialized version of the parameters to output somewhere or put it as a column in a table? In that case, using the initializer might not be very helpful but the second option of creating parameter classes that inherit from abstract parent class with the param_to_string_json might be better?
@fierce1340
@fierce1340 3 жыл бұрын
Still loving these videos! Keep em coming!
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks! Will do!
@gustavorangel729
@gustavorangel729 3 жыл бұрын
Is there a reason for why you transformed the strategies into dataclasses instead of just adding the __init__ method?
@ArjanCodes
@ArjanCodes 3 жыл бұрын
I find dataclasses in general a bit simpler to use than regular classes. In particular, I find defining attributes and default values easier with a dataclass.
@GlobusTheGreat
@GlobusTheGreat 3 жыл бұрын
It's functionally very similar, sounds like it just feels easier to type
@CarlDoesEverything
@CarlDoesEverything 3 жыл бұрын
Data classes help a ton with readability as well
@XRay777
@XRay777 3 жыл бұрын
It saves you some code duplication, since you don't have to write all the init arguments and then asssign them to attributes of the same name. Also you get comparison and repr for free. This is prettey much exactly the case which dataclasses are intended for, i.e. a class that mostly holds data and does not do any complicated setup.
@annaseyfert4541
@annaseyfert4541 3 жыл бұрын
Hi Arjan! Awesome video! I just have one question around 4:00 you mention that the bot when changing to the other currency will act weirdly because the min max values are bitcoin, did your third implementation solve this problem? If not would you suggest to implement min max values per currency? But then you are coppled to the Trading Bot class no? Anyway awesome video!
@pellegoeg
@pellegoeg 3 жыл бұрын
Thank you for another great video :-) In your first example @ 5:36 you are creating window_size as an float, but you are using window_size for slicing your price list? For slicing you should use int, unless you want a type error :-)
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks! Correct - it should be an int. This is also one of the problems with the kwargs approach: you have little control over the type or the arguments. Actually, when I ran this code, it does work, but I guess if you try a window_size of 2.5 or something, it will fail.
@JelleWolbers
@JelleWolbers 3 жыл бұрын
Makes perfect sense, thanks Arjan!
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thanks Jelle, glad you liked it!
@Tekay37
@Tekay37 2 жыл бұрын
Rule #1 of the Trading Club: Don't model money as a float. Rule #2 of the Trading Club: DO NOT model money as a float. Thanks for coming to my TED Talk.
@ArjanCodes
@ArjanCodes 2 жыл бұрын
Yep. In more recent videos, I'm using integers.
@AlejandroLamKhoa
@AlejandroLamKhoa 3 жыл бұрын
I hope that you’d do a video on UML one day
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Thank you for the suggestion!
@maxwell2201
@maxwell2201 Жыл бұрын
Do you have any suggestions on how to solve this problem when using the functional strategy pattern you have shared in some of your other videos??
@plankton383
@plankton383 3 жыл бұрын
Great content, thank you!
@manofqwerty
@manofqwerty 3 жыл бұрын
Does anyone know which video Arjan did where he created a program that created unique IDs and could be plugged into multiple interfaces? I believe he used a TKInter and command line interface.
@giovanifarias2493
@giovanifarias2493 2 жыл бұрын
Thanks man!
@ArjanCodes
@ArjanCodes 2 жыл бұрын
Thanks Giovani, happy you’re enjoying the content!
@mattduffyw99
@mattduffyw99 3 жыл бұрын
I'm just here for the R.E.M. easter eggs
@sushantrocks
@sushantrocks 2 жыл бұрын
I'd go with a predicate function as an argument.
@mishikookropiridze
@mishikookropiridze 3 жыл бұрын
Third options feels trivial & intuitive, any drawbacks? i guess first and second solution is go to when we have strategies as functions instead of classes.
@ArjanCodes
@ArjanCodes 3 жыл бұрын
One of the drawbacks of the third solution is that it complicates things if you need to create the strategy instances in a generic way, for example if you want to dynamically load these as plugins and you have no knowledge of the kinds of parameters that should be passed.
@mishikookropiridze
@mishikookropiridze 3 жыл бұрын
@@ArjanCodes I see, thanks for the reply(es), enjoying the content
@directrix1
@directrix1 3 жыл бұрын
I mean it's pretty simple functionally with closures
@asdfghjkl36958
@asdfghjkl36958 3 жыл бұрын
Make sure you don't give away too many spoilers for future videos from the wip folder in VSCode ;)
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Haha, well spotted :)
@kinematics7092
@kinematics7092 3 жыл бұрын
Another data scientist learning, thanks for your video! I have a question about config files and wrappers though. We use a lot of spark and there's an instinct to make things reusable, but what do you do when there's so many options to set for a single object (some objects can have 10-20 parameters to set). I'm currently playing around with something similar to strategy pattern, but the final objects feel really heavy.
@MellexLabs
@MellexLabs 3 жыл бұрын
Could you use the strategy pattern with the factory pattern? I mean I am visualizing that the factory methods could receive a config string from a file for a particular strategy and the parameters can be encoded in that string. All the factory has to do is return a strategy you want when passed a config and the strategy object is initialized and passed back to the caller code... does thats sound right? I think in that way the strategy is not coupled to the config but the factory handles all the config for you...
@johngibson4874
@johngibson4874 3 жыл бұрын
That sounds reasonable to me. Create a strategy with specific parameters based on a config file. You could even use json in the config file to make it easier to read and process
@MellexLabs
@MellexLabs 3 жыл бұрын
@@johngibson4874 Yeah the JSON file was what I had in mind...
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Another example where you can imagine using the two together is in a data processing application. You could use the factory to produce different kinds of data loader objects and then inject various strategies for processing that data in some way.
@fackarov9412
@fackarov9412 2 жыл бұрын
ty
@tobb10001
@tobb10001 3 жыл бұрын
To me it seemed like a Factory Pattern would have cleaned up the code even more. What do you think?
@ArjanCodes
@ArjanCodes 3 жыл бұрын
You mean a factory pattern to create the trading strategy objects? I didn't do that here because I wanted to keep the example focused on the strategy pattern, but yes, that could definitely work.
@tobb10001
@tobb10001 3 жыл бұрын
@@ArjanCodes exactly. Yes, I agree. But I'm glad I was able to recognise an application for it. 👍🏽
@vincentsolus9227
@vincentsolus9227 3 жыл бұрын
I mean, it just seen the logical way to do it, i was expecting something more hahaha Having to pass it al the times you can just sounds a really weird sollution
@kurdmanpar5706
@kurdmanpar5706 2 жыл бұрын
Hello. Thanks for your good video. How can I run this program on Python version 3.8 in Windows 7 ?
@astronemir
@astronemir 2 жыл бұрын
You can't; update to python 3.10
@johnabrossimow
@johnabrossimow Жыл бұрын
strategy parameters monster lol
@GuRuGeorge03
@GuRuGeorge03 3 жыл бұрын
@bocckoka
@bocckoka 3 жыл бұрын
you need to be careful to not use a language without proper algebraic datatypes. then this problem magically goes away
@ArjanCodes
@ArjanCodes 3 жыл бұрын
Possibly, but the goal of this channel is to help people who develop in Python, so I’ll have to make do with what the language offers.
@GlobusTheGreat
@GlobusTheGreat 3 жыл бұрын
Care to briefly explain?
@zhalie12345
@zhalie12345 2 жыл бұрын
Hello Arjan, a question if u don't mind. I see that AvgTradingStrat and MinMaxTradingStrat use @dataclass, and TradingBot use __init__. Is there any difference between using @dataclass and python class __init__?
Why the Plugin Architecture Gives You CRAZY Flexibility
24:06
ArjanCodes
Рет қаралды 113 М.
How to Implement the Strategy Design Pattern in Python
27:20
ArjanCodes
Рет қаралды 53 М.
Каха и лужа  #непосредственнокаха
00:15
버블티로 부자 구별하는법4
00:11
진영민yeongmin
Рет қаралды 29 МЛН
What is the Strategy Pattern? (Software Design Patterns)
13:18
Be A Better Dev
Рет қаралды 58 М.
5 Tips For Object-Oriented Programming Done Well - In Python
16:08
Protocol Or ABC In Python - When to Use Which One?
23:45
ArjanCodes
Рет қаралды 204 М.
Let's Take The Adapter Design Pattern To The Next Level
22:45
ArjanCodes
Рет қаралды 50 М.
Composition Is Better Than Inheritance in Python
23:29
ArjanCodes
Рет қаралды 261 М.
How principled coders outperform the competition
11:11
Coderized
Рет қаралды 1,7 МЛН
This Is Why Python Data Classes Are Awesome
22:19
ArjanCodes
Рет қаралды 812 М.
8 Python Coding Tips - From The Google Python Style Guide
17:12
ArjanCodes
Рет қаралды 159 М.
7 Python Code Smells to AVOID at All Costs
22:10
ArjanCodes
Рет қаралды 374 М.