Tom here from Warrant Systems and we're going to cover port forwarding on PF Sense Plus 2205 or PF Sense Community Edition 2.6 as the latest versions that are available here in August of 2022. Now, this is just some basic port forwarding we're going to cover, but I also talk a little bit about the security that you should be considering when you're doing this. So we will show also how to do some port forwarding, restricting how to handle it with multiple WAN addresses, how to set up aliases to make port forwarding easier for either aliases on inbound or aliases on the ports, or why not both? Those are all things that are great options you can do in there. I'll even show a couple advanced use cases for port forwarding, but I always want people to think about and consider that before you open something up to the world, and by the way, a prerequisite for this to work on the public internet is for your WAN to have a public one or more public available IP addresses. So before you open something up to the world, really think about whether or not that's a good idea first, because this is often, well, how many attacks occur is people look for open ports or bots, I would say automatically look for them. So the moment you open a port, yes, lots of things start poking away at it, be prepared for that to happen. Hopefully you are secure and can mitigate any problems that may arise from it. Just want to throw out those warning and be in the video. Now, before we dive into the details of video, let's first, are you an individual or company looking for support on a network engineering storage or virtualization project? Is your company or internal IT team looking for someone to proactively monitor your system security or offer strategic guidance to keep your IT systems operating smoothly? Not only would we love to help consulting your project, we also offer fully managed or co-managed IT service plans for businesses in need of IT administration or IT teams in need of additional support. With our expert install team, we can also assist you with all of your structure cabling and Wi-Fi planning projects. If any of this piques your interest, fill out our Hire Us form at laurancesystems.com so we can start crafting a solution that works for you. If you're not interested in Hire Us but you're looking for other ways you want to support this channel, there's affiliate links down below to get your deals and discounts on products and services we talk about on this channel. And now back to our content. All right, now the first place I want to start is to cover the IP addresses we're going to use. This is a simulated lab that I have set up, so none of these are actually WAN public IP addresses, but they're the ones we're going to use for this demo. And we have my computer at 172.16.69, coming across the pseudo internet over to PF Sense Lab. Now I've got two IP addresses assigned to this lab because this is a frequent port forward question that comes up when you have a single WAN interface and you want to choose which one to port forward to. This can be tricky, especially when you're aliasing IP addresses, people are like, but how do I get the other one? I only see one address option and I'll make sure we cover that in a video. So we're going to have this assigned on the WAN side, 2.17 and 2.50. So this is a 192.1683 network with these two IP addresses. And the target is being able to SSH and maybe test a few other ports and get into this Ubuntu lab server that is <IP_ADDRESS>. So these are all the IP addresses we're going to use for this particular demo. Now in PF Sense, go to firewall then NAT. And that's where you're going to be able to get to the NAT port forwarding options. There are options here. We're not going to cover today. It's in the documentation. If you wanted to do a one-to-one map where you just take everything from a particular IP address and map it to another device, I find that, well, less secure generally. I really want you to think about principles of least privilege and you only open up what's necessary to who it's necessary to be opened up for end of story. That to me reduces the amount of noise you're going to see, reduces the amount of potential problems you're going to have. So we're going to go here and we're going to go ahead and click add. And we're going to do it put forward by saying interface WAN. And even we have a few interfaces, we're going to start with WAN on this one, address family IPv4, TCP. And there are other options you can do. You got UDP, you have TCP, UDP as a combo, ICMP, GRE, et cetera, et cetera. SSH is a TCP based protocol. So we're going to use that. Now there's two options over here. We can say destination and WAN address we're going to leave here, but we can choose SSH if we wanted to make it really simple and say, just go SSH. Or you could just type in the port number. Once you choose one of the hold on options, remove support number. Also we'll go ahead and leave it as other 22, 22. Now the way ranges work in there. And it's sometimes be a little bit confusing because I can say 22 to, let's say 28. Now we're going to actually forward four parts. We're not going to actually do this. But then they see over here, there's only one on the redirect target port. Now the reason there's only one is because that's the starting range on the target port. So if we have these six more ports that we're going over here, well, it'll start here and forward them over. So you actually don't get a range on the redirected port on the device you're targeting. But now we'll go ahead and <IP_ADDRESS>. And we'll just leave this at 22, because we're just getting SSH working. We'll say allow SSH down here, net reflection, use system default. There are a couple different options for net reflection. And you can go into defaults and change these. You can enable net proxy, pure net or disable. What net reflection means is how does this behave when you're inside the network? This is very popular with camera systems where you want to open up a port for camera system. But then you go, Hey, it's not working when I'm inside the network, because I'm still hitting this, you know, public WAN IP address I programmed into the app. But now when it's inside the network, it doesn't redirect. What this does is it redirects you. So it says no, reflect it inward. So even though something's inside the network, let it go ahead and route through the rules and come back. I have mine set up system default because I have it set up for the pure net on there. And if you'd like to set that you go under system advanced firewall net and choose net reflection to pure net. That is where you set the system default. It's in the documentation for PF Sense as well. Now the last option here is add associated filter rule. This is where some firewalls in modern times can annoy me where they don't create a separate rule because yes, there is a separate rule needed. PF Sense has added this for your convenience. The net operation is separate from your firewall rules. That is a fact. And someone will go, of course it works that way. If you're used to using firewalls where you create a net rule, and then you also have to create a rule to allow the traffic to come into the firewall. PF Sense as a convenience does this in one click. So we hit save, we click apply and the associated filter rule will go ahead and edit here. We'll go down and here is view the filter rule, which also are going over to firewall rules at it. So it comes over here and you're seeing where we're allowing a firewall net allow SSH is creating that separate rule. If we go just over to rules and we look at the WAN rules, ignore all the extras on here there for different things we're testing. But you'll see this bottom one that we just added net to allow SSH. So it's adding that filter rule automatically because you have to allow in on WAN. And then when that packet comes in and hits that port, it hits the net rules and redirects to the destination we set up in that. So back here where we have our port forward rule created, I just have a tab open over here because I'm doing a PF top diagnostic where I say host, here's our host address, I want to see anything that's connecting to this address. Currently there are no connections. So let's go ahead and create some and make sure our port forward works. Now referencing back to our diagram, LTS at 192.1683.217, the WAN IP address of our demo firewall. And it works. And if we look over here, we see that, Hey, I just logged into a box that has an IP address of 10, 00, 100, perfect, worked exactly as expected. And we can see these connections established. Now one of the things I want to point out when we establish these connections. So here is my IP address. And the thing to note is that the destination port was 22. And you may have noticed that the source port is something different. So we have 45674 source ports are generated randomly from the outgoing firewalls through the internet, and they land on a specific port. So they may come in indiscriminately. That's why when you're looking at these net rules, and I've seen people sometimes break things like this, you want to limit your source address, but listening limiting a source port requires, well, a little bit of extra because you have to make sure it's only coming from that port. So generally your source port, you're always going to leave, you know, wild carded as an asterisk here, source address is the next thing I want to talk about. Because one of the important things to think when you're doing this is like, well, anyone can now hit this port, it's wide open. This is where you may want to limit your source addresses the way you do that. We're going to go over here to edit, and you look at display advanced. And what is the network we want this to come in on. And you can say any or single host or alias single host is one single host that you want to filter this for. So if we say we can only come in from 3.12 for any other IP address, that would limit the scope to only that IP address and coming in more ideally, we would want to do it this way. So we go here to firewall aliases. And we want to add an IP aliases, hit add allowed in SSH IP address, we'll paste it in there. What's the address we want to allow? Well, we allow my computer in 172 1616 9 times computer. So we're going to add another one. And we'll say what if we wanted to have it from one another computer. Now we've added well as many as we want as we keep clicking add to be able to add these in here. And then we click save. Click apply firewall, Nat, we're going to edit that rule. And we're going to display advanced single host or alias to start typing it will autocomplete go down here to save apply changes. And if we mouse over now the source address instead of displaying one value displays all the values in here. So if we go over here and SSH in, we exit, it works great. So we can go back and forth and say now it's working. Now let's go ahead and update that aliases to show you another condition you may run into, we're going to edit this, we're going to delete Tom, save, apply. No problem, we've got this address rule, let's go ahead and refresh this page. We only allow this particular one in. So we go back over to PF top. And we see a couple connections here from Tom. So let's talk about those connections because they shouldn't exist right now because I have to rule that says Tom can't get in. So it happens. So right now I'm in. I can type top and commands seem to be working. Let's go ahead and exit and see what happens. We've just closed that active state, we're going to jump back in, but we can't. What happens is when you change a rule, but there's already an open state, the default behavior, this can be changed or you can kill the state, the default behavior is to allow states that exist to keep existing. So if you're doing some testing with this and you have an active state open, such as an SSH connection, even though I change the rules, they're not going to just drop off. So now I can't come in. It's not allowing me, but we can go over here, firewall aliases, edit this. We'll add host. I'm dot nine. Save, apply, retry again. Hey, look, I'm in, it works perfectly fine again. So that's how those work in terms of aliases. Now you can use aliases for things like ports. So let's go ahead and look at the net rules here. We want to add another net rule. WAN IPT before TCP. But what if we had a list of custom ports like this, like the Unify controller, there's a popular grouping of ports. And we'll just put that in there for each one of these single hosts, the same post, it's not actually Unify controller, but let's pretend it is for sake of something popular, someone may want to do. Same thing, whether ports Unify controller allow Unify ports. Great. Now we have these ports over here for the Unify controller works the same way. Now, how do we do those? There's over here in alias, we go to ports. Hey, there's all the ports for the Unify controller. Now the other advantage is, of course, I have one, two, three, four different ports in there. What if I needed to change one of these and I had many rules related to port forwarding for a couple of different reasons where, you know, I needed to add or remove a specific port. I could just keep adding or removing them right inside of here. And it's as easy as that to keep control over, you know, things that you want to open up. So it works while they're using IP addresses, it works with these different ports added in here. And I actually, when you have a lot of things you're forwarding, I do prefer to add them all in here. That way as you repeat rules, it just makes a lot easier. And whenever you edit it here, it will automatically apply. That's why when you edit these, it asks you and let's just go ahead and open one up real quick. We added a port, whatever that port is, test, save. When you hit apply here, it's not just applying the alias, it actually is rerunning the filter rules in the background and reapplying them. That way they've all been reworked because they realize there was a change in alias. This alias is used within filter rules. So it actually reloads all the filter rules when you do that. Now let's go back over here to the firewall, and we're going to go ahead and delete this one as we don't need it. But the next question is, how do we build a rule when we have another IP address in our WAN? Now this is going to be obvious if you go here and say, Hey, I can just choose WAN two if it exists. But this at the top says interface. I want to make sure you understand interface is not the same as destination, because destination is WAN address, or WAN two address sounds pretty simple enough. But what about when you have more than one IP address on your WAN? And the way you do that, and I've done talked about this for but just a quick briefer here is you go over here to virtual IPs. We have an extra virtual IP assigned to WAN. It's an IP alias single address. So it's assigned to this interface. And there's the IP address. And it's just another WAN IP. We're going to go back over here to our firewall NAT. And we'll duplicate this rule for simplicity. So interface is the same because it's aliased on that interface. This is where we want to get to the other IP address. And we can add three, five doesn't really matter how many we have. We just have one on here. They would all show up in this list. So <IP_ADDRESS>. Now, we're going to hit save or not apply. So it's sitting here ready, but not applied. Now I want to show you what happens here. So we're going to go ahead and exit this. Then we're going to go ahead and say 250, the other IP address in there. It doesn't work. Just want to make sure despite there being a rule that allows it for the WAN and just generically worded WAN address, even though this is an alias to the WAN, it's not the WAN address. That's an important distinction. So it doesn't automatically work. So we click apply. Now we can see these two different rules, the WAN address, and then the secondary destination address on the WAN. There's the destination. There's the NAT IP internally. So now when we go back over here, logs us right in works perfectly fine. All right, I've deleted that rule. Now let's talk about another scenario. Our destination address being a WAN address, go ahead and click edit. We've deleted that extra one. So let's change it to WAN net as a destination. Now if we do WAN net as a destination, so it's interface WAN, but then WAN net. So everything that's aliased on the WAN net, let's go ahead and click apply. So we only have the one rule here. And if we do this, we go to 3.217. It works. We go to 3.250. It works. If we add more WAN addresses, more aliases, it will continue to work because we're just going on and saying anything that's on that WAN address, go ahead and just allow it to come through. This may not be an ideal situation that you want to do. But for those of you curious of, Hey, this will allow it for all the IP addresses, at least, and maybe your use case is for that, then yes, that will absolutely work. Now one final thing I want to cover that's kind of a novel, but just to show there's more than just ports that can be forwarded through net is ICMP. Maybe you don't have a use case for that, but I think it's novel that this is an ability that's in here is we can ping 192.1683.217, except by default PF sense blocks, ICMP traffic, that can be changed, but we left things at the default behavior. But what if, and we could go over here, and we want to add a rule and we want the WAN IPv4 protocol, though, let's change the protocol. And this is where the few different options we can even do. We have, like I said, these other ones in here, if you needed OSPF to be forwarded to another device, but let's specifically talk about ICMP. Now, there's obviously not as many options. You don't get ports. It's just ICMP traffic, but we can do that where we go 10.0 at 0.100. And we'll say allow ICMP. So pretty simple. Go ahead and hit save, apply. And the pings have started. And we'll go over here back to the PF top. And we can see the ICMP traffic down here coming from my system and going in there. So pretty simple. These are other things you can forward when you're using these. And that's it. That's all I have for port forwarding, but please take the time to read through the NetGate documentation. It is wonderful. It has even more than I covered in here. So there's always a lot of scenarios and maybe some specialized use cases that the scenarios can be helpful in there. Check out my forums, forums.laurencesystems.com for a more in-depth discussion on this topic and, well, any other videos I've covered or head over to the NetGate forums. There's all kinds of information over there on things like, you know, how port forwarding works or certain scenarios that are outside the norm. But what I covered today will cover probably 99% of people's needs when it comes to port forwarding. As always, thanks and see you next time. And thank you for making it all the way to the end of this video. If you've enjoyed the content, please give us a thumbs up. If you would like to see more content from this channel, hit the subscribe button and the bell icon. If you'd like to hire a short project, head over to laurencesystems.com and click the hires button right at the top. To help this channel out in other ways, there's a join button here for YouTube and a Patreon page where your support is greatly appreciated. For deals, discounts and offers, check out our affiliate links in the description of all of our videos, including a link to our shirt store where we have a wide variety of shirts that we sell and designs come out well randomly. So check back frequently. And finally, our forums. Forums.laurencesystems.com is where you can have a more in-depth discussion about this video and other tech topics covered on this channel. Thanks again for watching and look forward to hearing from you.


