Good afternoon and welcome to this talk on approximate algorithms for stream data summarization. My name is Himadri Sarkar and I work for SumoLogic. Let me start with a demo which will set context for three different approximate algorithms that we will be talking later. Manages and analyzes machine generated data. This is the SumoLogic web application which can be used to debug and analyze already ingested log messages. This search feature allows you to identify important messages and extract meaningful values and metrics out of them. When you're dealing with millions of log messages, at times it is difficult to write very specific and targeted queries. For instance, this is a query which I ran a couple of minutes ago and it produced around 1 million results spanning across 71,000 pages.  Now this is not an ideal state to be in. So what you do is, you start with your initial query and further refine it to return lesser results and subsequent runs. For that we needed a feature which can assist our users to drill down further into such a massive result set. First let me explain to you briefly what is that I am trying to search. This query here tries to do a keyword search over log messages. These are the keywords. Then it tries to identify adjacent string within the log messages and extract some interesting fields from them. Generally speaking it is trying to get metrics corresponding to queries that are executed by our customers. Along with the query we also supply a time range for which we want to search over the data. Now let me run the same query in a separate tab. When I press the start button it kicks off the search. Now we don't wait for the search to finish. As the search starts producing results they are streamed to the UI starting from the most recent message to the least recent ones. Remember these are server logs, each of them have a timestamp from which recent scene is derived. Along with that we also display results related to statistics of each field present in the output result set. We call this the field browser. For instance if I zoom into the left bottom corner you can see that while the query is returning results these values are getting updated in real time. Now what do these values represent? These are the various fields that are present in the output data. You can identify them as columns in a big table. Besides each field name we display the number of distinct values seen so far. So if you look at this field customer ID we have seen 566 distinct customers so far. Going further this number 8000 represents that we have seen 8000 distinct queries so far. And remote IP addresses shows that the users have been firing queries from 200 distinct IP addresses. Now let us look at each of these fields in detail. If I click on customer IDs then it shows the top 10 customer IDs and their frequency of appearance in the logs. It also shows histogram which is updating in real time as you can see. And it gives us a relative idea of this frequency with respect to the other top 9. Similarly for query for this particular window we can see that it is displaying the top 10 queries with the frequency of execution. And if I hover over the queries then it also shows the complete query. You see that we have seen around half a million distinct session IDs still now and this particular window is displaying the top 10 session IDs by their frequency of appearance in the logs. Previously we were trying to analyze logs corresponding to all the customers. Now let us analyze logs of one customer who is running the most number of searches. So I go to this customer ID field name. I click on it and I get the list of top 10 customers. Now to drill down into the search I just need to click on this. And then it will open up the same search in new tab but with an additional filter pertaining to that particular customer. The search has started and the field browser has started populating again. Now you can see that the customer field has only one distinct customer because we applied that filter. Now what you are seeing is data pertaining to only this particular customer. Now you find that there is just one exit code till now and its value is zero which is very good. It means all the queries of this customer have executed successfully. We also see that this customer is executing queries from three different IP addresses. We have returned till now in them there were 17,000 distinct session IDs and going further at the bottom we see that we have utilized 35 host machines to execute search for this customer. Now you have lots of data points to guide your search nearer to the desired result and hopefully we will be able to fix the production incident. Alright so that was the demo and we were trying to do two simple things in that demo. The first thing is we were trying to count distinct values in a stream of data and within each field we were trying to count top ten values. So that seems to be a very easy problem right. We do counting daily in our lives and lots of times you might have done in the code that we have written. So what are the traditional approaches of solving these two problems? It's very easy right to count distinct values you use a hash set for each incoming element you insert that element into the hash set and when the query comes for distinct values you just return the size of the hash set. Similarly for counting the frequency of each distinct value you can use a hash map. Now hash map will contain the value and their counters and you will keep incrementing them. So let's try to apply scale to this simple problem. Now what happens when you want to count one million distinct elements where the size of each element is one kilobytes. So it simply translates to the storage requirement of one gigabyte and say you want to do this for 200 fields then you multiply it by 200 and you need 200 gigabytes. I'm not saying this needs to be a main memory that can be any kind of storage but still it requires 200 gigabytes. Additionally if you have to keep counters corresponding to each of the distinct values from this calculation if you use long values for them you need additional 1.6 gigabytes apart from the 200 gigabytes I showed you already and there is one more thing. Then such queries need to run on one single machine. So we should multiply 10 again which translates to 2 petabytes of storage per node. I'm sure no one will allow you to build such a feature which has this kind of requirement and it's just a single feature not a complete product. So there is something we want. What we want is a data structure which has constant memory footprint. Additionally what we also want to do is we want each of the operations on the data structure to be inexpensive. Now we cannot have a way with everything right. We have to trade something in for achieving these kind of things and let's suppose we agree on trading some amount of correctness which gives us this kind of results. So before I go into the solutions of the two problems I described let us try to gain some intuition from set membership problem. I'm sure many of you have solved this problem in your production systems or have thought about solving it. So what we want to have is a memory efficient data structure that can be used to check membership of an element E in a set S of elements. So as we discussed that we are ready to trade off some amount of correctness in view of that, I claim that there is a very simple data structure which has just two components. One is a bit string, all initialized to 0 initially, and k hash functions. Now what are the property of these hash functions? They can take in any arbitrary object, they may be integers, strings or anything, and what they will return is an index into the bit array. So now the stream will contain two things. The operation that has to be performed and the value of the particular element on which that operation should be performed. Now let us see how we will keep track of what are the elements present in that particular set. So for each incoming element, we have this operation insert. It will go through all these hash functions, there are k of them, and it will generate k indices into this bit array. So what we will do is we will go to those indices and we will turn on the bits. That will help us keep track of, what that will do is it will say that this particular element is present in the set. Now you see one interesting thing. We are not storing even anywhere. We are just storing the information that even is present in the set. Now we inserted n elements. So lots of bits will get turned on. Now what about query? When an element en plus 1 comes and it asks whether I am present in the set, what do we do? We do a similar kind of application. We go through all the hash functions, we get the indices, we go to those indices, we fetch the values, and we do an and on that. Now if the and returns 1, that means that this particular value is already present in the set. If it returns 0, then we say that it is not present in the set. But we should be careful about something. It is quite possible that the elements e1 to en that we inserted prior to en plus 1, a combination of those have turned on all the bits for which en plus 1 would have been turned on if it was inserted. So this gives us false positives. But we will see that we can reduce this value of false positives to such a small probability that this particular data structure will still be useful in lots of cases. So without going into the theoretical proof, let us directly jump to the results. So what, so to use this data structure you just need three things. N, m, and k. N is the total number of elements that you expect will be coming in the stream. M is proportional to the memory that you can utilize for this particular data structure. So what you do is you use the second formula first and compute k. So you get the number of hash functions. Now once you get k, you plug n, m, and k into the first formula and you get the error. If that particular error is suitable for you, you continue with this, these values of n, n, m, and k. Otherwise you go back, you increase the memory and you get the new value of error. You do this iteratively. So this lays path for the first approximate algorithm that I wanted to discuss and this will help us in gaining intuitive understanding of the original solutions to the problem that we discussed. So this is, I'm sure many of you know about this and I've used it. We just described what are bloom filters. So from our understanding of bloom filters comes a very interesting family of data structures. Those are the sketch data structures. So imagine these two images. One of them is raw and one of them is JPEG. The raw image is 100 times bigger in size as compared to the JPEG image. But both of them convey the same meaning to you. Then why would we need to store the raw image? So this is something similar we did with the bloom filters. We did not store the exact values. We did not store the exact ease. But still it was able to tell us whether any EK was a member of the set. Now, sketches have a very good property and that is they can be aggregated. Now that gives us two benefits directly. The first one is if your data is spread across multiple machines, then you can compute sketches on those individual machines. You can just transfer the sketches to one particular machine and aggregate them. For instance, if you were to do this for bloom filters, then you would compute the bloom filters on individual machines, bring them to one machine, and do an OR operation. And that gives you the picture of entire data that was collected in N machines. And N can be very big. All right, so we just wandered off to some other problem. Let's come back to the problem that we were looking at and solve that. So the understanding of bloom filters will use our understanding of bloom filters and use it as a role model. So what we'll do again for counting the frequencies that we will not store the exact elements, but we will store just the counters. In previous case, that was a membership operation. So it was zero or one. In this case, we'll have to store either integer or long counters. And bloom filters used 1D sketches. Let us improve upon it and use 2D sketches. All right. So this is how the data structure looks like that we will use to keep track of distinct counts. So there are multiple bit arrays. Basically, there are d bit arrays of size w. And again, our good old hash functions are there. There are d hash functions. So how does an insert operation for tracking the count works? So whenever we get an element e from the stream, we pass it through these hash functions. They give us d distinct indices. We go to those particular indices in the respective bit arrays and we increment the value. So we are incrementing this time because we want to keep track of count and not just setting the bit to on. And how does query works? So when you want to query, how many times we have seen x so far? What you do is you do something similar. You pass it through these hash functions. You go to those buckets. You fetch all these values. And your frequency is minimum of all the values that you get. Now we'll see why we are taking minimum. That is because of collisions. So for instance, take this example. We inserted x1 and we inserted x2. For h2, that is a second hash function, they both mapped to the same bucket whose value is 21. That means when we insert x1 and x2, every time it goes and increments the same bucket. So this is the overestimated value because two different elements are going and incrementing the same bucket. So that's why we take the minimum from all the bit arrays because that value that we get, it has the least amount of error. And we will see that by choosing appropriate values of the depth and the width of this structure, we can have bounds on these errors. Again, very simple formulas. Let's go to the results directly. So we have epsilon, which is the accuracy that we want to have. What that means is epsilon is the maximum error that we can tolerate in any frequency value. And delta is the probability with which we want epsilon to happen. So this very easily gives you the value of width and depth. Width will be given by e by epsilon, e is the base of natural log, and depth will be given by a ceiling of, again, natural log of 1 by delta. Very simple formulas, and it really works. But you should remember one thing while using this particular data structure. Suppose you have counted all the frequencies, and you sorted them, and you plot that frequency distribution, then it will look like this, right? Because you sorted them. Now the estimates near the y-axis are more accurate as compared to the estimates at the end, or the tail. That is because many of these estimates at the beginning will also go and increment the buckets in which the tail elements lie. And that will lead to higher overestimation in the tail elements. That's why what we do is we generally use this data structure to keep track of top k distinct frequencies. And that's what we did in the demo that I showed you. We kept track of top 10 distinct frequencies. Now to keep track of top 10, you have to use an additional, very simple data structure. Every time you insert an element into the previous data structure, you get the final count. And then you check whether it can displace any of the elements in the top 10. If it is true, then you insert it, and one element gets spilled out. So every time you keep track of top k elements. So what I just described is a very useful data structure known as count min sketch. This is not a new data structure. It is a time-tested data structure, but it has become very popular today because of huge amount of data and the need to process it fast. All right, coming to the second problem. How do you keep track of cardinalities? Now if you had used hash map, then you could have tracked both frequencies and cardinalities. But we didn't store the values. So it will be very difficult to go back to using count min sketch itself to keep track of cardinalities. So for that, we'll look at this another data structure. And before we directly go to the data structure, let's have an intuitive understanding. So this time, our hash function is a little bit different. It is not outputting integer or long values, but what it will output is a real number in between 0 and 1 for every incoming element x. So and the good thing about Hx is it will distribute all the elements uniformly across this number line, which is from 0 to 1. So what it means is if you insert 10 distinct values, then they will lie at a distance of 0.1 from each other. So this good property gives us a very good insight into how we can compute cardinalities. What we can do is we can just keep track of the smallest hash value that this data structure has produced. Now, because our assumption was that this particular Hx will uniformly distribute the values, that smallest value will be the distance between any two elements. So to count, to estimate the cardinality, you just divide the total range that is average distance between any two elements, that is 0.1, and which gives you the cardinality as 10. And in actual, we had eight elements. So this is very much near to the actual estimate. Now, of course, you will say that keeping track of the smallest one might be inefficient. It might give a huge bias. So what we can do is we can go forward and keep track of the k smallest values this time. So even this is not accurate. For this case, say the kth smallest value seen is 0.3, you plug it into the formula, you get 6.7, but that is more nearer to the cardinality that we got in the previous example. This is the basic understanding with which cardinalities are determined using approximate algorithms. So let's go ahead and change our hash function again. This time, say our hash function outputs a bit string in which each bit has 50% probability of being turned on or off. Then we can easily say that there is 50% probability that any of the hash values generated will have one in the first position, and it can have anything later on. And we can say that there is 25% chance that any of the hash values will have 0.1 as the first two bits and anything rest after that, so on and so forth. So what this tells us that if we hash four unique things, at least one of them will begin with 0.1. If we hash eight unique things, at least one of them will start with 0.0.1. Conversely, let us converse them, and then we'll see that if the lowest index of one in the bit array is two, then you can say that there are two raise to two distinct elements present in the data structure. If the lowest index of one is three, then we can say that there are two raise to three distinct elements in the data structure. And I'm counting one from the left-hand side. But again, there might be some skewed data which might give you wrong estimates. So what we do is we maintain multiple estimates and then combine those estimates to get a single cardinality value. So what is basically done from the hash values that first k bits are chosen to index into a particular bucket, and the rest of the m minus k bits will be used to do what we just saw to determine cardinality. And then we combine the cardinality from all the k buckets and get the final estimate. Now let me give you a more intuitive example if this doesn't make sense at all. Say one of you comes here and tells me that he has been flipping coins since morning. And the continuous runs of one that he got, the maximum of them, were just two. Then I can assume that he didn't flip the coins a lot of times. But if someone else comes and says that the maximum run of heads that he got is 100, then I can easily derive that he has flipped the coins a lot many times. Because the event of getting 100 continuous heads is a very rare event. And that can happen only when the operation, the prior operation, has been performed a lot many times. So the data structure that we just saw is known as hyper log log. This is widely used in the industry today to compute cardinalities. So coming back to my demo and let me set some context. So here there were multiple fields for which we were keeping track of cardinalities. And then within each field, we were keeping track of top 10 values by frequency. So what we did is we have account mean sketch data structure and a hyper log log data structure corresponding to each of these fields. So let's see what was the final amount of resources that we used. So we allow 200 fields at max in the output data. The count mean sketch, we chose the parameters of width and depth as 100 and 6. And that works very well for our data distribution and for 1 million results. We chose an error, HLL we chose the hyper log log data structure we chose with a bound of 0.02%. Now you can build this hyper log log in a way that you take the error percentage itself and it gives you the values of k and m. And that translates to 3 kilobytes. So for 200 fields, we need 200 megabytes of memory. And I said in the beginning that we run 10 concurrent queries on a single machine that translates into 2 gigabytes. So now we can actually do all these operations in memory. And there was just 7% increase in CPU. So we also said that we want a data structure which is not CPU intensive. And this 7% increase is because of computation of hash values. All right, that's what I had. Thank you very much. I can take any questions if there are. Hi, so my name is Sanket. I have a question on two slides. The one where you compute the width and the depth. Yes. Can you get the slide, please? That's a lot of questions. Yeah. No, no, I'm asking. This one, right? Yeah. So maybe I lost at this point. But I want to know, how did you come up with this formula? I didn't get the depth thing. Yeah, so that's what I said that we will not go into the math behind this. I just presented these results. There is some rigorous math that you need to go in and do for getting this. So we can discuss it offline. OK, fine. And there's another one where you had said that if we consider a hash function, right, the 50% probability, you have a probability of having one in the most significant place with a probability of 50, right? And if you go down, then you will have 0, 1, right? Then in the next slide, you said that if we have four unique things, at least one of them will start with 0, 1. But that's again with the probability, right? Because we also have this property of the hash function that it will uniformly distribute the incoming elements across the number line, right? So if you have 0, 1 in the first place, then there is probability that there are four elements because that is the minimum value that you see. OK, yeah. Cool, thanks. Yes. On the same hash function that you are saying that it will distribute it uniformly over the probability, how will a hash function distribute it? Hash function doesn't have that much information, right? Yes, so it's not just about a single hash function. You have multiple estimates. And you try to choose good hash functions, but you can definitely not. That's why it's not just a single estimate that you do.  That's why we were using multiple hash functions. It won't be a static manipulation on the data which will give you a unique hash, right? It will have to have a feedback of how many numbers have arrived already. And based on that, it will decide what the frequency of this particular number, let's say, this particular element to be in. Like, how will you find out that even has occurred this number of times if you don't have all the previous elements stored? Yeah, so that's why we had this data structure. This is a sketch data structure. It's a probabilistic data structure. It will not give you very exact values, but by choosing appropriate parameters, it will give you some value which is very near to the actual value. And we can do, I mean, you can tune the parameters of course. Hello. Yeah, maybe I would have understood it wrong, but what I understood from the PPT is like, you have a two-dimensional error kind of thing where you are storing all the hash and finally you're merging it with all the nodes fine in the. Yes. That you are doing. Take, for example, you have passing all the hash, what you're saying. In the first node, it is present. Now there is a huge probability. You're talking about the bloom filters? Yeah, yeah. So the length view which you are deciding it. The length which you are deciding. Take, for example, you have decided for the 1,000 or you're taking a 2,000. There is a high probability that the particular thing, element which you are going to count it, may not come in the 2,000 part or may it be coming in the last thing and in that case, what the result we will be getting will be probably not correct. So you are saying that what happens if it spills out? If the hash function produces some index which is outside of. No, so that's why you choose a hash function which outputs the value between 0 and m minus 1 where m is the size of your sketch. Take, for example, I have a user. Okay, I'm coming from a website and I just want to take a user who's coming on online. So if it is a real-time kind of thing and you are going to check the cardinality, you want to take the top 10 kind of result. You were talking about the top 10. I thought you were talking about bloom filter. So if you're taking a top 10 kind of thing, in that case, what is going to happen? That user might get skipped because there are n-number user already present and within a millisecond you are losing his data, isn't it? We are not losing the data. For every incoming element, we are inserting something. So where is the position of the 1000 part you are incrementing that matrix? Where you will increment that? So we have like K different hash functions, right? And there is a bit added corresponding to each hash function. For each hash function, you get a different index. You go to that index and you increment the value. And then you take the minimum of all the values that you get from the different bit arrays. Hey. Yeah. Yeah, so you said multiple hash functions help. So but won't a single bad hash function basically skew the entire result set or increase the margin? I mean, a single hash function can potentially cause that, right? So if that does, that's why that is one of the reasons we use multiple hash functions. Yeah, so but if you have a single bad hash function that will skew your, you know, let's say if you have two hash functions which gives quite closer results, right? In that case. You were talking about the case in which they are dependent on each other maybe. Correct, correct. So yeah, so things like the count will totally be skewed. Yeah, so that's why in case of bloom filters all the hash functions are mutually exclusive. You have to make sure that hash functions are mutually exclusive. And in case of count means sketch, you have to make sure that they are pairwise independent. So that, so if you do the derivation, these two things will be used to get the final error rates that we derived. Hey, Himadri. Himadri. Why there was a need of two dimensional array. Yeah. You started with one dimensional then you. Okay, right, right. So in case of bloom filters you are saying, so this also comes from the fact that in case of bloom filters we need more rigorous hash functions. They are mutually exclusive. In case of count means sketch, those hash functions are pairwise independent. So you know, if you choose just a single array, there will be a lot of pollution of one counter with because of other counters. No, but you could have. But there are actually variants of bloom filters which use 2D sketches. No, no, so just to avoid the collision you had that two dimensional array but you could have had a bigger one dimensional array that could have given. Yeah, so yeah, that's what I was telling you. That in case of bloom filters, hash functions have one more property. I just didn't want to go into the verbose details of that. That's why I didn't present that. These hash functions and bloom filters are mutually exclusive. It's more rigorous to build those hash functions as compared to the hash functions in count means sketch. They are just pairwise independent. So pairwise independent hash functions are easier to build but they have a property that they will not work very well if the space that you are updating is same. That's why we have different spaces as in different bit vectors corresponding to each hash function. Hi. Hi. So yeah, so I was curious to know about the error bound, the function that bonded the error for bloom filters. Yes. So what are the parameters that it was dependent on? So yes, there were three parameters that is n, m and k. So n is the total number of elements that you will see in the stream. You have to estimate that somehow because you have already seen your data. And m is proportional to the amount of memory that you can give to this problem. Okay, okay. So you also talked about that you can combine results from various machines to find out the count and all. So I was asking, so does this error bound remains? How does it vary with the number of machines? Right, so when we were talking about count mean, when we were talking about sketch data structures, we saw that, I mean, I talked about this that you have multiple estimates, you combine them. When you combine them, you have to make sure that each of your individual estimates had those parameters that when you combine, you get the desired results. So yeah, so you know. So I mean, you have to estimate the value of n upfront. I mean, the. Yeah, after combination, what will be n? That is what you have to use for individual sketches. Okay, okay, thanks. I mean, total number. Sorry, n is, m is, n is the size of the bit array. It depends on how much memory you can give to that. So if you increase m, you have to give more memory and your error rate decreases.


