Javascript Freecodecamp Algorithm #26: Cash Register

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Nice stuff! Subscribed.

👍︎︎ 2 👤︎︎ u/cdsalty 📅︎︎ Feb 05 2020 🗫︎ replies
Captions
hey guys welcome back to my channel this is Justin here and we're back on free coke an org and algorithm that we're looking at is under JavaScript algorithms and data structures structures projects such a long title and the one that we're looking is to find the one as a matter of fact caste register all right so guys if you guys are interested in any of these other ones here like palindrome checker Roman numeral converter and so on I have videos for all of them or links in the description below I also have videos for all the ones under intermediate algorithm scripting so please go inside my channel and check out any of these that you guys want too but today we are interested in the last one of the data structure projects one which is cash register now let me give you guys a heads up for those who hasn't done this yet this is a beefy one so is a pretty juicy one and it will take a little bit of time so as always I highly encourage you guys to if you haven't tried this out already please pause the video try it out just try it out oh you might run into a couple mistakes and please please please read the directions very carefully before you attempt look at some of these outputs that expect the output stats down here because this question in my opinion is kind of needlessly like precise in the ways that they want things it's kind of stupid if I were to be honest however you know they asked us to do it so we'll do it for them but just keep that in mind be very careful make sure you're good at reading directions okay so pause the video now and try and come back to this video to see my solution okay so if you're still here I'm gonna assume that you guys have tried this whether you got it right or not that's not the issue we will solve it together here let me just bring the code over here and let me read the directions for us okay design a cash register drawer function check cash register the accept purchase price as the first argument price payment as a second argument cash and cash in drawer see ID as it turned argument okay so we have three parameters here see id is a 2d array listing available currency the check cash register function should always return an object with a status key and a change key we turn this if cash in is less than a change to you or if you cannot return the exact change we turn this with cash in drawer as a value for the key change if it is equal to the change due so this is coming from right here if we have exactly the amount that they are asking for in change then we give them back dot CID pretty much is if it is what they say here with a CID caching drawer as the value of the change if it is equal to change to okay this is important you'll come back later otherwise return status open with the change to in coins and bills sorted highest to lowest order as a value of the change key so this is where it gets kind of stupid okay so if we have the exact amount if it changes the exact amount as our CID what do we do we just return the CID upon in the change key so look at what CID is like okay check this out this is an example what's the idea right it starts to the lowest to the highest so if we get closed such as where are we this one closed we sort these from lowest to her or highest because that's how our CID was given to us however if we use the open one then we sorted from the greatest to lowest so if you look here 2010 five one quarter of time penny so this is where it gets kind of stupid uh-hum but whatever that was the direction so we'll follow it now before we go on a couple of things to consider javascript is very weird when it comes to fractions when it comes with decimals okay so check this out I'm gonna open up not that one but my console we've been within my Chrome not my son Mike I don't know why that open is my frickin touchpad there we go we finally got this one okay let me clear this real quick oh no how do i clear this terminal I completely forgot okay whatever oh I just pressed so let's try this I'm gonna try I had the console open and I try point one plus point to look at what we get here we got this crazy point three zero zero zero zero zero and for at the end so this is where things get a little murky when you deal with decimals in JavaScript so the standard way of dealing with money for example like some dollar amount and including some change amount we always want to convert everything we wanna times everything by a hundred so for example here we say nineteen point five right that's $19.50 we want to multiply this by a hundred so we get one nine five zero and this 20 becomes two zero zero zero that way we could do all the math in the world so for example one plus two if I could type it there we go that'll give us three that won't give us like three point zero zero zero four so what we're going to do is we're gonna change all of our amounts to not multiply them by a hundred so that we don't deal with this crazy this type of error right here okay cuz this type of in there inaccuracy could apply to us in the but in the end okay so let's multiply everything by a hundred now I don't need that look at this I don't know why they gave us our CID value in an array with an array of key value pairs like this why don't you just use an object so I don't know why they did this but they did it this way so we'll just follow with the direction so before we go on above our function here by the way here's one last caveat okay notice the key value for the one we use the actual word oh and eat that one right but look at this example they put here here they put dollar which is super confusing now I don't know why they didn't I think it's probably a typo right here but it should be a one okay so whenever we deal with one single dollar bills we use the keyword one not dollar like they show you here I don't know what this is a huge mistake on them whatever okay so let's go on before we go on and then I make like a dictionary object a key value pair object that tells me what each of these keys what amount they correspond to with the times 100 ok so just follow along with me let's write Const what should we call this money did how about that money dictionary will be an object of key value pairs so we have penny which is what's the amount in penny times a hundred member normal is point zero one but we don't like dealing with decimals in JavaScript so we're just gonna say this is one because point zero one times 100 is one and then we have nickel make sure you write these very carefully don't make typos just five dime which is ten corner which is 25 now we get to one remember that dollar about 1 and this is a hundred five which is five hundred ten which is one thousand twenty which is two thousand we skip fifty for some reason they'd want petty dollar bills and we get to 100 which is 110 thousand so make sure you wrote these very carefully and we're gonna be referencing this using this from now on so whenever you have constant values like this like one five ten instead of manually running them like that and have a potential of making mistakes you wanna define a dictionary like this so that you could just reference that so like let's say by accident we made this one into a thousand by accident and then our code wasn't working we could be like oh we could just change it here instead of changing it everywhere where we reference that value and just looking at numbers if he had this big function here it'll be very hard to see which one you have to change right so this is a good practice in JavaScript whenever you're dealing with constants like this just make a dictionary like this and let's go on so what we are interested in let me close this real quick let me make this a little bit bigger for us what we're interested in right now is the difference between cash and price so if you look here if you look at the test example here 20 is the cash price is the 19.5 so the difference the change that we have to give is City sense right so that's what we want right here let's erase all this nonsense what should we call that uh I'm gonna use the word let or the keyword let instead of Const be cuz I'm gonna change this value as we go on and and they'll make more sense as we as we keep on going but let's just call this amount left to pay how about that and so it's gonna be cash - price but remember we wanna we don't like dealing with decimals are not a parentheses around them and then I'm just gonna multiply by a hundred okay that is very important now why I'm calling it a mountain left to pay is I'm gonna try subtracting the $100 bills from our CID and then we're gonna subtract it from this amount up to pay when I keep on going until we have covered every single monetary value is that what it's called but I hope you get the idea okay so let's do this now what we should do is we should go top we should go to our CID see which we should try to subtract a $100 bills first and then if we can't go to all if it did go down to 20 and then go down to 10 5 1/4 all the way to penny so that's what we want to do however again before we go on we don't like dealing with decimals and not only that I don't know anyone that likes dealing with this array of a no rating so I'm gonna convert this whole nonsense here to an object that kind of looks like this penny the key penny is gonna be not one point zero one but 101 because we multiply by a hundred and then on nickel that is two zero five and so on so it'll be a single object consider this crazy array with array stuff we're gonna convert it to this okay so let's write what should we call that here we could use constants but nah we'll just use is length let's cash and drawer how about CID object CID object and we can have a shorthand the object CID object like that and the way that we are going to do that is this so notice this is an array right this is what we're going to do we are gonna use CID that an array has a method called reduce pretty much a guessing array loops through each element and converts that into something else whatever we tell it to do it takes in two arguments here the first one is a callback function the second one is an initial value of what's kind of cumulate ER so let me just write up for you guys within the callback function in our first element within the parameters we always have this acc short for accumulator and the next element is called the the element that we're looping over in our case is an array each element is no ray right in this case penny this case nickel and so on but not only that not only are they array there specifically an array of two lengths two elements there's always the key here the name of the of the dollar value although I don't know it call this and then the actual amount right so we could be structured that right away as a matter of fact put it on right here we've got this structure this value here we're gonna store that under the variable name what should we call it the money type how about that money type and the next value we know is the amount whoops like so now this will be an error function like so and remember I said the second parameter of the reduced function is the initial value of our object so we want to make an object right so we're gonna start out as an empty object this accumulator is called a memory variable we pretty much whatever we return from this that's what our human later becomes starting with the initial value of this empty excuse me and the object and we're gonna keep on filling it up with whatever with the stuff that we are written down here until we are done so we're just gonna return here in object we're gonna spread the accumulator what the accumulator was so far so for example if we went through the first two year age iterations accumulator would echo this penny is 101 and nickel is two or five right so this whoops I spelled that wrong Neko is 2:05 this was our accumulator after the second iteration so we're just gonna spread this value right here so that later we could add dime is 300 310 I believe so that's what we're doing when we spread so we're spreading everything but we're adding the money type as a key so how do we get this as a key we can't just write money type like this let me show you guys and by the way we're going to amount times 100 right because we want we don't want to deal with that suppose let me just show you guys why we can't do this money type as a key like so I notice this is so great meaning it's not being used let me come so log or CID object that we have just created with our reduced function let's see what that is all about I'm gonna run this we get this money type is just 10,000 we only have one key and the key is money type we don't so this will be right like this all JavaScript things that we actually want to name the key as pani type that's not what we want to do we want to name it as whatever value this money type variable hats so the way that we do that is we just put square brackets around it whoops square brackets like so now let's count along again and see what we get so now this is more like it although we have this kind of crazy thing going on here so this is again JavaScript being JavaScript for some reason when we multiply by a hundred it gave us this crazy nonsense here so how should we deal with this how about this let's just math that round whatever balli this was okay and just to make sure that our amount left to pay doesn't become crazy like that - why don't we map that round that it - that's got rounded to the nearest whole number let's see what we get now I'm gonna run to co-locate and now we don't have any of those crazy decimal values so I think this is better for us and notice what's Eid out it is isn't a single object with bunch of key value pairs I think in my opinion this is much easier to work with than this crazy array of an array that they have given us so this is what we'll be working with from now on so hopefully you guys are still with me we just created a CID object and what we have to do now is we have to go through each of our cash and drawers starting with the 100 we want to start subtracting from this amount left to pay starting from the biggest denomination first aha that's the word I was talking for this whole time denomination also technically nickels not denomination is it I'm not sure oh yeah whatever that's not the purpose of this course so we want to start from the biggest nomination keep on subtracting if possible and as we subtract we we want to do competence we want to subtract from our amount that to pay the amount that the most amount that we could subtract we want to subtract from Cid object because we may later want to return that later and also we want to add up in inside another array that we're gonna return so check this one out which one do I want is less it's not insufficient funds but the one would open this one right here that is open we wanna return the array that has all the array with this key value pair type of thing going on with the denomination on the left side and the amount that we took out from the right side so why don't we initialize that right now so we're gonna say let change to game how about that and we will initialize this as an empty array but we will fill it up as we keep on adding money amounts to it hopefully that makes sense now let's begin with our hundred dollar bill so let's do this the only times we will try to access hundred dollar bills from our CEO jack is two things either the amount left to pay has to be greater or equal to the monetary value itself in this case ten thousand so we could either say if a month left to pay is greater or equal to ten thousand so we create the right ten thousand here but this is bad practice I would much rather us prefer use the money dictionary with one hundred as a key again this makes debugging easier later trust me all right so if the amount left to pay is greater or equal to 100 and why are we doing this let me show you guys an example here look at this the first example here the amount what the cash was nineteen point five they gave us twenty dollars so that's fifty cents left right are we ever gonna possibly take out $100 bills from a 50 cent change No so we want this to be at least greater or equal to the amount money addiction in a hundred which is ten thousand our case cause we multiply everything by a hundred not only that we need some money to exist within our CID object as one hundred right so we need CID object of one hundred to exists so we could just do that now if that is the case then we have two scenarios either the amount left to pay is greater than the amount in the CID object in which case we just use all of our hundred-dollar bills or our CID object $100 bills are cash in drawer of $100 is more than the amount of to pay so we just kid them maybe one maybe two maybe three or so on right so those are two different conditions so we will do this if the amount left to pay is greater sure what two equal to yes let's do equal to creator or equal to CID object of 100 meaning the amount of the pay was more than all the hundred dollar bills we have left and we just gave them all of our hundred dollar bills right so if this is the case let's see what we're gonna do we're gonna do amount let to pay it we're gonna subtracted by the total amount that we have let's do this how about another structure that so can't amount to subtract it's gonna equal everything in our CID object of 100 and from amount left to pay we're gonna subtract to it - equals amount to subtract not only that we have to push to change to give right so let's push it to that change to give that push and remember that our substernal ray the first one being the actual key denomination and also the amount to subtract is the amount that we're gonna give however we got to be very careful because this is right now multiplied by a thousand by a hundred at me later when we return it we want to return it with the proper values right so how about we just the amount to subtract divided by a hundred that should work all right and finally we want to subtract from the CID object so CID object of 100 should just be now zero because we took out everything right else so that was the case when the amount left to pay was greater than auto amount that we had 100 doubles otherwise we have more hundred-dollar bills than they need to have so we don't even give them part of it so how much are we gonna kid them that's the question so I'm gonna right amount to subtract again amount to subtract it's equal to bear with me we're gonna do amount left to pay mm-hmm let's still amount left to pay we can't pay we can't subtract from amount left to pay a amount that is not multiple of 100 dollar bills for example we can't give them one hundred twenty-five dollars worth four hundred dollar bills subtracted from amount to pay look only subtract multiples of a hundred right so we want to divide this we don't see how many whole dollar bills we could get them so the way that we ratify this it's either right ten thousand here but even better yet we're gonna do money dict of 100 which will give us 1000 not ten thousand hundred make sure you spell it right because otherwise everything breaks and so this would give you like a decimal if ammount left to pay was like let's just pretend that we're not multiplying everything by 100 I know it's gonna be so confusing I'm sorry guys it's just a chore to have a script let's see a model of to pay was three hundred three dollars and we we want to see how much we have to divide right so in this case we're saying amount of to pay divided by 100 is like three point zero three right oh we don't want to take out three point zero three amount we want to map the lower this to get three now after we got three we just want to multiply it back by the money date of one hundred so this will give us three hundred dollars worth four hundred that we're gonna subtract from hopefully that made sense alright so now that we got them amounted to try we gotta do the same thing here subtract from the amount left to pay amount to subtract change to get push but how much are we pushing exactly we're pushing 100 again and we're pushing amount to subtract same thing as a matter of fact one hundred like so and CID object at one hundred we're gonna subtract from it not equal to zero design was attract from it the amount to subtract hopefully that made sense and hopefully that this is all correct if we can do this we don't do this or this otherwise we don't do anything with a hundred now pretty much we have to do the same thing here except change these words 102 what's the next one twenty dollars and then the next one to ten so that's a lot of repeated code right so one of the principles in programming is the try principle don't repeat yourself so what we're gonna do that's what we're gonna do we're gonna abstract this into a function that will take care of this for us so that we could just use it many times so let me just copy this whole big if statement let's make a function above our check cash register function our main function and I will call this cons I will use error function notation by the way because I just like that better all right we'll call this um what should we call it I'll never go with names guys so sorry about that how about subtract take out money from Cid how about that I don't know terrible okay but we got a pass in a couple things we have to pass in the amount left to pay we have to pass in D let's see cid up we have to also pass in the change to give array change to give and finally we gotta pass in the money type which is can either be 120 and so on now the reason why we're passing all of these in is because later we're gonna return the updated values of these three the amount of the pay will be subtracted if you could subtract an increment CID object will also be subtracted in that denomination change the K will also have been pushed if we subtracted any money hopefully that makes sense let me just paste this if pic if condition here now we we no longer when the reference is with 100 string but with this money type so we have one here if you're using PS code and just highlight this command D everything like so until you get everything until there so we have one two three four five six seven eight nine ten erase that and write money type hopefully did that correct hopefully now at the end of it all we have either subtracted things from this and add it to change the give and subtract it from say the object or if we never satisfy the in if condition meaning the denomination was too big so we can't take out any money from there or we had no denomination in that we should return what we have given the function right so no matter what the case outside of the eight we're just gonna return and there's multiple ways to return this I'm not just returning an array of these objects that I need I need a mountain F to pay CID object and change to game now let me explain what is going on here we're gonna erase all this stuff here and right we're gonna notice how we're returning an object here in the function that we have just created I'm just gonna destructure these three objects right away the way that we do that is just put an array right amount left to pay as our first variable CID object again and change to give as our turn and these three we run the structure from this function called take out money take our money from CID remember that first gets amount left to pay CID object change to give and the money type we're gonna start up as one hundred hopefully that made sense now this is not a good example here I want to test our code but this is not a good example because he only takes out from the quarters if you guys remember let me try to finding a better example here maybe this one is a good example although they do not have a hundred such a shame mmm how about this all right spice this example up a little bit and I paste it in here and before I paste it in let's just put a console log to everything actually why am i doing that we don't need counsel well because we have no returns yet I copied wrong so let me try copying it correctly this time as you go to here before the part like so now the reason why I'm trying to test out 200 right um the only issue is yes we do have one hundred dollar bill in the bank however the change is not enough they gave us a hundred to 326 I was like what 96 that's 70 74 that's not enough to give out give them any over 100 so what we're gonna do is we're gonna pretend I think it was 200 that way we'll give them at least 100 for sure okay so what I'm gonna do is here let's counter log after a hundred dollar bill taking out a hundred dollar bill still amount left to pay that's gonna be our first one console.log CID object is our second one and console.log change to give is our third so if everything went to plan amount left to pay should be what what did I say like a hundred 996 point something because we just took out 100 for the two hundred CID object should be all of this except with the 100's zero here and change to get although it's actually gonna be an object not not an array over a like because we converted it and change the gift should be an array with just this inside let's run this code and I pray and hope that we get that okay so we get one nine six seven four and that's is fine because if you divide this by 100 you get one hundred ninety six point seven four which is what I said earlier this also looks fantastic here this object and this also looks perfect so this is working as intended hallelujah all right now the only thing we have to do now is run this function for each of our denominations so I'm going to just copy the whole line bring it down here make this into 20 or not lower case all caps bring it down here ten make sure you write these correctly five make sure you also do in the correct order by the way from the highest to lowest one not dollar but one quarter dime nickel and penny all right so we have constantly updated our model to pay see id object and change the kid so let me just see if everything is correct here let me cancel a lot of three things again and this time I'm just and it is I'm all have to pay comma C at the object comma change get with the example that we have down here I'm gonna run the code and hmm why is our amount so high I don't like that if I feel like we're not subtracting from it why don't do I feel that but everything here is zero he said no that should not be the case that should not be the case so something wrong is happening here let's see what is going on let's see are these correct values here should return ignore the hundred twenty is sixty ten is twenty five is fifteen so something happened with the five do you see this it says 55 here although it should have been fifteen let me I'll change our value back to a hundred here because that's what it initially was right let's run the code again and we get twenty it's sixty ten is twenty five there's something going on with the five because they're giving us 55 although it should be 15 so let's forget the bottom of this what is going on here something what did I say something happening between the five so ten to five something happened mmm I feel like here we did something wrong five is 500 so that is all correct these are all correct except let's see is time I'm gonna console.log the amount left to pay because I also feel like that's not going down do you see this this is not going down why is the man left to pay not going down I'm gonna pray yes six string interpolation here and we're gonna write amount left to pay and that is going to be what that's not it okay Ahmad left to pay is going to be amount left to pay for money type that's one on the console.log and let's run this alright so notice this value is not going down every time so why is that the case are we not subtracting from amount left to pay that's what it seems likes going on so a lot console.log here a multi subtract among to subtract amount to subtract for money type and we have two if conditions so I also want that down here right let's run this code again and guys I'm sorry it is kind of frustrating but you know this is a process of figuring out these type of complicated algorithms so mana to pay for a hundred amount to subtract for twenty is six thousand right so do we not subtract from the six thousand why are we not subtracting huh I am so sorry guys hopefully most of you guys picked this up but notice how I spelled em I'll have to pay I capitalized a P but I for some stupid reason I made this lowercase so I just have to update all these amount left to pay with the uppercase version that was so stupid on me I'm terribly sorry alright so now let's see if our code runs as intended we get back this and that does look legit that looks correct so let's go back erase all of our console logs guys I'm so sorry about that hopefully you guys caught that before I did props to you if you did that is one of the reasons why we should use typescript but that's a discussion for another video let's erase all this console.log and now let's take care of our three conditions that we have we could either have insufficient funds closed if we use all of our money or open let's take care of the easiest one first insufficient funds we will have insufficient funds if the amount left to pay is equal to naught is greater than zero at me so if amount left to pay is greater than 0 then we have insufficient funds so we will say this that means we didn't take out all the money from our cash register so we will say return status make sure you spell this correctly insufficient sufficient funds and change it's going to be empty right that's what they want okay now we have two conditions closed if the CIT is a equal meaning we use all of the money in our CID now how can we know if we use all the money from CID what we can do is we could loop through our CID object remember it's a key value pair and we were subtracting from me from every time right if we add up all the values of it and if it's greater than zero then we know we didn't use everything in our cash register but if it is equal to 0 that means we use everything and this that's where this status closed situation happens so the way that we can do that is let's first grab all the objects all the values which is the amount from CID object so object dot values of CID object and let's status other than later so this will give us an array of all the values or maybe like 1 1 1 0 2 1 2 5 and so on and then what we're going to do is we're gonna call the reduce function again on this and we're just gonna add up all the values that we have so we're gonna have accumulator and the amount and we just can do this in 9 so return right away accumulator plus amount initializing the accumulator at 0 so this will give you Const amount left in CID okay now if amount left in CI T is greater than 0 then we're dealing with this open situation because we still have money in the bank otherwise we don't even need this else because we return something in here we're dealing with this close so if you're dealing with clothes let's do return status capital closed and change this very important change with cashing drawer as the value of the key change now remember we pass in the CID into our function we never actually altered that function we just made a new CID object which we altered this one but we never altered the original CID array over the radius nonsense here going on here so what we can do here is just return our CID and that should work alright now within the open situation this is what we're going to do let's see we have an object that we have to convert to this I don't know actually we don't because we were building or changed to give array right so this is actually very simple to return status open with change change to give so that should work let's see what the result of this cash register function is I get the status open 2060 it seems correct so what I'm gonna do is I'm gonna get all of this code here make sure you get all of our function and our dictionaries paste it over here and let's see if rico camp likes it and hand they do I was actually hoping that it works but it does work thank God now hopefully you guys were able to follow along with me here hopefully you guys are able to understand what's going on here if you don't try to mess around with they try to put console.log somewhere doubt areas that you don't understand that's what I do all the time what we what I want to do now is kind of refactor this code we have a lot of repeated code here look at all this stuff we're just calling it for each of these instance right so what do we do this above our money dictionary I'm just going to define denominations so Const D and I'm gonna make this capital cuz it's gonna be none we'll just use lowercase denominations and I'm just gonna hard code starting with 102 highest value first hundred twenty ten five one quarter time nickel make sure you write everything correctly penny and using our denominations now let's go back down here we got a lot of repeated code here so I want to loop through our denominations array and to afford each function call on it so let's see this denominations for each now we cop we passing a callback function here and we aren't gonna have our money type that's what we're looping through within our denominations and for each money type what do we want to do we just want to call this function here update our variables like so right so let's see I love to pay so I think this is good let me erase this 100 however and put money type here instead alright so I think that will do everything let me erase all of this duplicated code here and let's see if we get the correct answer for this one here I'm gonna run the code and it seems like we do our code looks a lot drier this time a lot cleaner let's copy this and see if pre code cap is happy with this result as well and they are alright guys thank you guys so much if you're still listening to this video guys I give you guys mad props hopefully you guys were able to follow along with this I'm sorry it feels a little bit confusing I know I had a moment there where I got stuck hopefully you're able to spot it uh I didn't wanna erase it cuz I kind of want to show you the process of how I go about debunking it grantee it was a very stupid mistake or spelling error but however if you don't use typescript and you just only do with JavaScript that may happen time to time so if you guys are starting out and you guys haven't touched a script I highly recommend you learn typescript and start integrating high square code however again that's not the point of this this is a frico camp tutorial I know that this was a little bit of a hard one so I'm gonna publish this on github and you guys can find that in the links below if you guys want reference to this but let me go back on free code camp so we have finally finished this section here javascript algorithms and data structure projects now I finished everything here in the intermediate algorithm scripting and also not everything here I don't know what you want else to do so guys if you guys have a recommendation if you guys have something that you want me to go through please post it in the comments below and I will look into it guys thank you guys so much for still listening in if you guys like my content please click like or if you don't like my content please click dislike and let me know why the comment section below and guys please subscribe to my channel you will constantly find these algorithm videos almost on a daily basis and I also post react tutorial videos or JavaScript tutorial videos it's whatever related to coding you'll find it here and guys happy coding have a good day
Info
Channel: Justin Kim
Views: 3,154
Rating: 4.9534883 out of 5
Keywords: javascript, algo, algos, algorithm, algorithms, es6, es2015, freecodecamp, js, programming, coding, code challenge, software engineer
Id: gkUosPt3c4I
Channel Id: undefined
Length: 42min 29sec (2549 seconds)
Published: Tue Feb 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.