Okay, thank you very much for introducing me and the actual talk. So please be aware that this session was marked as an advanced, the red color was a warning. So it's a 4 p.m., great respect from my side to you that you made it. But just to be clear, I'll really keep explanations to introduction to PDD itself minimum. So I assume that you either heard about it, saw something or you practiced it. That's that kind of tag. Out of curiosity, who uses or uses or saw PDD in the past? Well, actually, I guess, if my math is right, around 30%, so it's not that bad. And the rest of you, well, not to say I'm sorry, but the second half of the talk should be more practical to you, even if you don't practically use PDD. Okay, so, but also for you, a very short introduction, PDD is like a technique, comes with a lot of libraries that let you describe the systems in this language called Gherkin, where at the top you name the feature and you have scenarios. And we'll be talking about examples in a system of subscription management, something like you can, Netflix is sold in that model or Amazon Prime and many other products, very popular these days because it makes up for the perfect customers who pay and don't use the service. Because you always forget to cancel the subscription. Yeah, so you have a scenario, it's described in several steps, like first given a user with expired retrial, when a user purchases monthly subscription, then purchases confirmed, and they can be upgraded to monthly subscription. And that way you describe how the system should behave, so to speak. And that's later mapped to code, that's why we need this fancy language, because it not only aims to be readable by Qman, but also parsable by computers, so it kind of serves both. And since we're in Python world, there are a couple of libraries to do that, Python's PDD, it's fork, Python's PDDNG or behave.  And also, often PDD is sold, so to speak, with testing techniques, while the reality is it's not about testing at all. It's only a byproduct that you get your automated verification, but PDD has a completely different goal, which I will shortly uncover. But you know, that's how marketing in general works, and there comes complexity of the reality. And this is a lovely city of which in Poland I came to you from. Yeah, so my name is Sebastian Buczynski, I work as a trainer consultant in Bottega IT Minds, I'm also tech lead at Source Labs, not to lose touch with reality. Everything I say to you today, this is something I use, not something I invented between one training or another, this is treated as a lessons learned mostly. And I have a little mission of evangelizing software engineering in Python, because you know, many stuff that we talk or rediscover in Python has already been solved in other programming languages, maybe we just need to adapt, we don't really have to go through all the bad experiences. And in my spare time, I experiment with coffee a bit. So, going back to PDD, let's break it down, and B stands for behavior, and we really need to first define what it actually is. And the simple definition I have is whatever is visible on the outside of the system or whatever the scope you're testing. If you guys looking for some empty seats, there are on the my left side on your right at the front. And an example of a behavior would be simply stating something that the user can see, maybe on another screen, maybe directly after direction, maybe in some report or whatever. So a classic example would be, how do we spec registration feature with username and password? And some people, like, tested via a database, this is not the behavior because user cannot look into database unless they can, but it's a different problem. So, a visible behavior a user can do after registration is to login with that username and password. So that's how we like specify behavior, what the user can do, how they can see. Other auxiliary questions are how it affects other features, is there something new action available to the user or maybe there's something they cannot do anymore. So in case of feature for a banning, let's say a login pattern is banned, the scenario, given a bus asterisk is banned. Whenever user registers as bus astral, which kind of fits the pattern, then registration attempt is rejected so they can see that they, hey, this failed. And as a result, bus astral cannot log in. So everything is visible from the outside of the system. And what's not a behavior? Definitely not assertions about records starting a database because it's not. It may be under some circumstances helpful to check this, but it's definitely not behavior. And another bad habit that happens when we try to test behaviors, not implementation is over so-called over specification. I will show you an example without explaining it a lot, it would be easier. So at the top, let's say like you fetch your users from external system. And I assume that you use mocks or have used them in the past. So at the top, like you said, whatever should be returned from this external system mock. But at the bottom, let's say you have two assertions. First one is about response. And let's say you can deduct from it's that the user data is there. And then you actually want to be extra secure, extra sure and double check this mock. You don't really have to. If it won, only one. But yeah, this is a simplified code. Definitely, it's not working. Yeah, so other two things not to do when checking behavior. Anything that's not part of the source to speak public API, because like behavior can be defined not only on user interface, but also like on the level of API. And whenever we specify behavior, like we should focus on what, not how, I will show you some more examples later. So this puts the first bullet point on our list how to do BDD is namely expected behavior. So something that is visible on the outside.  Like we're not interested what's inside, but we're more visible on the outputs. Yeah, so going to Gerkin. So like I said, this language is a bit tricky because it has two purposes. One of them is that humans should be able to read it. And this will be the main goal, focusing on that mostly. And the second is it should be parsable by computers. And as a result, we get something we call executable specification. So you can read it, it feels natural. I mean, I'm not a native language, native English speaker. So for me, it's not that awkward, but I suppose that for them it might be a bit. But it's a trade off. Nonetheless, if nobody gonna read the BDD specs you write that kind of defeats the purpose of having them. Maybe you need another approach. So if we compare like these two scenarios, it's simple that one of them is more readable than the other. I won't tell you which one, I guess you already know that. The second one on your right is actually has more problems with it, but I will get to them in a second. Yeah, so we want our scenarios to be nice, sweet, like the one on the left side that could be grasped, you know, without much effort. Because otherwise, again, it defeats the purpose because nobody would gonna read them. Yeah, so, but before we gonna jump into details how to write such specs, let's talk about development process in particular. So maybe let's start from recipes that actually work. So it's very nice if we can do it in a collaborative way. So there is a lightweight workshop called FreeAmigos when we have, for example, software developer, a tester and a project manager, or someone else from business or a stakeholder, and we work on them together on these examples, maybe using auxiliary techniques, like example mapping and so on and so forth. But the bottom line is that we don't do it solo. And another stuff that can work is pairing, for example, software developer working on a task and pairing with tester to help them work on the BDD scenarios. And if, for example, your stakeholders, your business is not available right to you, you can also review with them those specs later. That should also be fine because they will know, we agree or disagree with you, you could improve and so on. And why do we do that in a second? What definitely doesn't work is, for example, testers or QA departments working separately. And they are the only ones responsible for maintaining those. Nobody's reviewing that, that's not gonna work because they will just slide away from the system. And for example, developers don't have any incentive to make life easier for the testers. And on the same note, business analysts, for example, working before the team and just handing them out these scenarios also wouldn't work that much because, well, they have their understanding, but they may fail to convey just everything to the software developer. And now, this is because the main goal of BDD, and if there is only one thing that you take out from this presentation, let it be it, the goal is to building shared understanding between stakeholders and developers. Or for another note, any person that works or interacts with the system. If we lose that shared understanding, we actually have pretty big problem because there appears a gap between how people working on the system or how the system actually works and how I know business stakeholders or project managers thinks it works. So other symptoms are something should take little time according to project managers, but actually it takes months. That's because this gap occurs. So when this happens, you don't need BDD, you actually need this one. Yeah, or work hard on building that shared understanding. This is sometimes also called ubiquitous language, meaning omnipresent language that means that we all are on the same page. We use the same names. They are present in code, in specs, and in day-to-day conversations. So that's the actual goal of BDD. And about gherkin writing, the first piece of advice I can give you is to use realistic common scenarios. It's also worthy to test for some edge cases, but don't exaggerate. Maybe it's not the best way to put them into BDD specs. Actually, I worked with a pretty smart guy, Chris, in some time, and once he got his hands on BDD stuff, he was, whoa, I can now automate the way all my manual work of testing. But the result was that he wrote a lot of tests that took time to run, but brought no benefit, actually. So we deleted some of them, and also testers do have the appropriate skills to do so, because when I approached him and asked, hey, Chris, but when you are testing the system for regression before release, are you actually, no, we're executing all these scenarios? No, of course not. I'm smarter than this, I'm choosing the ones I'm executing. So you should do the same with BDD, because it takes effort and time to maintain and try those tests. The other thing is to rather be specific in your gherkin, avoid expressions like less than equal 10 or something like this, because if this is an executable specification, there is a word specific in a specification for a reason, like if someone reads that and doesn't quite get how it exactly works, it also defeats the purpose. And last, but I guess the most important, which always get people into trouble when they start with BDD, it put into spec only what matters, because we're tempted to put a lot of details as if we were writing code, but they all many times not relevant. So for example, let's say we have two specs. The first one is for authentication based on username and password, and the second one is on the banning users. You kind of already seen this one. So in the first case, when we spec the behavior, we use both username and password. These two pieces of information are relevant to understand the feature of authentication. But when we are specifying banning users, we actually don't need the password to describe the behavior. It's like irrelevant. Of course, we need to have some password between the hood, but we don't really have to put it in the spec because that's unnecessary. And what not to do? Definitely don't write scripts in Gherkin. This is script. Okay, this exactly like tells you what to do step by step, but it's hard to deduct how the system actually works. Yeah, so you rather be descriptive, declarative way, describe what the user can see, what they can do, what's possible, what's not, and not explain like a robot what to do step by step because it's not really helpful. So whenever you're tempted to do so, just don't. Because you are describing the feature using behavior and not trying to tell step by step what happens. So other piece of advice, don't get lost in UI details. Whether automating PDD on UI is a good idea. It's a bit different topic. We'll get to it in a second. And also don't try to make individual Gherkin steps generic and reusable as possible. So that's the case with this username and password. If you have a step already that says there's a user registered with username and this password and in other scenario like with this banning, you don't need this password bit, just do another step. You don't have to be careful about large number of them. The goal is readability. Also about reusing. So there was or there is still a feature in behave library that lets you execute steps like by just entering the string and you just name those steps and the behave will execute them. So back when I see it working with Chris, the same guy, we thought this was a pretty good idea. But the reality is that Gherkin is not meant to be reusable. So this was pretty dumb. We got a lot of issues. Connected with maintainability about it because for example, when you have Gherkin and for example, you use PyCharm, it has an integration that lets you jump from the definition of the steps to the Gherkin files and so into ways. And in this case, it's not even supported. So whenever we change something, a lot of tests that were doing execute steps crashed. So also like, don't try to reuse Gherkin because it's not the way how it was meant to be. So this puts a second point on our list, how to do BDD. Once we know the behavior which was expected, we need to capture it using Gherkin. And it's best to work it collaboratively, at least show it to other person to tell them what they think if they understand it the same way we do because it's meant to be read later. And if someone tries to read it but doesn't get the information on what was the point of this entire exercise, and we want to make specs short and simple specific to the point. So you might have an impression that the piece of advice so far was to basically keep it simple and everything will be okay. But getting too simple is not easy, especially if the system you have under the hood is complex. So we can describe it simply, but the complexity is there somewhere lurking. So that's how we need to manage. Like out of my experience, one guy I talked to on one training was said that, okay, yeah, we tried BDD, but quickly those scenarios become too long and too hard to maintain. Yes, exactly, because like you perhaps lacked some tools for your architecture weren't supporting it. So I will now show you some examples and how to actually make them simple from complex to simple. So let's say like we're building this software as a service platform for subscriptions, and within that we can like identify different clusters of features. So for example, we have something about users access management, this registration, password reminders and so on. Plans management, when you for example defined what can be bought, like there is monthly plan that is priced $10 and there is annual plan that sprites $100 and what benefits they bring and so on. Then you have subscriptions, which actually control let you subscribe to concrete plans and payments. And we could pretty much go on, like you know, identify those sub areas until we like get bored or tired. But it's very important to do so from a standpoint of another technique called domain-driven design, which means first look at the problem, the entirety of it, all the sub-problems you have and then use this information to make decisions about modularity, the scope of your tests and so on. You will see examples in a second. So in domain-driven design, these sub-areas are called sub-domains and the entirety of the knowledge that for example is required to work on this project or the company that's solving the problem is called domain, but that's just extra. Let's go back to the BDD. So if we want to make our BDD simple, we need to limit their scope and only if we can distinguish different areas we are able to do so. And this is like a general piece of advice for designing systems. Like if you want to make them simple or unmanageable, you need to limit the amount of information. And there is lots and lots of problems that you get rid of when you get the modularization of the system rights. So if writing BDDs or testing in general hurts, it's not easy, it's difficult, then perhaps your architecture is to blame because in Python, you know, we can go to the great lengths, we can monkey patch everything we want to, but maybe the effort should be put elsewhere. So going back to our system, like let's assume we have these four areas of features or subdomains, so users management, plans management, subscriptions and payments, and we have a following scenario, which will be using all of them. And I'm doing this on purpose because we will shortly split into smaller manageable pieces. So it starts with a user registered with username full, okay, there's no password, that's some progress. Then let's assume we have a plan called monthly that has a specific price and has a specific benefits. And whenever user subscribes to this monthly plan, they should be subscribed to the plan, they should be charged $10 minus one cent, and they should have fast support in their benefits, and the user's next build date should be a month for now. So this is pretty huge, and when I say small, nice specs, I mean like three, four steps at maximum, so definitely something to work on because we have like seven. But to simplify, we need to first limit the scope because it appears that we are trying to do everything at once in this one little spec. We're trying to describe all the behavior, and that may or may not be like manageable in the longer term. So the first thing we can actually do is to decide which things we need to focus on. So there are a lot of stuff intertwined here. So let's say I will make this scenario specifically about cash, about how much I pay, when's the next build date, and so on. So I can limit the amount of details. So first little refactoring of this scenario can do is I can move one of those steps to the background. This is like in a single feature, this will be reused across all scenarios. So of course we always need something to subscribe to, but it's not important to be in this particular scenario because like doing nothing special about it. And actually we don't care about the benefits in itself because I only interested the focus I mentioned about the price I pay. So we can get rid of one step and simplify the other one. So it's already better. And then since focus is on the money, we can omit the first then step, user should be subscribed to plan monthly. So yeah, we get rid of one step, one other step, so we add four. And also, so this is one approach to, we remove steps that are not necessary because we simply decide not to check them at all and also remove some details from other steps that may be necessary, like this background given plan. But we don't care about benefits, so we also simplify the individual steps. As it was with username and password for banning when we didn't care about password. Yeah, and another stuff, we can make some things implicit because in such a system, there's always a user. Maybe I don't need to spec it. So I will just simply remove this given user because I don't really need it. So in this case, simplified means limiting number of details either because I don't need them specifically or maybe because they're not relevant for this scenario. So this puts another point on our how to be DD. Once we have the expected behavior, we capture it using Gherkin, use some collaborative process not to do it solo. We keep our specs short and simple and afterwards we need to think about architecture, the boundaries so that our scenarios are not too wide, not trying to test everything at once because that's not gonna work in the longer term. Nobody's gonna read it and also we have bad time updating it later. Okay, but if we make the Gherkin simple so it's easy to digest, easy to read and the underlying system is still complex, we just shifted the problem elsewhere, right? So okay, there are no more dragons in Gherkin but they do live somewhere, right? Yes, of course. And this will be called the automation layer or simply saying all the code that's just after these steps. So then in this place, we'll focus on making the solution maintainable, called the duplicated and so on. But before we jump into implementation, let's first talk about which layer should we use to implement our BDD specs on. So what I see in examples over and over again is to starting with UI, maybe with Selenium or some similar solution. I don't think that's a right approach in most cases, especially when single page applications exploded kind of became very popular. For example, when I open Facebook on my computer, on my profile, it sends 140 HTTP requested background. And I assume that at least half of them actually does something, apart from tracking me, of course. But it also means that, you know, probably they read some data from the database, maybe some do some calculations and so on and I need to set up my system for that. So in general, user interface will have more dependencies which means more setup, slower test, hard to maintain and so on. So out of experience like I learned, API level should be considered first to automate BDD on. But of course, if it makes sense in your case, you can go up and down. It's just my default. Yeah, I start with API. So let's now do some coding, right? Because I was showing you Gherkin, you are on the Python conference, I'm also a Python developer, so where's Smith, so to speak? Where's actual code? So let's automate this scenario that we simplified. So a user subscribes to monthly plan. The first thing we do, like if we do it on the API, like we're gonna have a lot of HTTP requests using test clients of our framework, for example, fast API in this case, and we'll be sending various requests. And like the first thing we do to make this code like more manageable is to abstract away the protocol. So like we can simply grab all those distinct requests, distinct methods of different endpoints and move them to another class or maybe a bunch of functions in the module works the same way, which we'll call a client and this will just accept some attributes but we no longer have to write the entire query. This may not be a big issue for HTTP because it's pretty concise protocol, but once in a day I worked with GraphQL that was also used as the main API and it was really hard for us to test two managers because built-in GraphQL query requires a bit more, a bit more lines of code. It's harder to format and so on parameterized. So it was much better when we introduced such a pattern. And of course we pack it into some Python's fixture like Python's BDD is the library I use in this presentation and eventually like our step definition looks like this. So it's much simpler and much easier. So the first pattern we can use is up client just abstract away the protocol. We actually name the methods with the actions that we can do on the system. So then our steps can be much, much smaller. But when we are dealing with API we're usually making requests on behalf of some user and like I said I decided to make you make this implicit so that don't explicitly name which user they will be calling requests on behalf of. And with HTTP and for example standard methods like authorization bearer token this is pretty simple because we make simply parametrize our up client to keep this user token as another fixture and keep it inside and just reuse it. So whenever like we make a request using up client we then you know don't have to deal explicitly with the authentication or whom who sends the request because it's part of up client. And for example if we have like a test scenario that needs a few users then we can have a few up clients each for separate for each user. And now about this user token. Of course we can make it the hard way the usual way like register the user then log in then grab the token and you know return it from the fixture. But in many systems that are for example using microservices are correctly decoupled what we actually need is a token. Maybe sometimes the user doesn't have to exist. And in these cases it may be very handy to just do the shortcut and generate the token the other way. We used a similar approach to our test that we're using Selenium on the UI. So in every test you have to go through the login right? No you don't you just need a cookie that's valid. So instead of logging over and over again in our scenarios we just generated the cookie and you know added it to subsequent yeah to subsequent requests. Right so to recap we have our Gherkin that you know is optimized for redability for Cumans. Then we have the steps definition in code and one of the design patterns we can use is up client that you know we abstract away that protocol used. And in our case up clients will be always associated with some user credentials because like all requests are done on behalf of some user. Okay so let's now focus on the second step. User should be charged something dollars. And it's natural that we will like be no will not be implementing like our integration with bank and payment systems but we'll use something you know of the shelf that's ready to use like Stripe or Addian or whatever. And what I often see and I perceive it as a regrettable practice is that we go like straight away to like monkey patching the client's library. Don't do this. This is wrong. This is very wrong. First of all there is a general piece of advice for testing don't mock what you don't own and what it means don't simply mock the code you haven't write or you have no control on to off because whenever for example you upgrade the library and you didn't quite catch the subtle change you will simply fail to notice it. So you mocked one behavior but by the library for example can behave a different way. Also for example Addian requires quite a lot of arguments to call so why burden and put a mess in your tests when you can make it a bit simpler. And the second reason is that concrete payment provider actually belongs to the payments not the subscriptions. So therefore it could be hidden from the outside world and we don't have to put this information BDD especially. And what we can do with that we can use another design pattern called facade and like for each of our modules like user management, payments, subscriptions and plans management like we can have facades that will expose the API in a form of a single class. It's of course one of the ways. So we'll for example have method like create recurring payment. And it can of course use Addian inside but in BDD tests like we don't have to go down to actually make sure that this will happen. Speaking of type hinting and type checkers of course we need those to actually ensure that this will be working later. And facade does have to be a class obviously.  You know the point is to just have a one entry point to any given module or component of your application. So like you know, you know where to stop when you for example implement BDD. And then since we have our facade which we said it's an API. So by definition will be more stable and also owned by you. Then we can resort to using our standard wonky patching. And for example assert that the exact amount of money expected has been charged. And last but not least, there is also a step with monthly plan. So of course we could naturally use plans facade inside our tests to just create the plan and store it in the database so that it will be checked later. But we can also just mock the method that will be used by subscriptions. In this case get plan. So we limit the scope of the BDD by you know the actual pay plans is not exercised here. We only like will be have mocked this get plan part. And regarding the implementation, it's pretty nicer right now because we have this mock on a stable interface. But there's one thing I still don't like. I deliberately removed the benefits part from the BDD spec because I said it wasn't relevant. So why the heck do I have to repeat put it into the step definition? Turns out I don't really have to. And for that, okay sorry. And for that purpose like we can use for example factory boy or just you know write custom function with default arguments. So like we have something called sensible defaults. So in general case, we can have like for example a plan without benefits because maybe they are optional or maybe we manage it the other way. And close, we are close to the end of the presentation. And after that I put the last final point on how to BDD. You can't really do BDD in any non-trivial system that lacks modularization. You need to take care about architecture first and then to make code reusable, maintainable, use various patterns in automation layers such as up clients, such as facades and so on. So that will be that will be simplest and factories of course too. So apart from the most important take away from you that goal of BDD is not testing but rather building shared understanding is that to verify behavior. This is also a good piece of advice in general for tests. Testing on implementation details like makes your code difficult to refactor later. When you verify behavior, I mean you closer to it of course not always on the UI, then it will be just easier for you to later evolve. And also sometimes you like don't have to write that many tests because maybe two scenarios on the top level will be enough to cover everything. Yeah, and I can't stress this enough building shared understanding is really the point of the BDD. It's not tests, it's not writing Gherkin itself is to build shared understanding which also means when that understanding changes because for example some new requirements come, maybe you hire another expert then says it's all wrong, should be done differently then you also need to be able to refactor those specs and yeah, and that's not something you write once and forget about it, it should evolve along with your understanding. And regarding further reading, if you are more interested in the topic, the first position I recommend the most it's a specification by example book by Gojko Agis, I think that's how it's pronounced and it's like, it has been a gold mine, it's pretty exhaustive because it has three or four case studies of actual companies, so there's a lot of knowledge in there and a lot of practical knowledge, a lot to choose from. The second one is BDD in action, you can read optionally and there are also like two next articles which are very helpful, whose domain is it anyway is from the author of BDD and it explicitly says about the problem when we try to put too many things at once in a single BDD spec, so then it's a second read, recommended from my side and if you, well I'm not making BDD explicitly but you would just like some general advice on unit testing, then you can start from this blog post people behavior and unit testing by Vadimir Korikov and I recommend also other posts on his site. Yeah, and that will be it. Thank you for bearing with me. Thanks for the interesting presentation. I have one question on the example that you showed with a monthly subscription plan. So I was looking at what is implicit, what is explicit and it seemed to me that the monthly plan had an implicit 30 day expiration in the Gherkin. Was that intentional or is that, because if we look at the Gherkin it's never says like a monthly is 30 days. Yeah, that's a very good question. So yeah, this is a simplification really. This shouldn't be hidden especially, I mean, for this scenario, yeah, when we look at the last step the next build date, this should be made explicit in this case, yeah, definitely. Okay, thanks. Hey, great talk, first of all. I would like to ask, do you have any tips for dealing with eventual consistency on the system that's underneath? So this is a very general question about eventual consistency. So usually we start from explicit weights done in a loop. So like, for example, we know that for example some endpoint will start returning a different answer but I don't know when, eventual consistency, right? So we keep on polling it, meaning querying repeatedly with some small intervals like 50 milliseconds or so the first approach, yeah. But if you have any specific case in mind maybe you could elaborate a bit. No, it seems like on this level it seems like everything happens instantly and is that a problem to deal on the spec level or rather the automation level? Okay, so that depends as always. So, but in general, I'm not dodging the question. We are generally doing this on automation level, yeah? Layer, we like do these loops with weights and we have some timeouts and then we, but if you're like, where to use gherkin to specifically specify these eventual consistency, then we would put it, yeah? But then it's, I still find it hard to imagine, for example, I would specify that this message like comes in less than five seconds and yeah, kinda seems awkward then, yeah? So I would deal it on automation layer. Thank you for your talk. Really excited to dive in. I have a similar feeling when I first started using TDD to kind of not just test the units but to inform how I design a function. It seems like BDD is really nice for informing the design of your service layer. My question is, was the reason that we're dealing with the API client was because this was a microservices thing? If I'm not dealing with microservices, can I just use the service layer? Yeah, absolutely, absolutely you can. You know, I just, I'll tell you why that's my approach. So even if you like have a smaller, not large monolith but the smaller one that's still manageable, I would still do it on the API because simply I can more easy get 100% code coverage that way, yeah? Because if I do it on the service layer, which is perfectly reasonable, I still have to somehow cover these views, yeah? Okay.  Sure, thanks. Thank you for the talk. So I have a question of how generally applicable do you think BDD is? Because I always see it in the context of you know, websites, other API scenarios. But let's say I have a data pipeline which like runs on a batch job which every midnight extract some data from the database, transforms it, loads into a different database and then there is another user which consumes the results and we need to have a shared understanding with him. Would you say BDD is a good tool for these to agree on the specification or would you advise to use something more formal here? Okay, so the question is about limits of application BDD. So in your case, I would rather not choose BDD per se because I feel and like the team I'm currently working with also learned the hard way that perhaps putting technical details in Gherkin is a bit awkward, it doesn't really help much, yes? So we just decided to that part we just use usual Python and just write it very technically because that better works for us. And the other part of your question which you didn't ask explicitly is about data-driven systems. Yes, because I'm working mostly with product companies and I deliberately choose them because I like it and in this area BDD works better but what if you have more like data-driven? I cannot answer that but Gojko Argic in his book specification by example has some case studies about that explicitly. Yeah, so if anyone of you works with more a data-driven approach, I'm not an expert on that but yeah, Gojko is. Thanks. Thank you, I have a second question, but... Okay, I would like to know what do you think about BDD as a part of a concept of test as living documentation? I think it's a pretty utopian idea. We, you know, I'm pretty disappointed by not many successful products or consultancies built around the idea. There are only few. So I really like the idea. I'm actually, let's say, experimenting to make it happen but the big blocker for example to make these specs accessible to people that are not necessarily writing code. So for example, one person that's not writing code in my team goes to a git and can read them but I guess, for other people, this is a barrier not impossible to cross, yeah. So, yeah, I really, I admire the idea. I'm really surprised by lack of success stories in the field and don't understand it at the moment. Maybe you know something, I don't know. Okay, but I will try anyway. So I work with AI and last six months have been crazy and when looking at these GPT and language model capabilities, my first instinct was whether it is possible to use automatic generation either for turning natural language into gherkin or for turning, for basically writing gherkin steps automatically with things like co-pilot because it requires only like limited context window. Have you tried it or have you heard about anyone trying that? Yeah, so I can say you that, for example, co-pilot is pretty bad and suggesting gherkin. Actually, this bad example that I saw you know which is a script was generated by co-pilot but co-pilot, okay, oh, I don't have this open anymore because there's also this closed beta of co-pilot X which ships for Visual Studio Code Insiders which is an early build and I ask it to provide some examples and it were better. So perhaps if they put some more attention into it, it may be better, yeah. Awesome, thank you. Right, first thing first, thank you for the talk today. You argued against the use of Behaviouratum in the Stein on the UI level, but I mean, you left unsaid or probably you just hinted about the idea of using BDD at the model level. Would you argue for against using BDD at that very internal layer? And if so, is there any example that comes to mind? Okay, so personally I have like no objection because if I understand correctly, you're asking if I would be against using BDD like lower on the model, I see no problem with that personally, but haven't done this. I think it might work, it should be good. Thank you again. Hello, thank you very much for the talk. We are currently thinking about using BDD in our project and I'm wondering if we should use Behaviouratum or PyTas BDD. What are the features we should consider for our decision? Right, so I worked with Behaviouratum in 2018, I believe, and as far as I checked before this talk, I haven't released a new version since then, which is kind of interesting, but also we had a couple of issues with Behaviouratum, like it wasn't really running tests in parallel. So I remember there was a match request supposed to provide that feature, I don't know if it was merged, so we're now with PyTas BDD and I'm really fond of it. No, I think it makes the job. It's not ideal because for example, it doesn't like support all the new syntax of Gherkin, but it's more than enough for us, so to speak. This fork, PyTas BDD NG, which I noticed it was some update four months ago and it has those features, so I would just run a comparison between those two. PyTas BDD, if you already have experience with PyTas, should be less, has less deep learning curve, so that would be my recommendation. Thank you. Hi, thank you for your talk. It was super interesting. I have a question around, you mentioned code coverage just before, but you also said that it's not really about coverage. I wonder what success looks like and what are the cues that tell you that you have enough scenarios or that your tests are broad enough for you to consider a good code base or a healthy one? I don't think there is a clear success scenario because the thing is that like with testing itself, we can have code coverage on 100%, but it's only a metric of how many code actually we executed. With test scenarios in general, you can only write those that you figure out to figure out or co-pilot suggests, so that's it. I wouldn't tell about. We can use another metric, but it's not easy to calculate or enforce, like are people actually using it and do they find it helpful? So that's different. For example, if these scenarios are not too big, that would be my success metric around it. But really, really tough question. Thank you for this one. I'll be thinking about it all night. Yeah, so we'll thank you everyone and thanks, Sebastian, for the talk. Yeah.