The Australian government has introduced biometrics collection as part of the visa process. Every year thousands of international travellers have their identities stolen. Biometrics is an important tool in the fight against identity crime and is used in many countries. The Australian government is committed to fighting identity fraud with the new biometrics collection program. Under the new arrangements you may be required to provide your biometrics such as fingerprints and a photograph as part of your Australian visa application. In some locations the Australian government uses service delivery partners to operate AVACs or Australian visa application centres. AVACs offer a range of visa application services including visa lodgement, fee payment and biometrics collection. If you are required to provide your biometrics as part of the visa application you will need to visit an AVAC to do so. Let's take a look at the visa application lodgement and biometrics collection process. Good morning. Hi. I'm here to apply for my Australian visa. Sure. I need your completed application form and your passport please. Thank you. Okay, everything seems complete. I'll just collect your application fee and then we'll proceed with your biometrics. No problem. Good. Why collecting biometrics? Are there any benefits? There are many benefits. One, it will protect your identity. Plus it will also protect Australia and its borders and make Australia a safer place to visit. Thank you. Okay, so what do I need to do now? I'll take a facial photograph, scan your fingerprints and record the information. The process will only take a couple of minutes. So let's take your photograph. I'll need a clear image of your face. Can you remove your glasses please? That's great. Now I'll take your fingerprints. Please place your four fingers of your left hand on the scanner. Thank you. And now your right hand. And now your two thumbs. All done. So the visa application and biometrics collection process is simple and straightforward. For more information about Australian visa application centres and whether you are required to provide your biometrics, please visit the Department of Immigration and Citizenship's website.


