Google Frontend Interview With A Frontend Expert

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up everybody how's it going i know i know you have all been absolutely dying for a new google coding interview well today is finally the day that we bring you a new google coding interview but this time it's not just any google coding interview this time it is a google front-end coding interview that's right when you apply to a big tech company like google or facebook now known as meta as a front-end engineer specifically they typically give you a couple of algorithm-style interviews as well as a couple of front-end specific interviews and so today we're going to be doing just that i'm going to be putting connor to the test a lot of you might know connor as the creator of front-end expert the front-end interview prep course on algo expert by the way if you're a front-end engineer preparing for your coding interviews or any software engineer preparing for your technical interviews then go to algo expert.io use a promo code clan clem for a discounted platform but so today i'm going to be testing connor this is a question that i created it is not yet available on front and expert though perhaps we might make it available soon um so connor is going to have to solve it last but not least we did film another coding interview on connor's youtube channel he just started his own youtube channel this is a css specific interview go check it out after you watch this video i'll put the link in the description in the comments below and with that connor are you ready for the interview yep let's do it all right i'm starting the counter now and let's begin so connor right now you are on the front end coding workspace that's where we're going to be doing the question but before we start i've told you to open another tab the questions list tab on front expert can you go to that tab perfect okay so you're very familiar with this page because you've created a lot of the questions that you see on this page now been here five times a few times exactly but i want you in this exercise or in this interview to actually recreate this page not the questions but the the look of the page and the functionality of the page so as you can see there's a lot of stuff going on on this page you have you know the progress bar for all the questions you have some buttons you have a bunch of uh columns with the categories of questions and the questions you know within each category are going to be building out the categories and their questions so you can kind of ignore everything that's above it and i have pre-written some css and html for you you don't need to worry about the css at all i'll just give you class names that you might need to use in the code but here you're really going to be concerned with javascript so if you go to the google doc that i shared with you before the interview now you will see on the first page a bit of data that's going to be relevant to you for the interview so the first piece of data that's going to be relevant is this uh api base url that you see at the top this is going to be an api endpoint that you need to uh hit and get you know data from what it's going to return to you is a list of questions that you're going to want to render on the page now the form or the the the structure of the questions is going to be this data that you have right underneath the one that you're highlighting exactly you can see that every question is an object it's got a category name that's going to be the name that you're going to want to render in the columns and then it's going to have a name that's going to be the name of the question that you want to render on the page and then it's going to have an id this is a unique identifier you don't really need to worry about it for now but just know that it's there and so finally underneath this you can see some html this is the structure of the html that you want to render on the page every category is a div with a category class so pretty straightforward it's got an h2 heading with the name of the category like html or css and then every question is within the category div every question itself is a div with a class question and uh a h3 heading of the question name and so the final point if you go back to the coding workspace now you are going to want to render all these categories and questions within a div that we have on the page that i've pre-written for you it's a very simple div with a class wrapper and that's it okay that's all you need to know okay sounds good so i guess let's get started by let's first just make a request to this api and get this data back and i think what we want to do because this is sort of grouped by by the category whereas this is sort of just like a big blob i think we need to sort of take this data from the api and sort of transform it into data that is grouped by categories so probably like a map of the category to the i guess an array of these question objects so that we can better create this okay so let's come over here and i will paste in the uh constant and looks like that google docs changed the uh type of string okay so let's so let's start by just first getting that data like we said so i'll create a function this will be an async function since we're going to need to use fetch so we can say async function and i'll just call it fetch questions okay so in this function we need to first call fetch and i take it this is just a get request and we don't need any like parameters to the url anything like that yep no parameters just a get request cool so we can just say fetch the url that you gave me and you will need to await this so let's say const response equals await fetch and then the response is going to be json so we can say const questions equals await response dot json and are we okay with not doing any like error handling here can we just assume that this is going to return to 200 and everything's okay yep for the sake of the question don't worry about network issues or other issues like that okay cool sounds good so this should be this array here right so that's let's start by just returning that here so we can say return questions so this will return that array and then we also are going to want to take these questions and transform them like i said so let's make another function that is going to take in the questions and return them in this sort of transformed way so we can say function and let's call this i don't know let's say git questions by category okay and this will take in the questions which is that array and let's see so we need to first of all iterate through the array and add to some object based on the category so we can first of all create the object so const questions by category is going to be equal to just an empty object to begin with and then we can loop over the questions let's say questions dot for each and for each question and make an arrow function so what do we need to do here so we need to add two questions by category at the uh the category as the like the key but we need to know if that's already there or not so we can say if uh questions by category uh and we need to do i guess has owned properties so we can say if it's is it object dot has own maybe it's just questioned by a category that has own property i always forget if it's part of the object class or just like this but it has own property i think it's this we'll see in a moment i guess see if this works uh so we need to take in the uh question category so we can say question dot category okay so this is going to be the case where we already found some question that is in this category and in that case we can say questions by category at question.category is going to need to add this value so i guess we can use the push function so we can push the question okay and in the other case we need to create a new array so we can say else and i will copy this so otherwise we need to set this equal to a new array so we can say a new array with the question in it okay okay and then all we need to do is just return questions by category i think so return questions by category okay so now we can fetch the questions and then we can get them sort of by category and i think the last thing we'll need to do is actually sort of append these to the page so wrong tab so we'll need to append them i guess like this i'm just going to copy this leave it in a comment so that so i don't have to keep going back and forth yep okay okay so let's create a function for this as well so we can just call it like create category so first of all we want a function to make this and then we will in that function sort of iterate through the questions for that category and create all these divs okay so let's do function create category okay so the first thing we need to do is just create this wrapper div we have okay so we can say const div equals document dot create element and we will create a div and we can say div dot class list dot add the category class okay and then the first thing inside of the div is the name of the category and then h2 so we can create that h2 const h2 equals document dot create element and h2 and the h2 is going to have some text content so we can say h2.text content is going to be equal to the category which i guess we can make a parameter and then we need all of the questions so we can say questions and let's iterate through the questions so this questions is going to be the array that we added in questions by category so it is sort of this array or the array that we were pushing to so let's say questions dot for each question and let's see what do we need to do so we need to create a div with the class of question so const question div just to give it a different name than the outer div is going to be equal to document dot create element of a div and then we need to give it the question class so question div dot class list dot add question and then it needs an h3 inside of it as well so const h3 is going to be document dot create element of an h3 and then we need to set the text content of that h3 so h3 dot text content is going to be equal to the question and we need to get from the api the name so question.name yep okay and then i guess we need to actually append all these things to each other so we can say question div dot append dh3 so this will add the h3 to the question div and then we need to add the question div to the category div and to rename this just so we can keep track of it better to category div okay okay so then we can say categorydev dot append the question div and since the category div isn't on the page yet here i don't think there's really any reason to use fragments or any of that because this isn't going to cause any repaints or anything like that yet and then we can say return the category div okay so this qui this uh function takes in the category and the questions and it returns a div for that category okay so now i guess we need sort of like a function that just uses all this code or we could just do it at the top level but i will make just a wrapper function for it all so we can say function fetch and append questions okay and let's see so this function needs to first of all call fetch questions and so this is an async function so we need to await this so this needs to be an async function as well so const questions equals await fetch questions and then we need to call get questions by category to change this into that object that we can use a little bit easier so we can say const questions by category is going to be equal to get questions by category and we can pass in questions and then for each category we need to call create category so let's iterate through this object we created to go through all the keys and for each one we will create a category and then we can append that category to the page does the order that we do this matter at all like does it matter if it's like html first then css like it is on the actual front-end expert page or can we just do it in whatever order it came back so that's a good question like like you pointed out on the front expert page there is an order like the order is always the same for the purpose of this question don't worry about the order um so however you know the way you you structured your code uh all the categories are going to be in your object don't worry about you know what order they're in the object in okay cool awesome so to iterate through the object i guess there's a few ways we can do it but i kind of like the object.entries functions let's do or for const and we'll have the key and then the values i guess the key is the category and the value is the questions and this will be of object dot entries questions by category okay so this just iterates through the object gets every category and the questions for that category so then we can say const category is equal to create category and we can just pass in the category and the questions and then we just need to append this to the page so we can get that wrapper that you said we had so document.getelementbyid the wrapper and i'll do this at the top of the function just so we only have to do it one time or at the top of the for loop so okay and let me just double check um it is yeah it is an id for the wrapper okay cool so we get the wrapper and then we just need to append the category to the wrapper so we can say wrapper dot append the category and let's see oh it's reusing the name so we can say category div here okay div like that and let's see so now we need to actually call this function and oh it actually worked on the first shy okay and uh connor my my my shared screen is a tiny bit buggy so i can't fully see your output but in the create category function that you have did you make sure to append the category heading the category heading oh i did not good call so i'm assuming it's not rendering right you're not getting the capture yeah can you see like anything or can you just not i can see i can see your code i can see your code for whatever reason but don't worry about the output i'm you know again trusting what you're gonna see okay i'll just tell you it's right so uh okay so yeah we need to append to the category we need that uh let's see let me look at the okay so we need an h2 with the category text okay so i created the h2 oh yeah it looks like i just never appended this yep uh yep okay so we can say categorydev dot append dh2 okay cool and now that is rendering okay so you're getting all four columns with um category titles at the top and then the questions list right below them right yep and these look like the correct questions and categories okay cool so we are now going to add a little bit of uh more complexity to this page because you know as you might remember on the questions list page there is more stuff going on like for example uh you can see whether questions have been submitted on the questions list you know they have a little circle at the side of them that says um you know like it's like green or red i guess yours are all green because you've completed uh correctly submitted all 25 questions but so that's what we're going to be handling now to kind of explain to you how that works uh that is you know user data in other words the questions list that you fetched before that was static data that you know every user uh shares right the the static list of questions but here for submissions it's relevant to your account so you're going to need to issue another api call and if you go to the google docs page that i gave you on the second page there is all the information related to these submissions so you have a new api call that is going to return to you your account specific submissions for every question so that is an array of objects where every object has a question id which is the unique identifier of the front-end expert question and if you remember correctly in the first api call every question object also had an id that was a unique identifier even though you didn't use it so far and then the second entry or property in these objects is going to be a status and that's going to be uh one of three values correct means that it is um you know you successfully submitted the question and that should mean that you render a green circle incorrect means that you render a red circle and partially correct means that you render a yellow circle for questions that have never been attempted meaning you know you never tried to submit them they will not be returned in this list of submissions at the api level and so for those you're going to want to render a sort of empty circle now once again i have given you i've pre-written the css for these circles if you scroll down a tiny bit below you'll see what the html should look like basically every question should have an additional div added right above the title that has a class of status it always has a class of status and then depending on the submission whether it's correct incorrect partially correct or you know not there you you add a different class so the classes are going to be actually the same uh strings as the status strings except in lower case and it's a hyphen instead of a you know underscore for partially correct and if the submission has not been you know submitted or there is no submission then it should be unattempted the word unattempted i know that's a lot of information uh yeah unattempted feel free to like you know ask me to to repeat some of this when you when you write it um so that's what you need to do and i guess one final thing on top of this you might remember that on the questions list every category at the top in the heading shows how many questions out of how many have been submitted so like you know you have dom manipulation eight out of eight so you're going to add that uh you know piece of the category title as well okay okay sounds good so i guess let's start with just the api again okay worked out last time so we can fetch all of this and this gives us an array back but i think we might want to transform this one again like we did last time uh because the array is not very useful i'm just sort of thinking about we need to iterate through every single question and then say we're on like item cart to check if item cart was successfully submitted we would have to sort of search in that array every single time so if instead we made an object we can do sort of like one pass through this array to make an object that is going to be question id to the status um and that way we can do those lookups faster and then we can sort of add this end when we build the dom so let's do that let's come over here and in the fetch questions function i'm going to also get the submissions so i'll just change this name to fetch questions and submissions okay and see so where did i use this to make sure there it is okay so in this and because i copied that i lost the copy paste of this okay okay so yeah so let's also get the uh the call to this submissions api so const submissions response is going to be await fetch and let's paste the api up here looks like we have the same issue with the string okay so fetch the submissions api and let's see so the way this is going to work right now is that this will happen and because we awaited it i don't think this other fetch call is going to happen until the first one finishes that's correct um so let's see we can do instead promise dot all i believe which takes in [Music] uh i believe is it just taking an array of the promises yep it's an array that's what it's going to do yeah yep cool so we can pass in both of our calls to fetch like this okay so we have both calls of fetch are happening at the same time now so we don't have to wait for one to come back i'll get the other and this is going to return i believe it's a after you await it it becomes an array right so we can say the uh questions response and submissions response is going to be equal to and we'll weight this so we're just destructuring the return value and then we won't need this code anymore okay so now instead of getting just the questions we need to get the response that from both of these uh these two items so i guess we can actually just return uh the response json we don't really need this extra return line anyways so let's return another call to await promise.all and this will again take in that array and we can say question response dot json and submission response dot json okay and now when we use this function it's going to get this array with the sort of return values of both so let's go back up to where we use this and instead of just questions we can get questions and submissions okay okay and then we need to do that sort of transformation we talked about with submissions so let's say const submissions uh by id i guess is going to be equal to get submissions by id and we will pass in the submissions okay so let's implement this function so i will put it down here by this other one just because they're sort of similar so function get submissions by id is going to take in the submissions and it's once again going to return an object so const submissions by id is going to be an empty object and we need to iterate through all of the submissions so submissions dot for each submission okay so in each submission i think we need to do basically the same thing we did here although i guess we only have one submission per question right like there's no way that it returns two submissions for item cart for example right that's correct we only return the what what is stored in the back end as the best submission for a quest okay cool so then in that case i guess all we need to do is just add the value so submissions by id is going to be uh submission dot uh was it just called id question id question yes to make sure the punctuation right and all that is going to be equal to and we can get the submission dot status okay so this function should now hit in the mic this function should now get an object that is going to have the submissions as an at or it's going to have an object with these submissions as keys or the question ids as keys and the statuses as the values so we can say return submissions by id okay so this gets all of those submissions by the id and now we just need to actually use this although the output is no longer working so i'm curious something that was done here is probably a little bit off uh let's see um so question response wait promised at all do you happen to know if this promised at all syntax is correct i think it is the promised little syntax i think is correct um see uh i guess i could open up the console in just in the inspector to see if there's an error message you can alternatively um if you yes alternatively um it might be that you rename the did you rename a variable name something uh where no never mind i thought you i thought you had um but if you want you can open the console okay yeah i'll just do that why gonna be the easiest way to see let's uh let's just rerun uh api is being blocked by course can you scroll up and look at the constant that you're using for the um uh you're you need to add a www dot algorithm love some cores i must have given you the wrong yeah i gave you no worries that the google doc okay so now now we have the output again so that's exciting okay okay so now we have submissions by id so now we need to when we create the uh [Music] the category i guess we can also pass in submissions by id and then when we call create category we will use that submissions by id parameter and we will use it to create a status for each question so where does the status go in this html so div above the h3 question name yep okay so we have the h3 here so above this we can say const status equals document dot create element of a div and we can say status.classlist.ad and it had a status class is that right yep and then it had another class based on the submissions by id so we can say status.classlist.ad and we'll do submissions by id and we need to get the uh the question id so we can say questions or question dot uh is it just id it's just id yep just id yeah okay submissions by id questions dot id so this would be the status if there is one um but if there isn't one then you said we need simply uh what was it on something unattended so it's unattempted for if there is no submission unattempted and then yeah but this one i think needs to be lowercased yep lowercase and for partially correct it's a hyphen not an underscore partially correct okay uh i'm actually going to do this on another line then just so this doesn't get out of control uh so let's say status class so const status class is going to be equal to this uh dot to lower case and uh and then you said we need to replace the underscore with a a dash a hyphen yep all right gotta love the css syntax versus you know api syntax i guess i think this this optional chaining thing will work i'm actually not 100 sure i always forget the exact syntax with function calls but okay so we can replace the underscore with the [Music] the dash yep okay so i'm not 100 sure about this we'll see if this works in a second when i actually add it so let's add the status to the question div so question div dot append the status okay yeah that did actually surprisingly seem to work so this worked so we have the status circles now but then you said we also want let's see how this looks to add to the name this sort of dash and then the completed number so it doesn't matter like the the exact string doesn't really matter but it's basically you know space hyphen space then the number of correctly submitted so not partially correct you know the number of uh of correctly submitted space slash space the total number of questions in that category i see okay so we need to keep track of uh which ones are correct or not so let's see let's just keep a counter say let correct count equals zero and uh when we do this let's also check to see if this is correct uh so we can say i guess i'll do it down here say if the status is it's going to be all capital correct right yep so in that case we can say correct count plus plus so we'll just increment this number and then at the end so rather than doing this text content here i will do it at the end um i guess we can actually just edit it for now so let's come down here and say the h2.text content is going to be equal to and i'll use the template literal so we have the uh was it just category yeah so we have category and then you had a space was it a dash yeah so we have a dash and then we have the correct count and then this is going to be is it uh forward slash like division yeah divided by you can put a space between the forward slash just for like this yeah okay and then we need the total number the total number of questions so questions dot length okay so that seems to work it's a little sketchy that we're changing the text so i don't actually need this line up here okay but i will go ahead and still append it first because otherwise the order is going to be wrong if we create this at the end i guess we could prepend so i'll do that just so this is all sort of in one place okay uh so it's oh it's not like that oh that's not where that's not where that needs to be we need that under yep down here and then we need to do this after we change the text content we will prepend this instead of append so that it shows up at the beginning okay and get rid of this empty line and that looks like it's working so html we have two out of four css one out of five js three out of eight and dom five out of nine perfect awesome um and uh so your code as far as i can tell looks correct just again because for whatever reason i can't see the browser output in my shared screen um you can confirm that you're seeing you know the the correct sort of um you know circles like for example array methods in javascript is red uh d bounce is yellow this and promisify are empty this and promise if i yeah those are both empty okay awesome so listen uh we have about a little bit less than 10 minutes left so um i guess a couple things that i wanted to to talk about one thing is just you know do you have any you don't have to change your code at this point but just any idea or uh you know insight on how you would maybe like clean up your code if you had a bit more time i know that by nature of this being like vanilla javascript it's you know not very um clean but you know would you how would you rearrange your code to maybe clean it up a bit right yeah step one would definitely be to use react instead um let's see so don't tell that to a google coding interview by the way [Laughter] sorry we can use angular uh so one thing i was thinking about while i was writing this is we have these two objects um and it might make sense to sort of just create a single data structure for both of them i think it might be simpler to have every all the data sort of in one place um store the submissions on each question yeah i see yeah so essentially to in this transformation process we did at the beginning uh add the submission here rather than having that sort of secondary uh object for it okay um see i think that would simplify things and we wouldn't really need this anymore uh so this would become like a a that array that we have would become i i guess it'd just become an array of those objects that includes the status okay let's see what else could we do uh we could probably break this function up this create category function um so we have like where we create this question div so we could probably create a new function that's like create question just because this function's long like i can't even put it all on the screen at one time so yeah we probably want to break this up simplify things a bit um okay yeah i mean that that means probably oh we could probably use like a array reduce instead of this this thing that i did but yeah it's a little bit it's it's a tiny bit awkward to like keep track of that correct count as you're creating the questions but yeah i mean there's there's kind of an argument for and against i do think that for readability probably would be better to have like you know counting the correct count like in a single you know uh reduce or something like that um okay overall especially because i meant that this was like at the end like having the first thing in the dev be the last thing we add to the div is a little awkward but yeah um overall it is just a little bit annoying that you have to deal with all the you know adding classes and text contents and vanilla javascript and that also just makes the code a little bit um more annoying to deal with but i think that the the suggestions you you gave made sense so in the last six minutes of the interview i want to introduce one line one one last piece of complexity um we're not gonna have time for you to code this out so perhaps you could just like think about it and explain to me at a high level how you would do it but if you go back to the to the questions list page on on the real website um you'll see that you can group uh the questions either by category which is the default or randomly so randomly you know it's like a random order of questions and all four columns and so i guess my question would be um how would you implement this in vanilla javascript keeping in mind that it's probably like really tricky with vanilla javascript you know for this this is where you know state management and libraries like react really do shine but yeah how would you how would you go about implementing this so so when you hit group randomly i actually had never played with this very much when you hit this is it the same groups every time essentially like it's not like regrouping when you do this uh sort of sort of actually uh if you if i remember correctly once you like edit the order of the random questions we save your order so then it remains the same and within a single session it remains the same but i believe that if you never saved your order and you refreshed the page and you regrouped randomly it would be a new group i see okay okay so i can sort of think of two ways we could do this um so the first would be when we do this uh sort of transformation of this to be that object by category um we could instead just sort of have an array of however many random categories we want so we could call the categories column one two three and four and then when we choose a category for it just um sort of randomly choose one of those four categories rather than using the one from the uh api response and then whenever you click this group randomly button we would basically do everything we had done before again with the one difference being we don't make another api request of course um so we would just take our original returned value from the api and uh sort of remake it into a new array um or we could also just do that make that array ahead of time or that object ahead of time when uh it's like when the page first loads make this object that goes from the uh category to the arrays like we have but then also make the second object that we're not using initially of this just like the random categories and then when you click the button just sort of change which one we're using and the other option i could see so that one would sort of when you click the button it would clear out the html and then it would just generate the html again but for this new object we have yeah the other option would be when we generate the html to generate the html twice and just sort of display none the one we're not currently using and then treat these sort of like tabs so when you click on one of the tabs it would set sort of this whole wrapper to display none and replace it with a new wrapper and then same thing when you go back and forth we wouldn't be generating all this html again we would just be sort of replacing it um yeah i think that way might be a little bit cleaner just because it means you only have to calculate it once so if a user does this and just keeps clicking back and forth we would only have calculated it one time yeah i think so too i think it would be a little bit cleaner just to prevent that operation obviously especially with front expert when you're only dealing with 25 questions it's not really like you know very uh right yeah intensive of an operation but still um it it just makes a bit more sense to do that i think and then yeah obviously the more questions there are or the more functionality there is for example on algo expert you also can group by difficulty and you've got 160 questions you can imagine that pre-computing it might make more sense especially if you're dealing with saved orders that are also returned by the api like a saved order of questions um but okay listen i think that is perfect that about wraps it up we just have about you know one minute left on the clock so we're gonna wrap up the interview um interview over i will just give a tiny bit of feedback um off the top of my head i think you did great i think uh you definitely got you know you you solved the question um and you dealt with the complexity of the question as best as you could uh there wasn't too much like you know this is where front interviews sometimes are a little bit different than let's say algorithm interviews um there wasn't too much like uncertainty about this question you know there weren't really too many clarifying questions to ask right up front um i think that the few that you that you did ask made sense like do we need to order the categories in a specific way or um can is this like a normal get request or do we need to error handle these kind of things but overall you know pretty straightforward um i think you did a good job of of communicating you know what you were about to write out in code before writing it out which helped me follow along and um yeah i mean you clearly demonstrated a good uh good mastery of like javascript and all these things uh the promise. always a good touch um you know to not have to not wait on two api calls um which really signs the more api calls there are because i do believe that on the real front expert page they're like they're more because you're also fixing other user data and all that for like custom order and all that um so that was very good yeah you you know you used you know good javascript uh syntax and modern practices like async await and uh you know chaining optional chaining and the the double question mark i don't even know what that is called knowledge coalescing i think no it's coalesces yeah um so yeah great job um and uh i apologize for having giving you the wrong api endpoint for submissions uh without the wwe but um yeah some debugging to it exactly um but overall a really great job and i think this would be for for a front-end interview this would be a um a strong hire um which perhaps is not uh too uh surprising given that you are after all the front and expert so i'm hired you're hired to but no we don't want you to go to google you say you stay at algo expert in front of expert all right so you're hired just for just for as a as a sort of like ego boost i'll take it but okay so that is gonna wrap up the interview i hope that you all found it uh very useful insightful entertaining maybe uh if you did don't forget smash the like button subscribe to the channel if you haven't already check out the other interview that we did on connor's channel we're actually about to film it now but it is going to be a pure css interview it's actually going to be the css version of this question and uh show con or some love subscribe to his youtube channel and otherwise uh don't forget to follow me on twitter and linkedin if you enjoy short formatting content instagram if you like pictures and i will see you in the next video connor say goodbye see ya
Info
Channel: Clément Mihailescu
Views: 770,124
Rating: undefined out of 5
Keywords: google frontend interview, google frontend interview questions, google frontend interview preparation, frontend interview google, frontend interview, frontend interview questions and answers, mock frontend interview, technical interview with a frontend engineer, frontend interview questions, real frontend interview, google software engineer interview, frontend coding interview, mock frontend coding interview, front end coding interview, front end interview, google interview
Id: ai1zmNO5Z3E
Channel Id: undefined
Length: 47min 58sec (2878 seconds)
Published: Wed Apr 13 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.