So let's find the domain of the function g of x equals square root of x squared plus x, and let's write our solution using interval notation and graph it on the real number line. So remember the domain consists of all allowable x values. Since we're taking the square root of something, then our radicand must be non-negative, so we require that x squared plus x be greater than or equal to zero. And to solve the inequality, we'll solve the corresponding equality x squared plus x equals zero. Since this is a quadratic equation, we could solve it using the quadratic formula, but this is one of those very, very, very, very, very, very, very, very, very rare cases where it's easy to factor. So we'll factor, and since we have a product equal to zero, one of the factors must be equal to zero. So either x is equal to zero or x plus one is equal to zero. So we'll solve the left-hand side for x, done. Solving the right-hand side for x gives us, and these were the solutions to the equality, so they correspond to the critical points of our inequality, x equals zero and x equals negative one. So we'll graph the critical values, and since the critical values solve the equality x squared plus x equals zero, and we can take the square root of zero, the critical values are included, and so we should shade them in. So we see the critical values divide the real number line into three intervals, so we'll choose a test point in each interval. On the right-hand side, we'll let x equals one million, so then x squared plus x will be a very large positive number, which we can definitely take the square root of, and so we should include the right interval. In the center, we'll have to pick a point, and because zero is a critical value, we can't use zero. Because negative one is a critical value, we can't use negative one. We have to pick something in the middle, so we'll take x equals, so how about negative one-half? So equals means replaceable. If x equals negative one-half, then x squared plus x will be negative one-half squared plus negative one-half, and we can calculate the value of that. And remember, we're actually trying to take the square root of x squared plus x, but because it's negative one-half, we can't take the square root of a negative, so we should exclude this middle interval. Finally, this third interval on the left will let x be negative one million. Let's take a look at our radicand. x squared is going to be the square of a large negative number, so it's going to be a large positive number. And while x will be large and negative, it will be smaller than x squared is going to be. So that means x squared plus x will still be large and positive, and we can take its square root, so the left interval should also be included. And once we have the graph of the domain, we can write our domain in interval notation. Here on the left, we go from the way, way, way, way, way, way left, that's minus infinity, all the way up to negative one, which we include. We don't include the middle, and on the right, we start at zero, include it, and go to the way, way, way, way, way, way right off to infinity. And since our domain consists of both intervals, we'll combine these two with a union symbol.