Welcome back to my channel and welcome to the first video in this kitchen. I am so excited to just share with you so we are actually in the process of painting and doing a lot of things so right now all of the cabinet doors are out of here and they're being painted and so if you see some things kind of not quite finished around here that's what's going on we've got paint back there that needs to be finished so there's a lot going on but in the midst of everything of course meal prep still has to happen cooking still has to happen I still have little ones that need to be fed and all of that so I wanted to share with you what I've been up to in the last couple of days I've been doing some food preservation that has needed to get done I've actually been working on doing some home-canned baked beans I've had these beans for quite some time and I'm also working on emptying out our freezer because I think in about a month or so we are getting part of a beef and I'm gonna need that freezer space so I've had a lot of like odds and ends in the freezer that I needed to get out so part of the baked beans that needed to come out of the freezer was the bacon I had bought some bacon ends to put into my baked beans so I need to get that out of the freezer so you're gonna see some projects going on over the next couple weeks that's really just weeding things I have frozen grapes that's not gonna be in today's video but I do need to do some grape jelly just get those out of there and so that's what the projects are going to be mainly focused around so let's rewind a little bit and I'm gonna tell you what I've been doing over the last couple of days and then we'll talk about what we're gonna do today one of the things that I wanted to get stocked up in my cellar was some beef broth and beef broth is so incredibly simple to make is very very cheap at the butcher place that I got this I think that these were 99 cents a pound and of course I'm going to get a lot of beef broth out of this and you can add whatever you want to your beef broth I like to kind of empty my refrigerator just whatever I have on hand so here I'm putting in a bunch of parsley and some celery I'm gonna put in some onions and carrots and just give it a wonderfully rich taste this is why homemade broths can taste so delicious they just are so rich in all of these flavors and I actually did this the night before I wanted to can up my broth and just filled this up this is a 22 quart cooker I'm not sure exactly the right term for this we just always call them the big cooker so they're kind of like a crock pot but on steroids a really large crock pot my mom has a bunch of these because she does catering in our area and so I usually borrow one from her or I have one around that is from her and so here I'm just adding salt and pepper and I'm also doing some dried minced onion as well and then I'm just gonna fill it up to the top with water so that I can get a lot of great beef broth out of this and then also the night before I wanted to do a bunch of this I soaked a bunch of beans and I'm going to be making homemade baked beans like I said earlier and you can really use any beans you want to I just did a mixture of some red kidney beans some navy beans and I think some small lima beans I can't even remember all of what I did just a mixture and I soaked them in a big bucket so this is amazing overnight they absorbed all of that water and filled the entire bucket and soaked beans just cook a whole lot quicker so that's why you soak them and then here is all the bits and pieces out of my broth that I scooped out with a large strainer before starting to do the smaller straining of it so whenever I do my broth whether it's chicken broth or beef broth and you all may have seen this in a video before I keep cheesecloth on hand I use it for a lot of different things and this is one of the purposes I keep it on hand for I don't like little things in my broth I like my broth to look very clear and beautiful when I look into the jar so over top of a mesh strainer I will put some cheesecloth so that it can catch all the little bits and pieces that may have been floating around in my broth from it cooking all night long I don't think I mentioned this but I'd like to cook my broth for a long time I would say at least 12 hours if I can't get even 18 or 20 hours out of it I like a really really rich broth and it also makes it almost more like a stock or a bone broth where I could even dilute it and add some water to it so here before I put the rings and lids on I'm just taking a little paper towel with some vinegar on it and wiping the rims because anytime you have a fat content in your item that you're going to be canning you want to wipe the rims to make sure there's no grease on there so it doesn't mess with your seal and then I also like to actually can my broths in pint size I almost prefer that over a quart size a lot of times a recipe will call for two or three cups and so it's nice just have a smaller size so here I have my little helper Haisley she was playing hard you can see by the hair she was just around the kitchen this day and kept asking me for a job they always love to help and so I was using my big 10 quart pressure cooker so this would be like an insta insta pot but it is just considered a pressure cooker because it's not insta pot brand to cook up my beans because it cooks them very very fast so we were just loading that up through the day to get them cooked and then here is some of my bacon ends and I'm throwing them in my air fryer because it just cuts down on the mess and it makes me some crispy bacon pieces to put in with my baked beans so since the canning process it does in fact cook the product that you are canning you can mix cooked and raw things together you can actually can raw beans dried beans however you need a good amount of water in there so that they can absorb that and I wanted my product to pretty much be already made in the jar that's why I pre-cooked the beans but I am putting my onions in raw so that they can just go ahead and cook in there through the canning process and here is all of the fun ingredients this recipe is actually my husband's grandmother's baked bean recipe it is not anything healthy but oh my goodness are these good and some people would consider these to be barbecue beans because there is barbecue sauce in there you've got some ketchup you've got some brown sugar you have some ground beef which you're gonna see me scooping here out of the pressure cooker because that's another great way to make ground beef really fast and bacon and all the yummy delicious things and everyone in our house really really loves these there's something that we do for a quick lunch because they're almost like a meal in a jar or a meal in a can you know you see that a lot right now people are sharing meals in jars and this is pretty much what this is however you could use it as a side to like pulled pork or a barbecue item as well and so he asked me last year if I could can up his grandmother's recipe because he loves it so much and it just works out perfectly so I will leave that in the description box below for you guys to follow along if you want to make this for yourself of course I'm making a huge batch of it and in the recipe it does call for cans of pre-made beans from the store you could take that route totally however with the way I'm doing this and using dried beans this is very very inexpensive very inexpensive to use dry beans and cook them yourself because a bag of dry beans are often around a dollar or two and it makes a lot a lot of beans so all I did to use the cooked beans versus store bought canned beans is I just measured out my beans after they were cooked and just made the equivalent to how many cans of beans the recipe calls for so here I am putting them into pint jars I just like to use a wide mouth pint jar for something that is messy and will make it easier to wash the jar once we've emptied it kind of my thoughts behind using a wide mouth versus a regular mouth and I actually ended up with about 60 or so jars of baked beans okay so today I wanted to bake something and I actually am going to be using the lemon juice that you guys saw me preserving in the last video I really want to make some lemon bars they are one of my favorite bars and I have not made them in quite some time and my family really loves them so I gonna whip some of those up and then we're gonna also go ahead and make dinner for this evening alright so to start out we are actually going to need a cup of softened butter so I'm gonna just pop this into the microwave and I'm going to just melt it real quick we're mixing together kind of the crust part of the lemon bars so it's very simple to put together I also need to actually preheat my oven as well the process of this kitchen has been so exciting if you guys don't know I actually have a home channel which is linked below so once we are finished with the kitchen you will see a video over there on the entire process and everything we did and if you could only see the before you would be even amazed at how far we've come so far all right so we are just going to mix the butter in it melted a little more than I wanted it to but we're gonna mix it with some powdered sugar and just some white flour and the powdered sugar is gonna give it that good smooth consistency and more like a mouth-in-the-mouth texture that's really what lemon bars are known for they're just this wonderful texture and as usual I will leave the recipes in the description box whether they are linked there or I sometimes have them written out there as well one thing I really like about this recipe is it is made for a 9x13 pan and I feel like a lot of lemon bars kind of like brownies can the recipes are often made for an 8x8 pan so this is a good like family or a large family recipe for lemon bars and since I don't bake much of anything without some vanilla in it I'm gonna splash some vanilla in this too vanilla is something that my mom was always very liberal with and if you guys know my mom is a baker she actually grew up in a bakery and so she's got all the good tips and tricks and she always says add vanilla okay so you could mix this with a fork or anything else but I actually have a I think this is called a pastry cutter I can't quite remember I know that you use it to make pie crust and I'm just going to kind of mix it together with this it'll help to cut up that butter that wasn't melted and just mix it all in really nice so you can see as I'm going here we're starting to get a more deli consistency I'm gonna call that good and because of the butter content in this you do not need to grease the bottom of your pan if you hear little sounds it's just my pressure canner doing a natural release on my stove because I have the last of my baked beans going in there so you're just gonna press the dough out into the bottom of the pan it doesn't have to be super fancy because we're actually gonna be putting another layer on top of here you just want it evenly distributed now we'll bake this for 15 minutes at 350 while the crust was baking in the oven I went ahead and mixed up the couple of ingredients you need for the lemon part on the top of it and I love the texture of this it's very gooey it's just got a wonderful texture so there you see me getting some of the lemon juice out that we popped into the freezer last week and you all did that with me and this is just one more recipe I know a lot of you are requesting that I share how we make lemonade with that so I will do that sometime soon but this day this is how I'm using it so once you have the eggs and everything all whipped up here and the crust comes out of the oven I like to wait till the crust is just a little bit brown around the edges that kind of tells me that it's baked fully through you just go ahead and dump that next layer on and pop it back in the oven okay so our lemon bars are done and out of the oven they have this kind of like bubbly top to them which is actually gonna get covered up with some powdered sugar once they're cut into squares but we're gonna let this thing completely cool in the refrigerator so that we can enjoy this after dinner tonight so for dinner I'm going to be making a very very simple broccoli chicken casserole and we're gonna do it all from scratch the original recipe actually called for cans of cream of chicken soup but I actually don't keep that in my house on a normal basis so if I get it it's usually because I'm making something for a meal that I'm taking somewhere else or you know maybe for a quick meal but I don't have it in my house today so we're gonna start out with dumping two bags of frozen broccoli again kind of working on emptying out my freezer into my Dutch oven here we're gonna get this steamed up we're only gonna steam it for or like cook it for about five minutes and while that's happening we're gonna go ahead and mix up our cream of chicken soup on the stove top I love this recipe because it uses frozen broccoli I know that fresh broccoli sometimes can be a little pricey in store so being able to use frozen broccoli versus fresh is a little bit of a money saver now I'm gonna go ahead and show you all how to make a cream of chicken soup now you could use mushroom as well I've done water and I've cooked up mushrooms kind of in place of the chicken broth that you're gonna see here so it's basically some butter and some flour some milk and then chicken broth and a little bit of salt and pepper and that is about it you really this is so so easy it doesn't take long it really only takes a couple minutes on the stove to thicken up and you're good to go and you don't have to use the store-bought cream of chicken soup again this recipe will be in the description box now we are just going to assemble everything which is gonna be really fast and easy but wasn't that incredibly easy to make cream of chicken soup I love it because I know every single ingredient that went in it it's with my homemade chicken bras and so it's got great salt in it I use the pink Himalayan salt and I just don't have to keep it on hand because I have all the ingredients on hand all the time and it's just it really only takes like five minutes to make so I'm gonna scoop out the steamed or lightly boiled broccoli here but before I do that I actually need to grease my 9 by 13 so I'm gonna use my handy little oil dispenser thing here that I know so many of you have and love I know like over Christmas time a lot of you got these and they are so great it's probably one of my favorite Amazon finds ever because I don't have to ever keep any oil sprays on hand and I can use like my organic oils and whatnot saves a lot of money so now I'm just gonna scoop the broccoli florets into the bottom of here we're just gonna kind of layer everything so I do feel a little bit silly about this but I got out a quart of shredded chicken to use in this since it's already ready for me it's good to go and I should have drained this and use this broth to make my chicken or cream of chicken soup but I forgot and so I opened up as you saw a small jar of broth so what I'm gonna do with this is I'm actually gonna drain the broth into a separate jar so I can save it and use it to make rice later on or something like that because we're probably going to do potatoes with this so I'm gonna give you a little trick if you like to reuse canning lids and I know some people don't do that but I do that so to save the rubber seal from getting punctured with a fork or a pointy can opener I just take a butter knife like this on the edge of the jar and I pull up and it gives me a seal that hasn't been punctured which is great because I do reuse my lids and I can get into that in another video I think I talked about it but anyways I'm actually gonna take the jar of the lid just to help kind of hold the chicken back and pour this in here because I hate to waste a broth I hate to waste anything if I can find another use for it isn't that amazing that there's almost a whole pint of broth in this quart of shredded chicken and then we're just gonna take all of this chicken and put it right in here and it's cold it's not cooked yet or any I mean it's cooked but it's obviously I'm sitting in my cellar not hot for me to grab here so we're just gonna layer this all in and I really feel as though I need to season this broccoli so I'm actually gonna get my salt and pepper and kind of season the broccoli and the chicken here so I was getting so excited about us eating this casserole for dinner and Cory walked in the door just as I was finishing up layering it here as you see and he decided that him and I were gonna go out on a date so we actually didn't end up eating this this night but that's fine because I can either pop it in the freezer or put it in the refrigerator which is what I did I put it in the refrigerator for the next night's dinner but that's what's great about meals like this is that they're ready to go no matter when you want to use them and this would make an excellent freezer meal I don't think I mentioned this but there's also some mayo that goes in with the cream of chicken soup just to give it a nice rich flavor and then you're gonna layer some cheddar cheese on top of that I love cheddar cheese with broccoli that combination is so delicious and then you can go ahead and use breadcrumbs and mix it up with a little bit of butter to top it off but I didn't have any on hand but I did have some Ritz crackers so I just put a sleeve of those into a bag and crunched them up just to give a nice little crunch on top of this casserole and like I said we'll be serving this with potatoes and maybe a salad of some kind I had to show you the end results of the lemon bars we actually gave some of these to our neighbors as well and they are just so delicious the girls have been loving them they have that nice tart pop especially for warmer weather months hey friends so it's actually the next day and I'm about to go run a few errands I thought it would take you along with me I'm gonna try to incorporate more of just normal everyday life like I used to in a lot of my videos but I did not mention this in any other talks I had about this new house then where we're living and stuff but it is very rural it's far out and we do have internet here we can pretty much do everything like I can do my editing I can we can like watch Hulu or Netflix or anything like that but I cannot upload from here and this problem we are going to get fixed hopefully within the next month we have to get like a satellite system put in so that it is strong enough for me to upload but in the meantime I actually have to go to my sister-in-law Sarah's house and drop off uploads every time I upload a video it's a little bit of an extra thing in my week but it's just the way it is just what we have to do right now so I'm actually heading to her house to drop off uploads and she has eggs for me I love getting her eggs because she gets all different colors and they're so pretty and I really need some eggs and since I'm going that way there's also a thrift store down near where she lives and I kind of want to stop in there I've been trying to thrift a little more than I used to or I should say this I used to thrift a lot and then I kind of got out of it and I'm trying to get back into thrifting some more especially with where we're living because the girls are outside pretty much all day long like until the sun goes down they're outside playing and so the clothing that they need a lot of it is just they need stuff they can get dirty and it doesn't really matter and I didn't spend a lot on it so keeping that stuff around is important and I also need some more warm weather clothing for myself so I think we're gonna swing in there and I thought I would just take you along with me so like I said I'm trying to get back into thrifting a little more often I feel like it takes consistency consistency is key when it comes to thrifting to find all of the goodies and we have several different thrift stores in our area here I'm showing you this mug I thought was so cute we had some little gems even though I didn't need them I've been on the hunt for a different glass wear set and this one was really cute but the glasses were just a little too small for me and I wanted to also show you here is some canning jars I know that I have personally been able to find a lot of canning jars at thrift stores for a really good price this one here was $3.99 for a pack of four which made each jar a dollar that's a very good price so check your thrift stores for canning jars and then I have such a weakness for baskets so that's always something that I'm checking out and looking at at thrift stores you can use baskets all over your home for so many different uses so here's a couple of the things that I snagged I caught this cute little miniature basket for the girls play kitchen up in their room and then I found this little treasure basket this was for Haisley each of the girls have been able to thrift a treasure basket and Haisley was the only one that didn't have one so we found this one for her for all her treasures and then I grabbed these other two baskets just for odds and ends things to store in my cabinets and they just work for so many different things I always find a good use for them and then I also found this really cute dress I'm so excited about this it's gonna be a fun summer dress I love the colors so thanks a lot for hanging out with me today you guys if you're new here don't forget to subscribe I love to hear your feedback on this style of video that I did today and don't forget to leave a comment give this video like and I'll see you guys in the next one


