Here's an older video I did about the Strategy pattern: kzbin.info/www/bejne/jYKbk4Garbd4frc
@devilslide84633 жыл бұрын
You are giving most valuable materials on KZbin regarding programming. Thank you !
@ArjanCodes3 жыл бұрын
Wow, thank you so much!
@digitig2 жыл бұрын
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.
@ferchiew70273 жыл бұрын
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 :)
@ArjanCodes3 жыл бұрын
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!
@superscatboy3 жыл бұрын
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.
@althayrL3 жыл бұрын
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, ...).
@ArjanCodes3 жыл бұрын
Thank you, and glad to hear you find the videos helpful!
@karusster3 жыл бұрын
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.
@SiddiqNx3 жыл бұрын
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.
@ArjanCodes3 жыл бұрын
Thanks so much! I’m happy you can see through the Python layer and still find some use out of the content.
@merlijn35783 жыл бұрын
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!
@ArjanCodes3 жыл бұрын
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.
@ozoniuss14633 жыл бұрын
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!
@nijataliyev14703 жыл бұрын
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.
@ArjanCodes3 жыл бұрын
Thank you! And glad to hear it was helpful.
@GlobusTheGreat3 жыл бұрын
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!
@ArjanCodes3 жыл бұрын
Thanks, glad you liked it!
@davidhall26983 жыл бұрын
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.
@SeanChitwood2 жыл бұрын
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 Жыл бұрын
Amazing video! I went through this exact journey in a production grade project. You examples are very relevant to real world scenarios.
@ArjanCodes Жыл бұрын
Thank you!
@mmihailicenko3 жыл бұрын
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 Жыл бұрын
The other strategy pattern video made me realize I was already using it. This one showed me what I was doing wrong! 👍
@ArjanCodes Жыл бұрын
Glad it helped! ❤
@PanduPoluan Жыл бұрын
Ahhh this video now makes me understand what 'coupling' really is. Thanks!
@ArjanCodes Жыл бұрын
Thanks so much Pandu, glad the content is helpful!
@XRay7773 жыл бұрын
Looks like a combination of Command and Strategy to me. Fits pretty well with the use case. Good choice!
@ArjanCodes3 жыл бұрын
Thanks! And indeed, the Command and Strategy patterns are pretty close.
@anindyasundarmanna66833 жыл бұрын
This is gold! Love your videos Arjan! Take care.
@ashleyspianoprogress13412 жыл бұрын
Great explanation. I'd love an entire series on design patterns.
@djl30093 жыл бұрын
Nice and clean solution -- especially helped by the convenience of dataclasses. Great stuff!
@charetjc3 жыл бұрын
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.
@VanNguyen843 жыл бұрын
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..
@ArjanCodes3 жыл бұрын
Glad you liked the video! I think this is actually the default VS code theme (at least I don't remember changing it, haha).
@sanjitdasgupta71483 жыл бұрын
I'm glad I found this channel. This is a goldmine of information !
@ArjanCodes3 жыл бұрын
Glad you like the content Sanjit!
@ramirotell2 жыл бұрын
This channel is pure gold! thanks for sharing with us this knowledge!
@ArjanCodes2 жыл бұрын
Thanks, glad you like the content!
@tobiasbergkvist45203 жыл бұрын
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.
@ArjanCodes3 жыл бұрын
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.
@astronemir2 жыл бұрын
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.
@thichquang10113 жыл бұрын
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
@ArjanCodes3 жыл бұрын
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.
@thichquang10113 жыл бұрын
@@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
@Phate7773 жыл бұрын
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
@cetilly3 жыл бұрын
Really, really loved this topic. Particularly funny to see your dismay over BTC.
@ArjanCodes3 жыл бұрын
Thanks Chuck!
@ajitk1003 жыл бұрын
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
@lukanya31243 жыл бұрын
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 Жыл бұрын
Super clean solution!
@ironosenshicas3 жыл бұрын
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.
@ArjanCodes3 жыл бұрын
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.
@presstv2 жыл бұрын
Amazing video. I enjoyed it Arjan🙂👍
@ArjanCodes2 жыл бұрын
Glad you liked it, Iraj!
@markusjohansson49493 жыл бұрын
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.
@ArjanCodes3 жыл бұрын
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…).
@rogertunnell57643 жыл бұрын
@@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)
@guyindisguise3 жыл бұрын
@@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 Жыл бұрын
Nice example!
@ArjanCodes Жыл бұрын
Thanks! 😃
@MrSpikegee3 жыл бұрын
Thanks that was simple yet entertaining
@ArjanCodes3 жыл бұрын
You’re most welcome!
@robertbrummayer49083 жыл бұрын
Hey Arjan, once again an excellent video. Great job!
@minhajabidin3 жыл бұрын
Amazing content especially how you make why and when clear.
@ArjanCodes3 жыл бұрын
Thank you!
@davidoh63422 жыл бұрын
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?
@fierce13403 жыл бұрын
Still loving these videos! Keep em coming!
@ArjanCodes3 жыл бұрын
Thanks! Will do!
@gustavorangel7293 жыл бұрын
Is there a reason for why you transformed the strategies into dataclasses instead of just adding the __init__ method?
@ArjanCodes3 жыл бұрын
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.
@GlobusTheGreat3 жыл бұрын
It's functionally very similar, sounds like it just feels easier to type
@CarlDoesEverything3 жыл бұрын
Data classes help a ton with readability as well
@XRay7773 жыл бұрын
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.
@annaseyfert45413 жыл бұрын
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!
@pellegoeg3 жыл бұрын
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 :-)
@ArjanCodes3 жыл бұрын
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.
@JelleWolbers3 жыл бұрын
Makes perfect sense, thanks Arjan!
@ArjanCodes3 жыл бұрын
Thanks Jelle, glad you liked it!
@Tekay372 жыл бұрын
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.
@ArjanCodes2 жыл бұрын
Yep. In more recent videos, I'm using integers.
@AlejandroLamKhoa3 жыл бұрын
I hope that you’d do a video on UML one day
@ArjanCodes3 жыл бұрын
Thank you for the suggestion!
@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??
@plankton3833 жыл бұрын
Great content, thank you!
@manofqwerty3 жыл бұрын
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.
@giovanifarias24932 жыл бұрын
Thanks man!
@ArjanCodes2 жыл бұрын
Thanks Giovani, happy you’re enjoying the content!
@mattduffyw993 жыл бұрын
I'm just here for the R.E.M. easter eggs
@sushantrocks2 жыл бұрын
I'd go with a predicate function as an argument.
@mishikookropiridze3 жыл бұрын
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.
@ArjanCodes3 жыл бұрын
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.
@mishikookropiridze3 жыл бұрын
@@ArjanCodes I see, thanks for the reply(es), enjoying the content
@directrix13 жыл бұрын
I mean it's pretty simple functionally with closures
@asdfghjkl369583 жыл бұрын
Make sure you don't give away too many spoilers for future videos from the wip folder in VSCode ;)
@ArjanCodes3 жыл бұрын
Haha, well spotted :)
@kinematics70923 жыл бұрын
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.
@MellexLabs3 жыл бұрын
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...
@johngibson48743 жыл бұрын
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
@MellexLabs3 жыл бұрын
@@johngibson4874 Yeah the JSON file was what I had in mind...
@ArjanCodes3 жыл бұрын
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.
@fackarov94122 жыл бұрын
ty
@tobb100013 жыл бұрын
To me it seemed like a Factory Pattern would have cleaned up the code even more. What do you think?
@ArjanCodes3 жыл бұрын
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.
@tobb100013 жыл бұрын
@@ArjanCodes exactly. Yes, I agree. But I'm glad I was able to recognise an application for it. 👍🏽
@vincentsolus92273 жыл бұрын
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
@kurdmanpar57062 жыл бұрын
Hello. Thanks for your good video. How can I run this program on Python version 3.8 in Windows 7 ?
@astronemir2 жыл бұрын
You can't; update to python 3.10
@johnabrossimow Жыл бұрын
strategy parameters monster lol
@GuRuGeorge033 жыл бұрын
@bocckoka3 жыл бұрын
you need to be careful to not use a language without proper algebraic datatypes. then this problem magically goes away
@ArjanCodes3 жыл бұрын
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.
@GlobusTheGreat3 жыл бұрын
Care to briefly explain?
@zhalie123452 жыл бұрын
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__?