The shift in the distant galaxy spectra told us that because of the Doppler effect, they were moving away. Their spectra had been stretched out, moved to longer wavelengths called redshifting. And that's interesting because that tells us the universe is expanding. But then wind the clock back and back about 13.7 billion years ago, that's when everything must have been pretty much on top of each other. And that became the moment known as the Big Bang. George Lemaître, Belgian cleric and also scientist, he coined the term the concept of the Big Bang, but it was a journalist who was actually mocking him who called it the Big Bang. And to be honest, it's not a very smart name because one, it wasn't very big. In fact everything was really compressed. And two, it wasn't really a bang. It was just a whole lot of things sort of expanding. So maybe it's kind of rather than a bang. But anyway, who cares? That's what we call it these days. We don't know what caused it all to be close together. There was some quantum fluctuation. You know, that's the world of philosophy. It's before physics. So as things get smaller, it changes the way they behave. Suddenly we have a whole insight into our history, the history of the universe, that once upon a time, things were closer together, which means hotter. What happens as things get hotter?   Go even tighter, the electrons get pushed into the nucleus. That's what happens inside a neutron star. Electrons and protons cancel each other out, form neutrons. You have incredibly dense stuff that makes up neutron stars. Even hotter still, you start to break protons and neutrons apart into quarks. They're actually so hot that quark. Well, we believe this is what happens, quark plasma forms, and that's something we've never been able to do on Earth, way too hot. So even hotter than that, when everything's pushed together into basically nothing, then we get what's called the singularity, which means we don't understand. It's a divide by zero error. That's out of the realm of physics. We think smaller than about 10 to the minus 35 meters. That's called the Planck length, Planck with a C named after Max Planck. At scales that small, we don't really understand what's going on. Physics, as we know, it doesn't really work. So that's something for you to work out in your PhD in the future. In the meantime, check out this website and have a look at just how big the universe is now and how small it was at the time of the Big Bang and how much it's expanded.