Welcome to the video on hyperkalemia. In this section, we will talk about the causes, investigations, and treatment in the emergency department. Hyperkalemia is defined as a serum potassium that's more than 5 millimoles per liters. Why is hyperkalemia a problem? Hyperkalemia causes poor conduction in the heart. It leads to prolonged QRS and eventually ventricular fibrillation. And a systole. Therefore, hyperkalemia is a must-not-miss diagnosis. What are the causes for hyperkalemia? We will look at shift and renal clearance. First, shift. Potassium is a mostly intracellular ion. The serum potassium level will go up if there is leakage of potassium from the cells. It can be caused by tissue injury. Such as burns and reptomyelysis. Potassium can also get out of the cells in exchange for another ion getting into the cells. Specifically in acidosis, hydrogen ion will enter the cell where potassium will get out of the cells. Second, renal clearance. Potassium is excreted by the kidneys. If there is renal failure, potassium builds up in the body. The kidney also excrete potassium based on aldosterone. Inhibiting aldosterone production or decreased aldosterone production will decrease the renal clearance for potassium. They can include congenital syndrome or medications. Such as ACE inhibitor, angiotensin 2 blockers and spurnolactone. There is one common reason for a fictitiously hyperclinia that is a falsely elevated reading. Remember that potassium is mostly an intracellular ion. When the blood is being drawn, if there is a lot of hemolysis, because it was a difficult poke or the turnkey was put on for a long time, potassium will leak into the serum portion and therefore will get a falsely high reading. Therefore, we often want to know if the sample was hemolyzed when there is a high potassium reading. If the patient truly has hyperclinia, these are the items you want to hit on history. Whether they had any history of tissue injury, whether they had any trauma, burns, and intense physical activity. For acidosis, we want to ask patients about whether they have any symptoms or causes for metabolic acidosis. For example, DKA or sepsis. For renal causes, we need to know whether the patient has a history of renal failure. And for chronic renal failure patients who are on dialysis, whether they have missed any sessions. For medication, we need to ask about new medications. Specifically, ACE inhibitor, angiotensin 2 receptor blockers and sperm electro. These are the main history items we want to ask. What are the clinical symptoms of patients with hyperclinia? They're pretty nonspecific and includes muscle weakness and lethargy. The investigation of patients with hyperclinia is simply a serum potassium level and also an ECG. We want to do an ECG in patients with hyperclinia. Since in patients with hyperclinia, there are ECG changes the higher the potassium level is. The sequence of ECG changes isn't the same in all patients, but they may hit the next broad categories. These ECG changes are important for us to know. We will talk about these ECG changes in sequence. We will start with the T waves, the P waves, and the cure of complexes. Let's begin. In hyperclinia, it is a common for us to see peaked T waves. Let's say this is a normal cure as complex with the T wave. A peaked T wave will look like that. On an ECG strip, it will look like this. It is easy to see the tall peaked T waves here. On a 12-leaf ECG, we might be able to see the tall peaked T waves only in certain leads. Can you spot them out? You can see them very clearly in the inferior leads and the pre-cordial leads. As the potassium level goes higher, the atrium begins to fail. That leads to changes in the P waves. First, the PR interval lengthens, and then the P wave disappears. Think of it as almost like there is a string pulling on the left side, making the PR interval longer and eventually pulling the P wave flat, like that. Let's first look at the PR lengthening on a hyperclinia ECG. If you look at the PR interval in this ECG, you will notice it's more than five small squares. In this ECG, you can still see P waves. As the potassium level goes higher, the QRS now lengthens. Think of a string pulling on the right side now. Once it starts pulling, the QRS now lengthens. The next ECG will illustrate the lack of P waves and a prolonged QRS complex. Note the lack of P waves and the prolonged QRS complex. You will also see the peaked T waves. As the potassium level goes higher, the QRS gets longer and longer, eventually looking like a sine wave. On an ECG strip, it will look like this. On a 12-lead ECG, it will look like this. If the potassium goes higher, the patient will go into V-Fib or a systole. How do we manage patients with hyperclinia? It consists of monitoring the patient, stabilizing the myocardium, shifting the potassium into the cells, and eliminating potassium from the body. We'll discuss each one of them. First, monitor. The patient needs to be put on a cardiac monitor. If we haven't done so already, a 12-lead ECG needs to be done. In patients with hyperclinia, we are much more worried about the patients who have prolonged QRS complexes. We stabilize the myocardium by giving calcium. We give calcium to patients with prolonged QRS complexes. It can be given as calcium chloride or calcium gluconate. Remember that potassium is an interest cellular ion. We can treat serum hyperclinia by driving potassium into the cell. We can do this by multiple methods. The first one is insulin. Insulin kicks potassium back into the cell. The dose is 10 units regular IV. We will also give dextrose-containing solutions such as D50 to prevent hypoglycemia. The second is beta-2 agonists such as cell butamol. It also pushes potassium into the cell. The dose is 10 to 20 mg by an ambulizer. Remember, acidosis is also a cause for hyperclinia. Giving bicarbonate will neutralize the acidosis. Lastly, we may wish to eliminate extra potassium from the body. It can be given by giving loop diuretics such as ferrosamide. We sometimes use a binding agent in the GI tract. In these resins, potassium is being extracted from the serum in exchange for sodium or calcium. Since it usually takes hours for it to work, it is mostly used in the inpatient setting. Lastly, the most efficient method of eliminating extra potassium from the body is dialysis. In summary, we discussed the causes for hyperclinia, whether there is muscle injury, a shift from the cells, or if the kidney is not working. We talked about the ECG changes in patients, starting from a peaked T-wave to a prolonged PR interval and the disappearing of the people. A prolonged QRS, a sine wave, and to a systolic or VF arrest. We discussed the management, including stabilizing the membrane, shifting potassium into the cells, and eliminating it from the body. Hyperclinia is one of the most often seen electrolyte abnormality in the emergency department. Because the patient can get really low blood pressure, because the patient can get really sick quickly, we need to know our management very well. We hope you find that useful. Thank you for watching.