Broke College is a British accredited university and we offer three-year bachelor's degree in creative media production. Have you been looking for a degree where you can mix all of your creative passions together, achieve a highly sought-after career path, and make a true difference in the world? Do you have stories to tell, ideas to invent, and images and thoughts to share? Meet Martina. Martina likes fashion, photography, creative writing, and blogging. When she started her degree, she was unsure of what career was right for her. But after three years studying at Brock College, she now directs and produces fashion films for leading designers. Let's meet Inaki. Inaki likes music, journalism, politics, and social activism. Inaki is now working at an NGO, writing and producing all of their digital content. And let's meet Ramler. Ramler likes filmmaking, marketing, podcasts, and design. As a young entrepreneur about to graduate, Ramler is applying for grants to build an innovative startup to distribute film and podcasts. Students in creative media production are working across a broad range of platforms as content creators designing innovative forms of media and creating audience-engaging digital experiences. Get in touch. We would love to help you find your path.


They have an identity, right? They're gonna punch you in the face, us against the world. They are a team built from the top all the way to the bottom. Derek Henry's a monster. Steelers, Titans, both five and all.


there we go all right Dara is checking out this new Rockchip 96 boards hello who are you I'm Patty and this is Dara right there so we're just comparing the size of the Rockchip board with Dara all right that's it yeah that's cool I'll send you the link oh good send me the link yeah so we right here we checking out a really exciting new 96 boards this is the 96 rocks right yeah that's right so the official name is rock is rock 960 and you can find all details about in the 96 board rocks.com let's look around a little bit this is type C port yeah it's got type C yeah well yeah it is indeed not at the moment mandatory but it's highly strongly recommended and this now we have a fun you know we can find itself on the rock 96 and we got two USB 3.0 which give you up to 5G so that's pretty awesome and a USB 2 and then HDMI 4K 60 HDR yes very good point I know we do not have it but we do have a 4K 2K and that's DCP so that's pretty good and the the chipset is in a nice configuration like this with the RAM this good RAM on here oh yeah very good so I think we can't we're planning for two different variant we have 4G with 2G RAM and and also if you look at here we do have PCIe Gen 2.1 which and give you up to four lines so that's pretty awesome what does it do so GPU no PCIe so what can I do you can have SSD card and NVMe storage and Wi-Fi 4G it's a lot of lot of things you can do is it possible to connect that to a SATA well or you would not use a SATA I guess you can because it's you know on the PCIe bus as long as you have the driver ready so we never test it I should say that never test yeah it's brand new it is brand new actually this is just off the oven and this is one of the first batch of engineering sample and also come with the rest of standard 96-bolt low speed and high speed connector with the camera etc and yeah it's very very powerful exciting plus the fact that is it's a very popular platform chipset in the community already and very upstream friendly we put this board you know just off the production line we put the chip within two days with the upstream kernel so this is Rockchip 3399 as Rockchip 3399 yes even as known a as as known as aka OP1 in my Chromebook it's called an OP1 all right so it's in my Chromebook I've been using for last six months yeah imagine that as my main main computing chipset yes so this is powerful enough for it's very powerful actually dual Cortex a72 with quad a53 exactly so that's one thing actually I should mention about this if you notice already the latest that we are announced yesterday released 17.9 machine learning library is optimized for GP it's a 72 53 that is exactly what the chip is capable so I think you people would find starting you know very interesting entry level hopefully even more than that machine learning and AI application using this chip because there are some future chips coming out with built-in on the SOC machine learning AI kind of area on the SOC but all all the chipsets before arm v 8.1 or 8.2 8.2 all the one with 8.1 and below they all they still want to have machine learning absolutely so as I said you know of course people will know that 8.2 award your arm has released dynamic IQ technology but as you said everything before 8.2 and there's just a lot of market and start a lot of interest in fact it's still very very powerful technology and it is I'll believe there's a lot of possibility we can do by enabling the machine learning and AI applications that is you know that's why actually the machine learning library effort is from arm and we believe this chip is a very very interesting and good platform people to start working on platform as such which is at the moment being optimized for the to you know for the usage of those libraries this is a kind of a like a beautiful 96 boards don't you think yeah absolutely it's beautiful I mean I really like how it's done and then you know it's not just the design is quite it's quite slick but also the the board quality is really quite solid nice color nice color and yeah very good choice of the component connectors it's just yeah it feels pretty nice so what's your strategy to make 96 boards more popular than Raspberry Pi oh wow I'm joking but I you have this potential for a lot of growth right yeah yeah I think you know all the difference fundamental difference we've been talking a lot about is differential 96 board from other interesting community project such as Raspberry Pi which was very successful itself by the way and the big goal and the bigger one of course and you would notice that in this connect we also launched the TI 96 board as well and based on latest Wi-Fi chip 3220 so what I would say is 96 boards the core value of it's been SOC independent specification which has really demonstrates a bit capability to really enable the latest and greatest SOC technology across the entire SOC industry and really enable those developers who has long been waiting for all the nice you know SOC technology to carry out their development and for a large great you know for the community and product designer application designer to benefit them from so we've seen a huge momentum in 96 board we believe is going to only going to be better from here we consider Raspberry Pi is a very good community project we set a standard but we are not in any way in terms of competing with Raspberry Pi maybe they could even join the 96 boards project maybe they can they can make the there's some new Broadcom chipsets for TV box and some big big CPU very powerful 15,000 DMIPS and you have the new 96 boards TV spec absolutely so everybody's welcome no and we have 96 board networking networking spec and sounds a lot of interesting project we're working on each one is different design kind of yes they are you know they're tailored different segment market to recommend and you know we have to bring out the realistic capable enough platform for each segmental usage what I would say is we certainly would be very open to work with companies like Broadcom or even Raspberry Pi and Rockchip Rockchip as well of course we open it's an open standard they have some very good engineers right Rockchip has a lot of excellent engineers they should come and hang around with the the narrow guys more often the door is open wide open next next in our connected in Hong Kong in fact it's quite interesting we see this board has actually already been very popular in Rockchip's community as well they have a very successful established their own community but what I would say it's open we welcome them to join we welcome the participation 96 board is about enable people everything open source everything it's kind of slogan but for us it's a lot of actually actual work need to go behind behind the scene but what I would say is that we only did the first step and it's up to you everybody who participate in carries forward what we can say today is everything suggests people love what we do and love who we are to be able to do more about we just would like to welcome everybody joining force Raspberry Pi everybody so yes there was the RMPC there was a big deal at this that was everybody here is excited about the RMPC right with the social next this is enterprise edition board it is indeed a large board so for people who have been following us knows that we have been making attempts trying to help and arm enterprise community if you like and help arms enterprise software developers to be able to have a realistic platform to work on the software stack etc but it's not without trying but we did fail a couple of times and like some others but we didn't stop there so in buddha partially now connect early this year we made a pledge that even though we know it's hard a lot of work has to go into it but made the pledge we would like to be able to have the opportunity to work on and giving the developer community the first 9696 boards on native developer machine and right after that session which apparently have got a lot of inquiry a lot of people are very interesting about we work with the odm gigabyte in this case we work with so even the social net in this case very closely within six months from an idea to actual box obviously a lot of work to be still need to be finished to be done but we have an actual machine arm native motherboard sitting in the demo desk people can play and use so i think that's it something that is something demonstrate not able not only we can do this as long as we believe this is helping the developer community and the soc and odm partners have the belief in it and we actually did it and this is only the starting point because that's how we enable all the good work including the firmware the kernel and the hardest bit of technology enterprise this is only the starting points a lot of people are going to be very very happy when they get this box we are hoping they will be and you hoping to be even more and more busy in the future you hope you want more and more people in the industry to contact you and say i want to be part of this right so we always we always welcome participation so yes our door is always open please drop an email and come to our website and yes we're always busy if there's any delay in response and please accept our apology just send a second email just send a second email to we won't forget about it but normally we handle this pretty well