This trustee August is hotter than ever at Appalachian Wireless, as they are slashing all normal contract pricing on all smartphones by 50% when you sign up for service. Better service, bigger saving, serving you for the last 25 years at Appalachian Wireless. Paca County Clerk Rhonda Taylor is reviewing stacks of paper containing thousands of signatures. It's all a part of the verification process for the petition to change Paca County's governing body from a magistrate fiscal court to a commission court. Taylor said the measures sought through the petition cannot be added to the ballot in November until the signatures on the petition are verified. But therein lies some of the confusion on the matter. The group that started the petition, Paca Countyans Against Government Waste, says the deadline for Taylor to complete her work on the petition is today. Taylor said her deadline is tomorrow. Five days after it's dropped off, it's dropped off late Wednesday evening. So we have Thursday, Friday, Monday, Tuesday and Wednesday, five working days. So hopefully we'll have it done by the morning. We have to pull another all nighter, we will. Taylor says she had 234 pages to examine when she started. We use a system called a VTR voter registration and we go in and we put the petitioner's name in and see if we get a match and if we do then they are valid. Taylor said despite the confusion, she plans to have the process completed by noon Wednesday. I don't really care what the question is that I'll be fair and do what I think I'm legally obligated to do. It doesn't matter what I want or what I think, it only matters that I do this job right. So to me, there is no great area. It either meets it or it doesn't. Pike Countyans against government waste issued a statement to EKB News this afternoon saying they still believe today was the deadline but they will give Taylor until Wednesday to finish. If she doesn't file by then, the group said they will take legal action. Reporting in Pikeville for EKB News, I'm Chris Anderson.