It is the ultimate make it as simple as being a performance, our presenting sponsor for this weekend's event. Of course, they're racing in the Dodge Direct Connection Shootout and it'll be shown on that car. What's up Mopar Fam? So just want to give you guys a quick update. We've made some passes, Frostbite seems to be working so far, we're just having some track hooking issues with trying to launch off the Transbrake, that's not going so well forced today so we've been having to turn it way down on the two step, but Zorro and Storm are doing really good so we've made two passes now in our qualifying actual runs and Zorro ran, first pass out it ran a $12.95 so we ran a $12.95 on Zorro and we're shooting for the 13th second class and to run that $12.95 we took the rear seat out, we took the passenger seat out, we took the rear back rest out along with a spare tire in the truck. We just went up, my son made another pass in it and this last pass it went what? $12.95 at $105. Yeah, so it ended up doing basically another $12.95 spinning, spun a little bit, mowed an hour almost one mile an hour I think it was like .76 higher so the car's going a little too quick so now we're playing the weight game guys so we put the back seat back in, we took one of the back tires, the full size back tire, street tire we put in the truck, adding weight to it, we took some more air out of the rear tires trying to slow it down some because we need this car to run like a 13-1 or maybe a little less to be real competitive in that 13-0 bracket.  So today Storm ran a $12.80 today in the first initial run so we took that $12.80 and we said okay it's going too fast we're trying to slow it down to go 13s just like my son's we're trying to do both cars, truck and the car we're trying to run 13s in so they're fighting each other they're battling and it's like right there guys.   So now we have three, count them three full size tires in the back, we have two, count them not one but two full size three ton steel not aluminum jacks that are heavy as hell in this truck right now to try to slow it down another two numbers so that we can get on that 13-0. So wish us luck guys, frostbite I'll show you the time slots we got because we finally made it, that I could I mean say was decent but definitely nothing nothing for what frostbite is known for but let me see here let me get the slips so my first qualifying pass because like I said we normally leave on like 4,000 rpm on the trans brake and the two step we tried that in our practice run it annihilated the tires so I knew we weren't going to be able to do that so I turned down the two step to 2,000 I've never launched it that low so we launched it that low and normally I can hit 1,3, 1,4,0 60 foot and you can see we had a 150, 60 foot but we still ran a 10, 25 and 130 I was I was happy with that you know the pike didn't blow off and we went down the track we made a pass and it did pretty good 10, 25 and the DA at that time it was around 15, 1700 I think somewhere in there so I was happy with that next pass up which was my first qualifying run we didn't do so good I tried to turn the two step up a little bit and we went up 500 rpm so we went to 2,500 rpm to see if it would hook because obviously we're trying to shoot for the 10,0 bracket right and even at 2,500 rpm guys that 500 more rpm it annihilated the tires you can see the 60 foot was 166 and we ran a 10,73 because it spun now I know you're going to say why was a mile an hour to two whole mile an hour and some change faster than the other pass well I had to bottle in the truck on that one and as soon as the tires spun already had to bottle on because I was trying to play a guessing games if we spend I was trying to stay in the game you know so I had to bottle on with a 50 jet in it and as soon as the tires hook I flipped the switch and we ran it out the back door on the bottle yeah I know you guys is nice and for but yeah we ran it out the back door on the bottle we still ran a 10,73 you know spinning out of the hole but it trapped over an extra two mile an hour which is pretty stupid for the same day same air kind of situation so I can tell you right now you know in the wintertime if we did that we would probably gain an extra two three mile an hour obviously which would put it you know definitely into the nines but now that we ran that 10,76 you know even if I came out and I ran a 10,0 right now there's no way I'm sure there's someone out there's gonna have a much more stacked set of time slips for the 10,0 bracket so I think we're just gonna go out I'm gonna turn the two step back down I'm gonna try to have it just hook again like it did on 2,000 rpm and if it hooks I'm thinking about just spraying it and you know see see what happens see if I can run a 10,0 maybe a 999 in this in this weather worst case I don't know if we're fast enough I haven't really watched these other cars but there is a possibility of the quick eight I could be selected into the Hemi quick eight group again there's a lot of demons and a lot of hillcats out here and they're fast so not sure if we are even comparing to those guys but we're no sitting duck that's for sure so yeah that was kind of my plan was just running this next pass out for fun and and see what happens or I could gamble I could run it out halfway and just let let out coast rest of track and see what kind of number it gambles in and maybe I get lucky and win like the 13-14 bracket or something you know how this works as it takes your three passes and it averages the three out and whatever that averages that is your bracket that you're gonna be in and as long as you got the fastest pass in that bracket then you're a winner so that's pretty much it guys so other than that that's that's what we're doing we got one more to do storm and Zorro is definitely clenching and it's gonna be a battle so I'm interested interested to see what happens I I want somebody in this group right now to win something so I really hope one of them pulls it off and maybe we as loud and maybe we can make a miracle happen with frostbite or something but at least we're making licks down the track again guys so stay tuned we'll keep you informed y'all have a blessed day we'll see on the next


I don't know who drives this van but as I was pulling into the grocery store parking lot I was headed for a space and she could have beat me to it and she didn't and she was real nice and waved me on in with a big smile and so if you see this van around Jackson Hole the driver is a good person it seems a nice lady and give her a big smile and wave she rocks and I'm thankful for her and so thanks lady!


On February 19th, 1944, my grandmother, Joyce Haynes, was born on September 2nd, 2021. That's when she passed away. Today, I went to her funeral. And it was kind of tough. This is not my first time dealing with death in the family. A few years prior, I want to say maybe 2017, I lost my grandfather on my dad's side. This is my grandmother on my dad's side as well. And I lost him. He passed away. And it was really tough. That one hurt. And this one hurt as well. And I think what kind of really gets to me sometimes is the fact that the last time I saw her, which was, I want to say, maybe like last week, actually, it was my first time seeing her in two years. It was really my first time going to see my dad and everyone else that stays in Bryan College Station since my grandfather passed on that side of the family. And to see her in the condition she was, she wasn't really saying much. She was asleep at the time. But it had just gotten to the point where she wasn't eating much, wasn't drinking much. And you can tell her time was coming. And I think what was also tough for me is the fact that when my grandfather passed away, I don't think she really knew who I was. And I think for anyone that's dealing with someone that's going through dementia is that so tough. It's not because they don't want to remember you, it's just they can't. And I think that kind of kept me away from going down there. Granted, I knew she was in good hands. My dad was making sure she was good. My aunt Denise, my aunt Lisa, my aunt Michelle, they were pretty much her caretakers. They were doing everything they could to make sure she was okay. So I knew she was going to be fine. But it still was tough for me because it's like I couldn't really see her, not because I didn't have the means to, but because I was just afraid to, because I know it was going to like eat at me because she doesn't really remember me anymore. But I will say this, even though the last time I did see my grandmother alive, she was asleep, not really knowledgeable of who was there and what's going on. She was just kind of asleep. It was that comfort that I knew even though her time was coming, I still got to see her one more time. Still got to relive those memories one more time, still got to be in her presence. And I didn't really say it out loud, but I said it in my head and I hope she heard it. That I love her and thank you so much for everything you've done for me. And I'm making this video because I'm dedicating this to my grandmother. And I want her to know that I love her for everything she's done. I hope to continue to make you proud what I'm doing on YouTube. I hope that you're able to look down upon me and see the good that I'm doing. I want to make sure that me having the Haynes in my name continues to be synonymous with greatness. For those who don't know, my last name is hyphenated, Ross Haynes. Grandmother's last name, Joyce Haynes, obviously married to my grandfather, Marion Haynes. So I want to keep the Haynes family name meaning something of positivity. My dad, strong man, and I would love to one day be as strong as him because he's lost his father and his mother. And seeing him today how strong he was, it was crazy. And I know, you know, he has a lot of emotions going on as well through this whole situation. But the one thing that he's told me is he's blessed. He's blessed to have had her this long. He's blessed to have had her in his life. And hearing someone say that, even knowing what the situation is shows a lot of strength, shows a lot about them, that they cherish those moments and that I should also cherish them as well. So shout out to my dad for being very strong through this tough time. I love you, Pops. And I know she would be happy to see you being as strong as you are during this tough situation. I don't even think she would want him to be down and out. She would want him to keep pushing forward because that's how my grandmother was. I don't think I can ever recall a time, me personally, where she was just down and out or, you know, like had a negative attitude. She was always trying to find the best of people and she was positive, you know, and that was always crazy to me. I'm sure she had her bad moments, but I rarely saw it. She made the best of any situation. And I'm very thankful to have had her in my life for this long. It is a blessing. I want to give a special thanks to my friends, Doug, Trill Billy. Thank you all for being there for me during this hard time.  I want to thank my close family members that are checking up on me, making sure I'm good. Friends that were checking up on me. You guys know who you are making sure I was good. And of course, the clutch squad, people that subscribed to my channel. I got a lot of DMs when I initially posted on my story on Instagram when she passed away last week. A lot of DMs on y'all checking up on me and I want to say I thank you for that. I didn't get to read every last one of them, but best believe I'm very thankful for how you guys really been making sure I was good. And that made me feel like I'm not alone. And I want to say I love all you guys for that. So thank you so much. Thank you for the condolences to me and my family and what we're going through. And I'm just very thankful. And I want to end it off here because I don't want this video to be too long. But I want to say this, that enjoy the people you have in your life while you can. Cherish those memories. Cherish those fond memories. Check up on people. Say, you know, hello to people. Tell people you love them while you can. Because there's going to become an opportunity or a time where you won't be able to no more. And all you'll have is those memories and those times that you did interact with that person. So make sure you guys do that. If you have some issue with someone, let that go. Life is really short. Not to say that my grandmother's life was short, but I'm just saying in general life is short. Let the petty pettiness go. No, no point in having hating your heart for someone when you can just let it go. Focus on being a better version of yourself and focus on enjoying life. And before I end this video, I just want to say, Grandma, I love you. I'll always love you to my grandfather. I love you as well. And I hope to continue to make both of y'all proud. And I'm just very thankful to have had y'all the majority of my young adult life. I'm gonna miss you, Grandma. Rest in peace. Enjoy James. See y'all on the next video.