Sweetest messages for in for 34-year-old Nambatha Ben Mazwai. Mzansi multi-award-winning entrepreneur and actress, Nambatha Ben Mazwai expresses excitement as she turns 34 years old. The actress shared lovely photos of herself and wished herself a happy birthday on Instagram. Those who know me, know how important birthdays are to me. I am so grateful for my family, my twin big sis who I share my birthday with. Don't ask, my mom did nuts, my chosen family of friends, and you guys I've never felt more loved, more appreciated, more celebrated, and most importantly, more self-love than ever before. Happy birthday, Kamashi, I am so proud of the woman you have become. Thank you Jesus for another year, for your glory, she wrote. So, it's my birthday. Those who know me, know how important birthdays are to me. I am so grateful for my family, my twin big sis who I share my birthday with. Don't ask, my mom did nuts, my chosen family of friends, and you guys. I've never felt more loved, more appreciated, more celebrated and most importantly, more self-love than ever before. Happy birthday, Kamashi, I am so proud of the woman you have become.


Hi everybody, how's my hair? Is it okay? I really liked the lightning talk we saw by Elizabeth earlier today and I did want to point out and prove that this presentation actually has 102 slides that we're gonna cover in 30 minutes.  Thank you all for the support. Last thing before we get started, I win. So we're captive to the notion of elegance but what do we really mean by elegance? I'm reminded this book that I read when I was a kid called Alice's Adventures in Wonderland and Alice gets in an argument with Humpty Dumpty about what the word glory means and Humpty Dumpty says something that always stuck with me. When I use a word it means exactly what I intended to mean, neither more nor less. It's a question of who's to be master, that's all. So does that mean that when we use the word elegance we can't really define it? That it means something different to every person? Well just so happens that there's an entire science devoted to understanding our appreciation of beauty and elegance and I'd like to share with you some things that I learned about it today. So it's called Aesthetics and we're gonna talk a bit about Aesthetic Theory to start with. Aesthetics is experiential. It's about the experience of beauty and that experience can be sensory in nature through our five senses. It can also be a cognitive appreciation of beauty. There are four main schools of thought when it comes to aesthetics. The first is pluralism. In pluralism it states that every person perceives things in a different way. Every person arrives at their own truth in their own way. A sort of a common example of pluralism is you probably heard someone say what if when we look at something blue and you look at something blue we don't see the same thing. How do we know that blue is really blue? Well that's a pluralist perspective. The second approach is called hybridism. In hybridism we say when we look at something blue you might see it a little differently than I do but we're all seeing basically the same thing so this common experience that we share is sort of truthiness. Then there's absolutism. Absolutism derives from the notion that beauty comes from perfection, from provability. Because the wavelengths of light are vibrating at a particular frequency and hitting our retina at a certain angle we all see the same blue. This school of thought emerged from something called applied aesthetics and its application to computer science is not a new idea that I came up with actually. There's a guy named Ezger Deekstra that we're gonna be talking about a little later who thought a lot about this. Finally there's eclecticism. Eclecticism says it depends. There's not one single way to define what beauty is or a relationship with beauty. It's contextual. So let's say they're multiple paths to the truth essentially. So the effects of our appreciation of beauty can be applied in a very practical way. Consider a structure. Consider a building. A building is designed for a single utility. It's created for materials that have a fixed cost. But if those were the only four attributes we cared about we would build a lot of concrete boxes. Through applied aesthetics, deliberately injecting aesthetic attributes, buildings can be elevated to a new level of perception and experience of beauty and give us a new thing to appreciate as we use the building for the intention for the purpose it was designed for. This makes our interactions more pleasing. So these two buildings both serve a function. They both are important to people. The one on the left has aesthetic characteristics that the one on the right obviously does not. This is Bacon's Castle. It is Virginia's oldest certified brick building. It's in Surrey County where I grew up. It was built in 1665. It got its name from the fact that soldiers during Bacon's rebellion in 1676 stayed there and were garrisoned and it's been perfectly preserved for about 350 years. This is a Soviet era building in the style of brutalism. Brutalism emerged after World War II when nations had to very quickly rebuild their infrastructure and their buildings and their housing so they really had no time for injecting aesthetics at all. Do you think this building is likely to be preserved for 350 years? No. Code is the same way. We don't want to work on legacy code that has a brutal architecture. That's ugly. That's unesthetic. We want to work on small agile nimble apps that interact in pleasing and aesthetically interesting ways. So elegance is an aesthetic experience. It's perfectly conforming to a set of imperfect standards. Elegance and code is a result of a mysterious process that we don't really wrap our heads around very well. Elegance and nature is a result of a mysterious process we call evolution. So it's really important that we define our terms here. So I'm going to briefly divert into evolution. Now, if you grew up in the south like I did, this may not be a refresher course on evolution. This may be your first introduction to the topic. Four main terms I want to cover. Genotypes. Genotypes are the genetic information that code a particular characteristic of an organism. These genetic information is expressed as a phenotype. This is the physical manifestation of genetic information. There's the concept of natural selection. In natural selection, characteristics that express themselves and have an influence on reproduction of an organism and therefore determine which characteristics become dominant or not dominant in a population. And the sort of canonical example of this is the moth. Moths like to sit on tree trunks and they like to blend in with tree trunks so they don't get eaten very often or very easily. So during the industrial revolution, when factories suddenly started cranking out lots of soot, light colored moths became easier prey for predators and dark colored moths survived more. So the population actually shifted to darker colors. So even though this was a human intervention, it was an environmental effect that had an influence on how genotypes were expressed as phenotypes. And finally there's artificial selection. This is when we deliberately breed for certain characteristics. So can aesthetics be a factor in evolution? I want to tell you the story about John Chapman. He's better known as Johnny Appleseed. He lived in the 1700s. He famously wore a shirt made out of a coffee sack. He traveled with a Bible and bushels and bushels of Apple seeds. It's important to understand that in the 1700s, the notion of sweetness, the concept of sweetness was very unique and sweetness was actually a luxury. Sugar was not plentiful in the New World and there were no honeybees except the ones that were imported from Europe. So the average person only got sweetness from rare fruit. And you see in stories like of Christmases in the 1800s, kids get an orange and they're excited. That's because fruit was really rare. It was hard to preserve. So when we think of fruit, we think of apples. We think of apples. We think of a red delicious, perhaps. Little known fact about apples. Most of them have about five seeds inside. If you took a red delicious apple and it's five seeds and planted them, you would not get five red delicious apple trees. You would get five different varieties of apple tree, none of which probably produced edible fruit. This is the kind of apple that you get when you plant apples from seed. Not very delicious. Just sour and soft. Now I said that John Chapman and Johnny Appleseed went across the country planting apple seeds. So was he stupid? No. He was actually pretty smart. He would go to where settlers were going to be, plant apple orchards and then turn around and sell them when the settlers actually arrived. But he was selling them apples like that, which are really great for making hard cider. Hard cider preserves much better than fresh fruit does and added bonus. It gets you drunk. How awesome is that? Right? So these ugly orchards were really, really valuable. They were an investment. But then in the 1830s, there was this movement called temperance. People decided that alcohol was evil. And apples as a source of hard cider were part of that evil. That goes back to the Bible, right? So apple orchards were in danger of losing their value. So the apple growers came up with a great concept that we actually hear today. It's apple grower propaganda from the 1800s. And apple a day keeps the doctor away. The health benefits of apples were pretty much invented in the 1800s and propagated as an idea to preserve those apple orchards, which were quickly reconfigured to produce edible apples as opposed to cider apples. So the genetic expression of apples over the last 300 years has been in response to our aesthetic demands. We didn't care about how shiny, how red, how perfect looking it was. We cared about its alcoholic qualities and its sweetness. And later we came to value those other visual aesthetic characteristics. And we got apples like we recognize today. So what do we guide evolutionary changes through deliberate crossbreeding? Or by environmental effects? Our aesthetic preferences are having an effect on the world around us and how it expresses itself. So is aesthetics an integral part of evolution? Or is it something that we just impose? There was a book that came out maybe 20 years ago called the selfish gene, which asked the question, what do genes want? The idea actually came from a man called George Williams who wrote this book. He posited that since genetic expressions are essentially competing for attention, competing for survival in the world, that it was more useful to look at evolution from the perspective of a gene than the perspective of a species. One of the interesting things that came out of this is the green beard effect. With the green beard effect, it posits that if there were a gene that created green beards and men, and the tendency for men with green beards to treat other men with green beards nicely, this would be a way that the green beard gene expressed itself, self-recognized itself and benefited itself without really any impact on the survival of an individual organism or of a species at large. So in Ruby, we have in our world here, we have the green beard effect. Our green beard effect means that when we write Ruby code, we look for other Ruby code that we use. We look for libraries and apps that are in the language that we are familiar with. We build entire communities around our language. Technology wins in this scenario just like we do. It's a symbiotic relationship. But if we look at it from the perspective of the code, code is playing a very different game than we are. So let's ask ourselves what does code want? First, it wants ubiquity. Code wants to be everywhere. It wants to be in every device, in every aspect of our lives. It wants to be universally applied to every problem. Think of the API paradigm. It's been around for years and years and years. The genotype has been consistent. The expression of that genotype as an actual physical API is the only thing that's changed from RPC to XML to JSON. Code will do anything in its power to live as long as possible. Think of Unix. Unix is probably the most successful program ever written. It's because of its modular nature and how flexible it is in adapting to new protocols and new technologies. So how does code get what it wants from us? It starts by being flexible. Flexible languages are long lived, and that means that they encourage specialization. Specialization means we don't want to change languages very frequently. Languages are extensible. They adapt to new protocols, new methodologies. We don't have to learn a new language when a new version of Agile emerges. Languages have to be novel to keep us constantly engaged. They have to bring new things to our attention, otherwise the bright shiny of Haskell will draw us away from Ruby. And finally, on a darker note, technologies survive by being entrenched. Think of IE6. The reason IE6 lives so long is that a lot of intranets were built to support IE6 features. The Microsoft technologies were so entrenched that they were too expensive to remove. This is like a gambler who's lost $1,000 and keeps gambling because of the fallacy of sunk money. My luck has got to change. I've got so much invested in this, I can't afford to change it. Is it fair to compare evolution in the natural world to programming languages and technology? I think that underlying languages are like the genotype. They contain the universe of possibilities of the way that ideas of the language can be expressed. And therefore the applications that we write are the phenotypes. These are the physical expressions of the language. They're environmental pressures that bring about natural selection. How fast is it? Does it operate on the hardware that's popular? Does it compete well with other technologies? These are forces in the natural world of a technology of a language. And then there's refactoring with our own code, a cycle of attention from when code is first conceived to when it's written to when it's refactored is a generation. And iterations of a language are like generations as well. By being actively maintained, it's like cross breeding for traits that we want. Can we measure the aesthetics of languages? There are five ways that we interact with a language. The first is a user interface. This is where most people interact with a language, the UI that's built using that language. As developers, we have a few other ways that we interact as well. Through the API, through the way that the language is actually constructed, the objects and methods that are available to us, the underlying paradigm of the language, the command line, the way we interact with executables in the language, the documentation that we read, is it clear or not clear? And the readability of the code. Is it easy for a developer to parse and understand? So in September, I ran a very I'm a college dropout. I ran a very unscientific poll about the aesthetics of languages. For those five characteristics, six languages, I asked people to rank each of those characteristics for those languages. And I used the data to plug into an algorithm I designed called the aesthetic index. Python came out to be the most aesthetically pleasing language to its users. Ruby was a very close second. It was a very close second. And I noticed that JavaScript and C Sharper are a very distant third. So Ruby is a language that was designed to make us happy. And I think this chart proves that to some degree, to a very large degree, it succeeds in that realm. And then I wondered, does that really have an influence on how popular a language is? All of the six languages, with the exception of JavaScript that I ran the last year, the ones that are losing the less are at the top. JavaScript is actually gaining probably because it's the only language that we can use client side in a browser currently. But Ruby and Python are losing less than a percent a year. PHP is losing three and a half percent of its developers a year. So there seems to be some sort of relationship between how aesthetically pleasing a language is and how well it's surviving in the wild. So that's languages. Can we also consider the aesthetics of code? And we get into a very dangerous realm here, where we're again trying to define this notion, the slippery notion of elegance. I think there are four characteristics that we can use to measure the aesthetics of code. There may be more, but these are the four that I sort of focused on. The first is correctness. And this sort of ties back to that absolutist perspective on aesthetics, right? Correct code is beautiful code. That's what Ezger Degstra wrote. He believed that programming languages are an extension of applied mathematics and that therefore provability was the measure, the only measure that mattered for the beauty of code. I'm going to tell you a story. A couple of years ago I found this book called Clever Algorithms. I was dabbling in AI again at the time for maybe the third or fourth time in my career. And this book promised to be a catalog of algorithms inspired by nature. Perfect. Natural systems, algorithms expressed in Ruby. Even more perfect. The only way it could be more perfect is if Douglas Hofstadter personally delivered it on the back of a giant raven and dropped it in my lap. I made the mistake of opening the book. I found methods like DRAND1BEN with arguments that were 15 arguments long. Yuck. I found methods like this which go on for 118 lines. Procedural code, no objects at all. Yuck. There are two places where code like this can be considered beautiful regardless of how correct it is. In the eyes of its creator that actually said game over but I said the whole thing on the slide. And in bizarro world. So that's correctness. Correctness alone is not enough to make code beautiful. There's performance. And I consider performance to be a relative thing. Even though we can actually measure it, we can measure how fast our code operates, the experience of performance is a very subjective one. What is fast to one person will be slow to someone else. There's brevity. I was reminded of this great line by blaze Pascal summarized it said I wrote to a long letter because I didn't have time to write to a short one. Brief code, code that embodies brevity is very hard to write, especially when you take into consider readability. Readability is how easy it is for other people to parse the code that you have written. Readability is absolutely subjective. These four measures taken together I think define elegance for me. And I was asked by someone out in the hallway during one of the breaks today. He said it's a shame we can't actually measure elegance. We can't quantify it. I think we can approach it. Using a grid like this with the four characteristics that I talked about as four axes. We can map how readable, how concise, how performant, how correct a piece of code is and strive to make the shape in the graph as large as possible. Why does all this matter? Einstein said that when a certain level of expertise is reached, science and art coalesce in aesthetics and that the greatest scientists are also artists. Consider the world we live in today. Entrepreneurs and technical co-founders. We make deals with the devil. Business people spend time dreaming up applications that they want built. And they engage us to make what are called MVPs, which are most evil products. Their contract signed in blood, the software must be delivered by insert arbitrary date here or the world will collapse. If we don't get another Twitter for Goldfish, we're doomed. What results is really ugly, monolithic, brutalist code that no one wants to work on. We'll fix it in the next iteration. That's a lie. We want to build this. What we end up building is more like that. We've all been there. Or we all will be. I would ask you not to write code for the devil. Ask yourself why we write code. Is it for money? Is it for job security?  Creating something out of nothing, solving problems. We like those things. Who do we write the code for? Do we write it for an interpreter? Compiler? Do we write it for stakeholders or users? I would argue that we write code for other developers. The people that will interact with our code later, at the level that really matters, we have to make sure that our code is not only performant, correct, concise, but also readable and understandable. We care about code quality for lots of different reasons. Maintainability and extensibility I talked about. But I think the most important reason we care about quality is that our names are on those commits. We don't want, a year later, some other developer doing git blame, finding our name and cursing us. The code that we write is an expression of ourselves and our capabilities and our intellects. And that's a scary thing. Think about what code you're putting your name on. Is that something you want to be part of your legacy? Aesthetic appeal is a measure of quality. I think it's one of the most important measures of quality to the people who really own the code, who are people like us. Architecture without aesthetics is brutalism. And code without aesthetics is a commodity. I don't think we want to be producing commodity code. Maybe some people are comfortable getting paid to write crappy code. I don't think those people are here today. I don't think those people are very active in the Ruby community. So don't do it. Care about your code. Recognize your code's needs. Respond to them. Create a symbiotic relationship with your code as it evolves. Guide its evolution and evolve yourself in the process. Consider the experience of writing and reading your own code. Is it creating a beautiful experience for someone else? We increasingly prefer to call ourselves craftsmen or artisans. But if we're just cranking out anonymous code for non-technical co-founders, our code is a commodity. This reminds me of a theory that Marx called the theory of alienation, where artisans have control over the process of creating their product. The materials that are used, the techniques that are used, their professional standards, the quality of the finished product. In a factory setting like capitalism produces, we become alienated from the products of our work. Artisans do not work in code factories. Think about that. We have the power to decide the form that our code will take. Code wants to be ubiquitous. It wants to be universal. It's willing to give us flexibility in exchange for our ongoing attention. We can blindly participate in this process, like the moths, allowing certain moths, certain of us to succeed while others fail for reasons we don't fully understand, or we can actively and intentionally engage with this process. We can create experiences of pleasure for ourselves and others. In the end, it's our responsibility to attend to our orchards of code and to produce something that is beautiful and delicious. Go build something beautiful. Thank you.


The Tilbrook University, for me as a researcher, is a really attractive university because I work in the field of marketing and in marketing the Tilbrook University is among the top departments in the world. We have an excellent PhD program, so we are able to attract PhDs from all over the world. There's also a lot of interaction with our research faculty and the PhD students themselves. They're working on really interesting problems and after their PhD they also are able to have jobs at really good universities all around the world. When I arrived here at Tilbrook University I initially had a work teaching research balance of 60% spent on research and 40% of my time was spent on teaching activities. I teach in the master program and all our courses in the master programs are taught in English. We have a professional studio here to record web lectures and I use these web lectures to show them to the students before they come to class so that when they come to class I can actually spend more time with the students doing exercises and answering questions. I have been here for many many years, I have learned a lot, I have been able to grow here as a researcher to do work also on very interesting topics due to the good support that I get here from the university and I think at this stage I can say that the Tilbrook University and the environment that they offer has been very important for me to develop as a researcher.