Hvala, to je Damian Krizmančić. Vse je interfejz. Sesson 1, koncept in ideje. Kaj je Vse? Vse je system inginering software in aplikacije, kaj prekupuje test, način, in kontrol, kaj je vse za hrvorega in data in začin. Vse je grafika programovana, kaj je vse vse začin vse začin vse aplikacije, of your application, including hardware configuration, measurements, data and debugging. LabView integrates measurement hardware for any vendor. Why we would need a LabView our interface? One can deploy air models directly into production. There is no need for additional software development. One can harness the power of both LabView and R. Who uses LabView? Industry, military, aerospace, automotive, semi-conductors, telecom energy, power, Consumer Electronics Computer Medical Devices, Experimental Research, Physics, Biology, Chemistry. Where does demand for artificial intelligence rise? Same fields. LabView are interface ingredients. R. LabView. It includes native support for Microsoft.NET framework. R.NET, an open source in-process bridge for Microsoft.NET framework to access the R statistical language. Session 2. A working example. Deployment of the KNN algorithm. Part 1. The LabView are lot script. This script in principle loaded data. This is how our data looks like. This script will be sourced by LabView. Part 2. Manual setting of a new observation. Feature 1 is equal 6. Feature 2 is equal 3. Let's assign them here, for instance, but they will be set by a real LabView sensor. Part 3. The LabView are predict script. This is the KNN prediction. In this case, the result is A. This script will be then also sourced by LabView. The predicted output class value will be returned to LabView. Session 3. The LabView demo. This is the LabView block diagram. It's based on an event structure. This is the LabView front panel for our example. This is where we source the LabView are lot script. Part 2. Here we manually set the values, in this case 6 and 3, and then we set the values to R. Part 3. We source the LabView are predict file and we get the result back, in this case A. Let's try another pair of values. We set Feature 1 is equal 2, Feature 2 is equal 2, and then we get the result B in this case. Thank you. Feel free to contact me. Bye-bye.


This study uses feature selection scenarios and machine learning tools to develop a general model for estimating biomass higher heating value, HHV, with the highest accuracy, which is determined to be a multi-layer perceptron neural network with an absolute average relative error of 2.75% and 3.12% and regression coefficients of 0.9500 and 0.948 in the learning and testing stages, outperforming other intelligent models including a recurrent neural network recently developed using the same data bank. This article was authored by Sader Miriza Abdelahi, Saeed Faramaz-Rajbar, and Dalsa Rasegi-Joromi.