Hello everyone, in this video I am going to discuss about Diagnostic study or Validational study. Most of the health research will be focusing on the risk factors, the diagnosis of the disease or the effectiveness of the treatment. For identifying the risk factor and the treatment, the epidemiological study designs are classified and most common classification is this. But in case of the diagnostic test, it's a unique topic where this epidemiological study designs will not touch. As I said it is unique, they have a different sample size calculation, different type of analysis and different results which we get. Before going to the diagnostic study, we have to understand how are we diagnosing a disease. This is an example for the spot diagnosis. That is if you look at this picture, you can easily identify it is a herpes zoster. So this does not need any more investigation, we can directly treat. We have self labelling, patients based on their symptoms directly go into the internet as their friends and they come out with their own diagnosis. Most of the times it will be threatening them. The third type is based on the presenting complaint, you can arrive at the diagnosis of liver failure. Then we have the place of ruling out the possibility of the presence of the disease, then refinements, then reasoning out thereby diagnosing a disease. Then we have the investigations, various types of investigations which can be broadly classified into the tissue sampling or the histopathologies, the biochemical investigations. Then we have the imaging investigations, then we have endoscopy and we have plenty of these investigations which will help in the diagnosis of the disease. Now where and how are these tests used? Most commonly the departments which use this diagnostic study design is or the validation study design is biochemistry, pathology, microbiology, radiology, public health and clinical subjects. And how do they use it is the clinical diagnosis, either they have certain sets of criteria of symptoms and they can have a clinical diagnosis and they can test its accuracy also. They can develop a screening criteria based on a single question or a set of questions that is questionnaire. They can look at the prognosis of the disease, they can look at the response to the treatment, they can screen for a disease. All these settings need validation of study design. Parameters on which diagnostic test is evaluated is validity or accuracy, reliability or otherwise called as precision, reproducibility, repeatability or consistency. The third one is the economicity or efficiency. Here this dots, the images with dots shows the difference between validity and reliability that is accuracy and precision. This is highly accurate and precise. This is highly accurate but there is low precision. This is highly precise but low accuracy. This has low accuracy and low precision. Validity is the ability of the test to detect what it is supposed to measure. Reliability or repeatability is the ability of the test to produce the same results when it is repeated. We need to understand the type of errors before going into the accuracy calculations. We always have to construct this two-bar-to-table for effective analysis of diagnostic test. The first rule for constructing this two-bar-to-table is always gold standard will be on the top that is say the truth or the best test will be in the top. Then the test result which you have will be on the left side then always yes will be first. Based on this we generate the true negatives that is the test result said no and the truth also no this is called as true negatives. On the other hand the test result says the disease present the gold standard also said the disease is present hence you call it as true positives. On the other hand here you have the test negatives but actually by truth they are positive. So you call this as a false negatives here as the false positives. Now validity or otherwise called as accuracy is measured by this following parameters that is sensitivity, specificity, likelihood ratio, positive and negative, positive predictive value and negative predictive value. Sensitivity can be remembered with the phrase positivity among the deceased and negativity in the health. If the test is sensitive then it is a good screening test. If the test is having good specificity then it can be used as a confirmatory test. You can remember with the fourth letter that is the key to remember. So sensitivity, screening, specificity, confirmatory test. So here we are going to see how we calculate the sensitivity and specificity. As I told sensitivity is the positivity among the deceased. Here they are the deceased, they are the healthy. This is test positives, this is test negatives, this is total. So it is positivity among the deceased. So true positives divided by true positives plus false negatives. This is the positivity in the deceased. Here it is negativity in healthy. So Fp plus Tn, so true negativity will be on the top. So this will be negative by the test, actually not deceased will be down. So this is the sensitivity and specificity. We can calculate positive predictive values and negative predictive values. Positive predictive value is out of the total test positives, how many are actually positives? Out of the test detected positives, how many are actually positives? Same way out of the test detected negatives, how many are actually negatives will be the negative predictive value. You can also have this likelihood ratio. At this stage you can remember it is the measure combining sensitivity and specificity. Basically what this likelihood ratio is, the chance of a person having the disease has how many times changed. That is the likelihood ratio. It can be for the presence of the deceased or absence of the deceased, based on which we have likelihood ratio positive and likelihood ratio negative. We also have this Fagin's normogram, pre-test and post-test probability and the likelihood ratio calculation. Then the next important parameter is the reliability, that is the repeatability. It is affected by variations which can occur due to observers, subjects, instruments or techniques. This can be statistically assessed by estimating the degree of agreement between the two measurements. The level of agreement can be calculated by the Kappa statistics. If the microbiologist diagnosis is the gold standard here and the technician's diagnosis is the test we are validating, then we put the 2 bar 2 table like this. To calculate the Kappa statistic, we need to calculate the observed agreement, that is we need to calculate the true positives and true negatives, true positives plus true negatives divided by total is the observed agreement and we need to calculate the expected agreement that is calculated by row total into column total plus row total into column total divided by grand total into grand total which will yield this value. Now the Kappa statistic is given by the formula or the Kappa coefficient is given by the formula observed minus expected divided by 1 minus expected. So 0.85 minus 0.754 divided by 1 minus 0.754 which gives 38.8 percent rate. Now how to interpret this Kappa value is as it is close to 1 or 100 percentage it is the complete agreement that is the agreement is better if it is equal to 1 it is complete agreement if it is close to 1 it is the better the agreement between the either the two observers or the two subjects or the two techniques or the two instruments or any method of measurements. Usually Kappa up to 25 percentage indicate a mild agreement, 26 to 50 percentage indicate moderately strong agreement, 51 to 75 indicates strong agreement, more than 75 percentage indicates very strong or excellent agreement. This is how we interpret the Kappa statistic value for the reliability. Then the third important parameter is the economicity we need to look at whether the test is safe for the patient, cost effective and available at our location. Then we need to ask is there a real benefit out of this test. And the third question we need to ask is will the result of the test change my management in clinical settings that we need to answer this is the third point about economicity. So far we have discussed about the outcomes of the diagnostic test in terms of categorical variables that is this is present or absent. Suppose when the measurements is based on a continuous scale for example random blood sugar HBO and C for a detecting diabetes militants then we have a continuous scale. In this example we have serum ALT for chronic paranchymal liver disease. The diagnosis is confirmed by liver biopsy. So based on the liver biopsy the disease present and absent are categorized like this and the serum ALT levels are categorized like this. Then we have taken the cutoff level of 20 that is more than 20 means then it has a good sensitivity but the specificity will be very low. At the same time if we increase the value to 100 the sensitivity will be reduced but the specificity will be very good. So we need to have a balance between the sensitivity and specificity. If we put up the sensitivity and specificity for different cutoff level as the cutoff level decreases the sensitivity increases. Sensitivity also increases the specificity decreases. In that case we need to identify a cutoff value with maximum sensitivity and specificity. In this scenarios we use a ROC curve otherwise called as receiver operating characteristic curve. This is a curve with sensitivity on the y axis and 1 minus specificity in the x axis. So this is the reference line and we have plotted the sensitivity and 1 minus specificity for different cutoff values. So we need to look at the value which is close to this top corner. The best sensitivity and specificity values can be identified using this ROC curve. We need to understand how are we calculating the sample size for this validation studies or diagnostic studies. First we need to specify the expected sensitivity of the test and specify the acceptable deviation. The expected sensitivity can be taken from previous studies. We calculate A is equal to sensitivity into 1 minus sensitivity divided by the acceptable deviation. If suppose we are validating ELISA test for HIV infection our rough estimate is that sensitivity would be 95 percentage and we accept a deviation of 3.3 percentage on either side then we need to calculate like this 0.95 into 1 minus 0.95 that is 0.05 divided by 0.03 the whole square.  Then we need to calculate the actual sample size from A by the formula A by prevalence. So let us say the expected prevalence of HIV infection in the population is 5 percentage then we need to put up 33 divided by 0.05. So which yield 1060 as the desired sample size for your study. What are all the steps in a study on diagnostic test? We need to clearly define the research question and its background significance. Specify the variable of interest whether it is categorical or continuous then the settings then the gold standard which we are going to compare then the reliability or repeatability then the accuracy or validity which is given by sensitivity specificity predictive values and likelihood ratio then we need to calculate the sample size then we need to make every subject undergo both the diagnostic test gold standard test and we need to arrive at the 2 bar 2 table we need to calculate the accuracy parameters such as sensitivity specificity likelihood ratios predictive values and capacity for reliability. We need to decide the usefulness of the test based on the safety cost availability acceptability and economicity for diagnostic test we have a good reporting guidelines called start criteria it is standards for reporting of diagnostic accuracy studies it has 30 essential items as I mentioned here so we need to look at as a checklist based approach we need to mention all these items in our manuscript in order to make our manuscript better so this start criteria will help we also have one more criteria called tripod criteria that is transparent reporting of a multivariate prediction model for individual prognosis or diagnosis easily accessed and downloadable from EquatorNetwork.org now how to critically evaluate a diagnostic test are the results of the study valid you need to look at the start criteria what are all the results you need to look at the validity and its parameters reliability and its parameters will the results help in the care of my patient you need to look at the safety cost effectiveness availability then you need to look at the real benefit present or not and also we need to ask ourselves that whether the result of the test change my management or not these are my references if you have any doubts and feedback you can contact in this email id or post in the comment section if you like this video please share it to your friends if you haven't subscribed to our channel please subscribe thanks for watching this video


All right, good morning everyone. So quick note about quiz one that is coming up what soon next week So you'll see that the other section is kind of behind us in some ways and we're behind them in other ways Don't worry about it We'll look at the quiz stuff together and anything that both sections haven't covered. We'll just throw out So we're all good and like for example, the other section doesn't know how to make processes yet. They haven't gotten to that fun fork orphan zombie discussion yet, so That and that's the hardest part of the course. So we essentially front-loaded everything the hardest part of the course is already over not really and Then Yeah, I guess that's it So quiz one two will be mostly like multiple choice true false like 80% of it And then the other 20% of it will be like here explain something Right, so they should not it shouldn't be too bad. It's only going to be an hour. So For better or worse, it'll all be over soon All right, so today we're going to be talking about IPC we can kind of relax and just learn for a little bit None of this will be on quiz one because the other section won't cover it But it's just kind of important just to help us understand what's going on There's some things at the end of this lecture that they have covered that I'll point out that is valid for quiz one But for like the first half of this course we can just kind of relax and enjoy the ride That is IPC or inter-process communication because remember if we have processes, they're completely Independent from each other one doesn't affect the other even if we change what looks like the same memory address They're completely independent. It doesn't affect the other one While in a lot of scenarios if we want to do something useful We actually have to communicate between two processes and the mechanism for that is called IPC Which stands for inter-process communication just a fancy way of saying communicating between two processes So any communication between two processes since by default everything is isolated. It has to be explicit and then therefore Explicitly allowed by the kernel right you want to make sure Processes are talking to other processes that they should be talking to So you can think of IPC at the most basic level as just transferring bytes between two processes and I mean in computing We're just transferring numbers between each other and just giving meaning to them Just because we want to right the the at the most basic level. That's all computing is So reading and writing files is even a form of IPC, which you've all done before Right, so if you have a process that opens a file writes to it that would create a process that process writes to a file and then later on if another Process reads from the file that's actually communicating between two processes that aren't even alive at the same time So another process comes reads from that file and that's how you get bytes from process a to process b Right, and that's all done through the read and write system calls And they just allow any bytes. They don't care So the simplest thing we could write Or one of the things we could write is a process that writes everything it reads Because remember we have these standard file descriptors. So standard input is file descriptor zero Standard output is file descriptor one so we could read from standard input, which is just By convention file descriptor zero and then we could write to standard output, which is again by convention file descriptor one and Let's go ahead and just see that and we'll see if it reminds of of any program. We've seen before So here is our program read rate So in our program we just declare a buffer of size 4096 this number will be important to you later on when we get to memory management, but for now we can just say hey It's a kind of big buffer So the read system call Takes a file descriptor a pointer to a bunch of bytes that you want to that can store some Bites that the kernel writes for you and then you have to say the size of it so we give them a pointer of Approximately 4,000 bytes and say hey you can write up to 4,000 bytes So this is in a while loop that just continuously calls it while it has some bytes read So the return value of read it returns a number of bytes read so if it's greater than zero it's read some bytes and We'll have to read more if we want to get all the bytes of that file descriptor So after we read some bytes we go ahead and write to File descriptor zero using that same buffer and just writing out the number of bytes we have read in and There it will also return the number of bytes written because the kernel Doesn't really care about you too much your write system calls merely a suggestion It can write zero bytes if it wants to and tells and asks you to retry Or it just might do partial writes and then you have to deal with the consequences at the end of that But it's a standard C function. So if there is an error it returns negative one sets error No, so we just print out our error and In this case I said that it might not write everything So I want to be lazy, but also be kind of defensive So I'm just going to assume that it always writes out the number of bytes I've read in before so it just outputs the whole buffer And I don't want to be caught by surprise So I just put an assert there that if it doesn't if it does partial reads or anything weird I'm just notified of it instead of like doing what Java likes to do and kind of failing silently and being possible to debug and Then at the end this right so the while loop will go through again while read is greater than zero Then there's two options to break out of this while loop One being if there is a error in read in which case, you know, it would return negative one and We assert that the only other value at this point if it's not an error and it breaks out that loop This is just a sandy check mostly for documentation because this should never Trigger is that the bytes read is zero and you'll notice that there's no like end of file or anything We could read an end of file. There's no end of file character or anything special The only way you know you've reached the end of the file is if read returns zero like I've out of bytes It's done. I don't have to read anymore So let's go ahead and execute that so it's just sitting here, right? the first thing it needs to do is Read and reading from standard input which by default if I just type something on my terminal It's just waiting for terminal input So I could do something like this and then if I hit enter, what does anyone expect to happen here? Yeah Yeah, so it should output hi hi hi back and anything I type here Should just echo it over and over again Until I hit on Unix if you want to like close the open file descriptor in your terminal You hit control D and that means end of file. So read would have returned zero and then it goes ahead and exits the process Does that remind us of anything? We've seen before might have used if we've used a bunch of Linux stuff before yeah Echo wait is that what echo does? No, nope any other little programs we've used if you want to display the contents of the file on your Terminal what? Sorry See yeah, so we could use cat. That's a that's another way to do it But that's like a full-blown text editor, but I could use cat right if I use cat And do it it looks exactly the same and I hit control D and it ends so What we just wrote is actually cat so cats not that complicated It's like but we'll see soon. It's actually kind of powerful to have that you've been using it And I mean how many lines did it take us to write it like even error checking it took us like 19 lines If that there's like header files up there, so it didn't even take 19 lines So that's the entire implementation of cat cat would do something smarter if there's like a partial right there, right? It would retry the right, but that's just another while loop. Oh We've written cat that's kind of cool Yeah, sorry So right will just always just keep on appending stuff By default Yeah, so the question is with the right does it just always append if it if the file descriptor happened to represent a file Or can we go backwards and overwrites things the answer to that is we can go backwards to overwrite stuff But we won't see that till later, but the default behavior is just to keep on appending bytes to the end Yeah Yeah, so the question is is If inner buffer there happens to be a null byte somewhere Does that stop writing and the answer to that is no the kernel doesn't care It's just a bunch of bytes if it stopped at the null bytes You suddenly wouldn't be able to write zero to any file, which would be really really weird The kernel doesn't care a null term name string is just a C convention. The kernel does not care whatsoever about it So you can write anything including the null character. It'll just keep on going it'll write as many bytes as you ask it to No matter what the byte is okay So let's extend this a bit. So here's just just for your Reference read just reads from a file descriptor and if it returns zero it means There's no more data to read from there that that file descriptor is essentially done with and you could go ahead and Close it or just ignore it. Whatever you want to do but always you should always check for errors to like Especially for Right, it's kind of weird because we now know printf calls, right? And it might not ever write the bytes at printf actually has the same return type where it tells you the number of bytes It's written but who's ever checked the return value of printf? Right one person Alright one person's checked the return value printf but we just kind of assume it works because For the most part if it's under four thousand that four thousand ninety six bytes, it'll always work For the most part Yeah, the right just returns the number of bytes written you shouldn't assume it's always successful. We'll see Actually, we won't see that but you shouldn't assume it's always successful But I guess for the purposes of this course if they're small you can assume it's successful But always programmed defensively put some asserts that So if you're not right, you actually know what happens and can actually fix the problem so and of course Communication to two-way channel right in our process we read from standard in and then write to standard out well Some something was communicating all the bytes. I you know, I Typed in to my process So there had to be some corresponding thing on the other side of that file descriptor So whatever file descriptor zero was in my process Someone called write to write some bytes to it that I could read in my program and then consequently When I wrote some bytes out another process had to read the bytes out so it could display what I just wrote Right and that's kind of a powerful concept. We'll see as we go on So, yeah, and there's a reason for doing the standard file descriptors as opposed to just confusing you relentlessly So what we could do as a little trick is we could close standard input, right? There's a close system call that just takes a file descriptor that closes up a file descriptor So we don't can't use it anymore We could close file descriptor zero that would free it up and open a file instead right in lab one You had to do that open system call that returned the file descriptor So Linux and other unique systems just will use the lowest available free file descriptor for new ones So by default you'll have like zero one Sorry zero one and two open so if you open just a new file you'd get it get file descriptor three But if you close file descriptor one and then open a file that file will be file descriptor zero So let's see what happens when we change that So we're going to keep the exact same core loop we had before and we're only going to add a open call so here we just checked that there are at least two arguments and if there is Yeah, if there are exactly two arguments if there are exactly two arguments we take the Argument as a file we open it as read only and then open will give us a file descriptor And this case since we close zero it would get assigned file descriptor zero and then otherwise We'd have the exact same program as before So without changing anything it's now going to Read from a file instead of read from my terminal right if I execute if I be meta and do open example and open example C read now instead of reading from the terminal should be reading from that file and again We didn't change where it's writing to so it should just appear on my terminal right, so does he so That's the contents of the file. It's now on my terminal and that's the exact same thing that would happen if we catted that so We were missing some functionality of cat, but now we have it so we've written a full cat program now Right, and we didn't actually have to change the core logic here, right? We just we just read from descriptor zero and we wrote to file descriptor one and By changing what file descriptor zero was we can support lots of different things and now we can support a terminal We can support files and all that great stuff Any questions about that? kind of cool well, I Didn't actually have to I could have just kept my read write example if you're using like bash or something like that bash allows you to change Where file descriptors go and will open files for you So you can support files without ever having to write any open system calls or any file handler code whatsoever So in this example, this could be read write example because I don't give it any arguments You can use this character on your terminal and It will essentially replace file descriptor zero Which is why it points into the process so you can think of as changing standard input with Open example dot C so your terminal itself will open that file for you and then feed it into that program So even if I do the read write example that doesn't have an open system call whatsoever and I feed that file into it I Get that file right back out right Okay, we don't want to do that. So I get that file right back out. So The way standard file descriptors work is hey your programs can even if your program doesn't support files Through kind of just modifying what file descriptors point to you can have it support files Without the process itself actually having to support files So you didn't actually have to write that system or that open. We just kind of wasted our time other fun things you can do is there is this pipe character that essentially takes a process on the left and Connects its standard output to the process on the right So anything that comes out of cat open example, which would normally go to file descriptor zero right standard output Which would just dump the contents of a file instead of going to your terminal it would go to this process as standard input So let's see that So if we just cat open example dot C we get the normal file Otherwise we could We could cat it to open example or we could just pipe it to open example dot C and it should just pass into our program and Then we would write it back out again. So this is kind of a roundabout way to do that. I And you could also link them together So our program was essentially cat without argument So I could do this as many times as I want because cat just you know reads in everything. I it Right so everything it reads in so I could connect This just connects the two processes on either side so I could connect them as long as I want and I'll get the same output again So you could of course do something much better than that So the other way so if there's an arrow going to the left you can also have an arrow going to the right so What you could also do if I cat you know open example dot C by default they'll just go on to My terminal because that's what standard out is connected to But if I use this arrow So if the left arrow goes to standard in the right arrow goes to standard out So I can make it right to files without having any file handler code So I could say output dot txt and then that would Take that open example dot C redirect it to a file called output dot txt now if I look at output dot txt It's going to have the exact same contents right and also What does this? Actually remind you of Yeah Yeah, so Because of the Unix philosophy of having all these file descriptors you actually don't need a CP command You can just use cat and redirect stuff. So copy is mostly just for your convenience Otherwise you can all you really need is cat Which is a dead simple program just writes out everything it reads in and hey you can copy files You can do all sorts of fun stuff That pipe character. Yeah, so it just connects This process is standard output to this process is standard input Yeah, so if I just run this example dot C It'll just show that contents of the file on my terminal if I Instead do that pipe character. It'll feed that contents to this process Which unfortunately just does the exact same thing but instead of going directly from This process to the terminal it goes from this process To this process and then this process that puts it to the terminal Yeah, yeah, yeah, that's just error checking code. Yeah, so it's like a standard C wrapper. So if it returns negative one, there's an error and it sets error. No Yeah, so that's just a standard thing that C sets for you for now until we learn about threads It's think of it as a global variable. So it's a global variable that C controls for you Yeah, yeah that and that's just the convention. That's just the Unix convention Yeah, so the question is is it always guaranteed that zero is like valid and can read and No, it's just a convention. Thankfully everyone follows it because your programs work But it doesn't have to be it's literally just a convention that everyone agrees to follow. Yeah. Yeah Yeah scanf just reads it does the same thing it just reads from the standard input so if since we know more about offering systems, you can change the standard input yourself and Similarly, I could close file descriptor zero open a file and then my print f's instead would go that file Yeah, yeah, it just keeps on going So like this so instead of just you know before it just took this output provided it to here and Cat just reads everything it runs in right so this output is going to go into the input of this Which is gonna output the same thing which is gonna go to this Which is gonna output the same thing which is gonna go with this Sorry Here's like the space doesn't mean anything And this is so the output of this would go into this process this cat Yeah, and then the output of this cat would go to this one Then the output of this cat goes to this one Then the output of this we didn't we're not changing file descriptor zero or one on this case And by default still the terminal so this one would actually print to the terminal Which is why I see something at the very end Okay, yeah In the code So file descriptors are unique So if I open two files one's gonna get file descriptor in this case One would get file descriptor zero the other one would get file descriptor three Yeah Yeah, and also So the question about the conventions of files. Hey, well is file descriptor zero always valid Well now it's not so someone else could do this to you just close zero and then start your process so if I do that and was If I do open example Give it an argument and I try and read it says bad file descriptor. So a good thing. I checked my errors So someone could have done this to you and then suddenly your process runs your file descriptor zero is not valid And you can't do anything because it's not valid So this could actually happen to you so always good to check your errors But if that happens someone someone not you is has a not followed conventions and something horrible has happened Okay, so this is kind of the more important thing it signals which you can think of as Interrupts, but they're interrupts for user mode. So everyone's seen interrupts and kind of used them before So has anyone ever like when they run a program hit control C? We've all hit control C How many times? Has it ever happened when you hit control C that the process doesn't end? Does anyone know why that is? Yeah, okay, so they're free to ignore it. So Signals are form of IPC and again we think of them as you can think of them as interrupts for user level programs So what you saw in your other course when you did interrupts at a hardware level The kernel would have to do that and we'll see some details of what the kernels job of handling those interrupts are Which are valid for quiz one but for now we're going to play in user land and it's essentially interrupts for user processes so if I Try and control C my open example or the read-write example We'll see that it behaves nicely. So if I run it and hit control C whoops If I run if I run it if I run open example and hit control C It stops and I can type back on my terminal again, which is what we expect But now we notice something kind of odd. What is this? Yeah, so that means that the process exited with this as it's like exit code and Nowhere in my program. The only thing I returned from main is a zero. So the question is who called exit 130 Not not you So we're going to see what we can do and answer the question Why some programs don't die when we hit control C? Yeah, so it's basically an error of Tanner. So we're going to see how to do that so control C just sends a signal to your process which is basically an interrupt and a signal is literally just a number and there's just Some numbers that you have to look up in a table or they're given names and you have to just kind of figure them out So control C sends a signal called SIG int so it's supposed to represent an interrupt from keyboard That the kernel passes on to you because usually that would have to be dealt with in hardware and Then there's default handlers that you don't have to write so there's the default handler for interrupt signals that you don't have to write will just exit the process immediately and It will add 128 to the signal number for its exit code So if we do a little bit of math, we got Returned 130 all 130 minus 128 signal interrupt must be signal 2 So let's go ahead and write our own signal handler. So this is basically how you set your own interrupt service routine So let's go ahead and see an example of that and here are a list of some of the signals So 2 is SIG and it which is interrupt from keyboard And there's some signals that are non-standard, but these are the ones you'll probably have to deal with and There's SIG kill which we saw last lecture, which was like the uber kill so that's number 9 and that's terminate immediately and you can't install a signal handler to interrupt or to kind of Handle that signal because it's all done by the kernel and then remember your process is ultra dead at that point Then we see everyone's favorite signal 11 So that is a memory access violation. That is a segfault Which kind of begs the question if it's a signal and I can handle it Yeah So you can actually a segfault is not the end of your program you can catch it and you can keep trucking on if you want and Then the last signal is signal 15. So that's like the nice way to tell a program Hey, you should stop whatever you're doing now clean up your resources Please shut down and that's like the nice way to tell a process to please shut down. So that's the default thing to do All right, let's just see what that looks like. It's a bunch of code that we can gloss over thankfully So in our signal example It's otherwise exactly like our open example and the only thing new is these register signal functions so basically this register signal functions all it does is register a Signal handler to run whenever this process receives the signal So this signal wants to handle sig int so control C basically or sig term Which is like the nice way of saying shut down Then in register signal the system calls called sig action and How that works is you just declare a struct of sig action and then you Would empty it with this to set it to null values and then you can specify a Signal handler, which is just a function, which is something that you can write and then you just call sig action to say Hey, I want to handle the signal and this is the function to call and Register signal this Format is something you'd like only ever write once you'd like look it up on stack overflow and then forget you've ever done it again So in the handle signal it takes the signal number as the argument So we can reuse it to see what signal it came from and Here's my amazing handle signal code, so I'm just gonna print F ignoring it and I'll return so now if we execute this program and I hit control C. I expect it to just keep on trucking but if I press control C it says ignoring signal to and then It would have returned so remember this is like an interrupt So you can't control when it triggers or anything So wherever your process is executing as soon as the signal comes in that signal handler is going to run no matter where your Program was executed, so it just boots it out and then runs the signal handler code to completion So it would print F ignoring signal and then go back to whatever the process was executing before Which in this case before I hit control C. It was just waiting for me to write output and we see good thing we programmed defensively because The read system call gets an error and when it prints out the error it says interrupted system call So you actually have to retry system calls sometimes because they can get interrupted by signals so the fix to that is we can write a Another version of the program that in the while loop It sees if there's an error and if there's an error and its error no is equal to this number that you would have to look up That represents an interrupted system call. We know that Read didn't return anything bad that file descriptor is probably actually fine I just have to retry read so I just say continue so I can go and issue another read system call So if I do that now and run signal example to that actually retries now if I hit control C It just says ignoring but otherwise continues on as normal and I can say hi hi Repeats back to me. I can hit control C again, and this is like your program that just ignored you. Yeah, I Feel like it Code or Terminal for oh this So that's the code for the interrupted system call So I just return that at the end that I return error. No if I see an error That's just the number that means the system call got interrupted No, so this handle signal this gets executed whenever it a signal comes in it's exactly like an interrupt service routine So no matter where your program is executing that handle signal will get called whenever it gets a signal So every time I hit control C. It gets executed in this case. It just straight up ignores me right and because In the other way to send signals to processes, so this is control C sends a signal But the other way is you know because of our violent natures instead of things being called Send signal or something weird the command is called kill to send a signal So I can look up what that process What's the process ID of that example? That's running by running pit of it's called signal example? To so I can get its process ID. Yep Yeah, the kernel would have something that's like an interrupt vector table for your process Yeah No, it's still running it's just Oh, yeah, so I just opened another terminal up there. So it's still running.  It's not happening.  Did something like this? Yeah, sorry That's just the error code for an interrupted system call Yeah, and I know I can just restart it So here I got the process ID of that what's running in my other terminal And I can send a signal to it and we of course do that with a kill command because we are violent people apparently So kill Essentially all this program does is do a system call kill. So kills a system call that sends a signal to a process So if I kill that like I really want to end my program We can see that by default it'll send signal 15, which is the please shut down.  You're not allowed to ignore kill Even though it wouldn't run it anyways it still kind of saves you from shooting yourself in the foot. Yep Register signal here it is so it's basically just declaring a struct and then Setting it to whatever it represents null values as to that function and then it just has a field called SA handler, which is a pointer to a function and that's just the function to run and Then this is this is a system call that registers that action to it So you can do more for an action But for now for the purposes of this course we just say what function we want to run when a signal comes in Okay, so that is Was fun so and This is kind of an example of concurrency too because our process Switches to the interrupt service routine, but it's also not exactly concurrency because it can't switch back and forth again As soon as it starts running that interrupt service routine, it won't stop until it's done and We'll see that Here's just for reference that you have to account for interrupted system calls sometimes because signals will do that to you signals are actually kind of the bane of programming on Linux and You'll have to use signals in lab 3 for stuff So lab 3 is probably going to be hard because you have to deal with this stuff So here's just more reference to send signals to processes using their PID This is just documenting what I showed previously when you got the process ID and tried to kill it Okay, so here is the more Valid stuff so most operations on your computer are like non valid. So think if you're the kernel having to deal with hardware changes Most things would be kind of like the non blocking nature So remember when we called wait before it just blocked until a child died and then it returned and then we handled it so For the most times especially if you're dealing with interacting with hardware There won't be special function calls for hardware that block They'll be non blocking you'll have to check a value or something like that and see if there's a change So just to kind of illustrate that we'll turn wait into a non blocking call We have to use wait PID With this no hang option and then it will make it return immediately. So and that's how Wait PID will return a process ID of zero instead of you know being an error or the child that died because now You know if you just poke it and say hey is a child dead the answer could be no So if you get a zero back from that it means you have a child, but they're not dead yet right So if you want to react to changes to a non blocking call we can either pull it So we just keep on trying it or we could hopefully have install an interrupt And this works at a user level and also at a hardware level. So because we're writing user code We're just writing C code. We'll see the We'll see what it's like at a user level So let's go look at our pull example So just to illustrate that Wait, so in our main program We're gonna immediately fork create two processes who cares about errors if it's the child It's just gonna sleep for two seconds and then exit. So the child process is just gonna sit sit there for two seconds and then you know exit normally in the parent process We'll set Temporary with wait PID to zero which should mean the child's not dead yet So we'll just initialize it to zero and we're gonna count how many times we call wait PID So we just have a while loop that keeps on pulling it So keeps on asking is the child dead is the child dead is the child dead over and over again And we'll go ahead and count the number of times we make this system call So if we go ahead and execute that which is wait pull example, we'll see Yikes so I called wait PID Over 200,000 times that does not seem like a good idea Yeah, anyone want to tell me was that a good idea why I just did or what's the drawback of that approach So I just wasted a bunch of time, right? It's just Pulling over and over again for over 200,000 times There is no change could anyone think of a better way to pull this without wasting so many calls. Yeah Without interrupting while still pulling Yeah, so if I wanted to To bring that number down. I could just you know, if it doesn't work I'll just sleep for a second or something like that Then if I do that Call wait attempt attempt. Oh, okay. Now it eggs it in. So what's the drawback of doing that now? Yeah Yeah, I don't know how big of a gap I choose there's some type of trade-off, right, which is why we're in engineering so If I set a number way too big, it's not gonna be terribly responsive, right? Because here I could wait up to a second Before I actually noticed that the child dies But the smaller I make that weight the more overhead I'm going to have because most of the calls are going to be useless, right? so having that trade-off between how many times I pull verse verse Yeah, how long I wait is one of the trade-offs you have to make But the better option is to just interrupt. So luckily for us Whenever your a child dies you happily the kernel actually sends you a signal So we'll go ahead and combine the two things we did and we'll register the signal called SIG child Please don't ask me why it's missing an eye We're we're programmers. We're trying to be efficient as possible So in this case it forks and to show that you know The signal will actually interrupt us in the child. We're gonna do the same thing fall asleep for two seconds and exit But in the parent, we're just gonna have an infant loop that sleeps for 9,999 seconds So it's the parents not gonna do anything useful. It's just gonna sleep pretty much forever So in our signal handler, we'll check that the We'll check that we're actually getting a SIG child in this case. I only installed that signal handler. So That should never be true. But otherwise I Handle that signal and inside our interrupt service routine I call wait there and I'm doing the same thing with no hang and This is just a shortcut just because I don't want to when you fork You'll know the process ID of your child, but I wanted to be lazy here and not save it as a global variable or something So if I put negative ones the argument wait PID becomes exactly like wait So it'll wait for the first child to return in this case. I only have one child, but So it shouldn't matter what I use And then if there's an error from that, I'll just return that I'll just print that error Otherwise, I will print wait and then I will end this process. So it should die as soon as my child dies So if I do the interrupt I The main process is asleep and now it gets interrupted with SIG child because the kernel nicely Sends it to me and then I call wait on it and it immediately returns and that's probably the better way to go about things All right, let's I'll quickly go over code and then take some questions So that was pulling this was interrupt So on a CPU if you're in kernel LAN So these signals are just like interrupts but for user mode But if you are you know the kernel and have to deal with real interrupts There's kind of three different categories You have to consider if you're the kernel and their name different things annoyingly So a true interrupt is triggered by some external hardware, you know like a keyboard Disks something like that and it's handled directly by the kernel And that's kind of what you did in your computer organization class All right, the kernel needs to respond super quickly because it needs to react immediately So it would just take that interrupt another interrupt is called a trap and that is triggered by users So for example a system call is an example of a trap So it's an interrupt that users are allowed to raise That the kernel handles and that was that SVC instruction or on Sun systems It's just called system call and that's handled by the kernel Which would suspend the calling process then handle that system call And then it would you know resume that process whenever the scheduler feels like it should run Then the last one is called an exception triggered by abnormal control flow so these again are handled or are triggered by user processes There are things like divide by zero illegal memory accesses and by default the handler is the kernel But you are allowed to overwrite this So with signals and that's the only way you can do interrupt like things as a user process So the process can actually handle those kinds of traps themselves so again, if you really wanted to you could handle your own seg faults and you know Magically solve them and then keep on keep on executing and Some programs actually trigger seg faults themselves so they can get interrupted, but it's like a whole weird dumb thing All right, any questions on that or the signal for the child or anything else? So and this stuff is like I've directly pulled this off. So this is like very valid for a quiz No hints or anything, right Yeah Well control C would be The yeah, it's it's more like an exception kind of because you're allowed to intercept it So it's kind of abnormal, but someone's triggering it for you So trap is just like a system call is a trap So you trigger it as well as a user process Yep Yeah, or like any Things the CPU itself has to deal with and then the kernel would have its own interrupt service routine for dealing with Keyboard input or whatever Yeah So that just means an error Yeah, all right. So wrap it up. We explored basic IPC that'll serve as well You even use the open system call in the first lab. So read write all good redirecting file descriptors is pretty cool Signals are not so cool, but we have to learn them They're kind of like interrupts for user process and the kernel has to handle all three different types of error ups So just remember pulling for you. We're all in this together


Hi everybody, Joe for Jaspy's CaseBrakes.com. We did it. We knocked out the last filler pack we got to do to unlock that football mixer that's coming up in a different video. But first, let's do this. Three different dice rolls here. First of all, we're gonna give away four spots within the pack break itself. Second dice roll will be the break, names and teams randomizer. And the third and final dice roll will be given away the last seven spots in that football mixer. Big thank you to this group here for making it happen. Let's gather up all of your names. First dice roll, top four after nine. Five into four, nine times. Six, seven, eight, and ninth and final time. After nine, here's the top four right here. Michael, Christopher, Kyle, and Kyle. So extra spots for you. Everyone else, don't worry. You're still in the action. But these four spots, these three people, Michael, Christopher, and Kyle, are gonna get slightly better odds to try to maybe win a mixer spot. So now, second dice roll. Let's gather everybody's names again. This time we'll assign you a team as well with the second dice roll. Five and a one, six times for names and teams. One, two, three, four, five, and a one. Six and final time. First tab, put your names and teams here. Five and a one, six times for the teams. One, two, three, four, five, and a one. Six and final time. All right, there's the first half of the list here. No trade windows in filler packs. Just wanted to get to the giveaway part as quickly as possible. All right, so let's print this out and see what we got. There's the pack we need to do. This, the mixer right here in the background is gonna be in the next video, a separate video if you're looking for that. We've got a numbered card. Yeah, 69 out of 99, Jared Dokes for Miami, that's gonna be for Michael. All right, so nothing too crazy there. We did get a numbered card out of here. Now let's flip back to this list here. Let's gather everybody's names again from top to bottom and everyone in between. Third and final dice roll. This is the moment we've been waiting for. Top seven after five. Three and a two, five times. Good luck everybody, fingers crossed. One, two, three, four, and fifth and final time after five. So from, so there's five. So from eight on down, we're only giving away seven mixer spots. From eight on down, it's gonna be sad times, especially for Pete, very close, but no cigar on that Pete. But thanks to you and thanks everybody for giving this a shot, appreciate it. Top seven, happy times for you because you are in the next break. Thomas is happy. So is Michael, Mark, Pete, Christopher, Thomas, and Christopher. So congrats to the top seven. After five times, we'll see in the next video for the next break, jaspyscasebricks.com. Bye-bye.


Guys, guys, I'm I'm scared. There's a lot. There's so much happening, bro We're back to the channel. We have episodes 461 and 462 over one piece watching today.  I'm so terrified Let's just get going if you knew the channel drop us up for my sake and let's get started Oh, it's like pops off. Where's the man himself? Oh, wait. They're more underwater. Where's the man? Oh, there's one like main one and then okay, I see. Oh my gosh, this is insane First division commander Marco. Oh my gosh 14 commanders. Oh My gosh Everybody's here. They come in for their boy, baby It's him. It's him Look at the double mingo's face There is the jigachat himself This is madness.  It went underwater. So how did the gate open? I love Luffy and his just ragtag crew is just gonna show up behind everyone. Your father is here or not Yeah, I definitely really think about if dragon would come or not. That's true. Oh He does know Oh my gosh, he knew already.  I was wondering since they revealed it He's worried about everyone Oh, what's he doing? His crew looks badass.  Oh, man. It's some backstory Started his crew Made a name for himself very quickly D Known about him for a while Oh They offered him to be a warlord that's not that shocking though.  Oh Shoot super rookies.  Oh My gosh No, wait, did he beat Jim base? He's so strong. Oh, I guess it's ace And I feel like Jim base prime is when he's in the water You're an even match with five days straight, bro. Oh, he did beat him.  I'm guessing he just saw him. Yeah talent Damn chance man, you could have killed him right there if he wanted to maybe he thought he did at first We saw this this flashback a long time ago I don't remember when we saw this flashback though. Now. I just have a full perspective Oh Okay, oh, maybe there's more to it. I don't know God the straw hats are missing a so much lore at this point It's crazy. They probably have no idea what's going down. Well, they don't we've seen where they are and what's going on He just took him and put him on his ship God's massive man I saw I don't remember looking like that when we saw white beard. Maybe it was just like he was on like an alternate ship or something beforehand Fourth division commander Thatch He just wanted off What oh They took all of his crew No, dude, they wait to join also. Yeah, they wouldn't need him anyways without much stronger So, why was he hooked up to these machines and stuff was he just that old? Oh my god, he actually got into his room Oh my god, I Love how he doesn't even need security or anything when he's sleeping with all these machines tied tied to him He's just that powerful. He's goes right back to bed. Oh my gosh. I love white beard so much No way he kept crying. He's got alphaed over and over again.  Oh, they tell him about about being roger's son.  I don't get it. It doesn't even make sense So I kind of wanted an explanation on the s still the ace the s marked out and so it began He was asleep Whitebeard's crew just getting grew stronger and stronger was the headache for singoku So all it took was I mean I guess ace learning whitebeard's character to gain respect for him and what he did for all his crew That he grew gained respect for him too Look at blackbeard's face. Oh my gosh. Did he kill that's bro. He's the one holding it, right?  Is he like genuinely controlled to see he's the pirate bro Yeah, I thought he felt guilty, but now my goodness Okay, so I'm assuming that whitebeard just straight up wants to take the Entire pressure off of ace's bag like he doesn't want him to feel guilty when we just saw he told him not to go clearly It's so crazy to see like the origins of that in the perspective of everything and speaking of which where is blackbeard now He recruited uh, what's his name shiryu from impel down But are they even gonna show up? They could be like a sort of a wild card in this war if they do show up Especially because he's I think from my perspective the most powerful Devil for users that we've seen thus far. I mean seeing whitebeards. His is pretty insane too episode 462. Let's get it Oh my heart is like pounding It just came from because he's family They both know what's true Oh my gosh I mean, maybe he's just saying because he like instilled that in him. Oh my gosh Dude, it's just about to pop off man all the ships in the back too Finally he speaks. Oh my gosh Gagomoria Yeah, I don't know man 100,000 soldiers. I wouldn't call them elite. I'm gonna be honest. It's gonna be just mayhem That's what I expect from mihawk for some reason I don't I don't see him agreeing with anything the navy does He's just here as a position Same for bella too. I think they're here for appearances She knows he's coming. Yeah, she trusts that he made it out and fell down. He's just like booking it this way Are we just gonna move past whitebeard's power? Is he doing it again? Wait, the sea level is dropping Wait, what was it because the door is closing? Those guys are just going flying by Oh my gosh No My water works. Oh, they're good. I figured it was from the door is closing. It was just drawing air I don't I don't know though Jim may knows Ah, what is it? Hello? Oh wait, it stopped Oh, they made it like an indent If the time is right, okay, buddy You don't receive the title of king of the pirates on a whim buggy. I'm sorry, bro His magnificent confidence Dude, they just they they just like about everything he does. What do they see? Even mr. Three isn't affected Brother we all escaped in bell down. He's just scared. He doesn't want to admit it Oh the current's back. Is it pushing them forward? What is happening? Are we going to find out who opened the gates in the first place? It's a cloud What it sounded like something crashed brother, what is happening? Dude, we know how strong especially kizuru and alkizia are too. We don't even know the third admiral We don't even know what singoku is capable of we have all the warlords. It seems stacked in the navy's favor They have jango for god sakes. Yeah, the water's going back. What was happening? Oh, is it a wave?  Oh my god Just to cause more chaos Tremor tremor fruit Bro He can cause tremors Oh my god Wow, singoku is actually like that shaky on this Oh my gosh, and everybody's just seeing this. Well, uh, sabotee at least Brother Is that what caused the doors open then the gates the music man It breaks my heart that the straw has to run with luffy though The two greatest forces There will be casualties Oh, man, I hope t-bone makes it out of this alive. He's the most important navy man to me aside from kobi Oh I'm exhausted. Nobody's even fought yet, man Luffy's not even there yet. And why is there an oarship? I'm gonna crash down on the hq You can't stop that. None of the warlords could for sure. Maybe alkizia can freeze it Okay, but Dude, that is a crazy devil root None of them are faltering. Oh Hey, what did I say out of anyone? Here's the only one I could think of that could stop it Dude Oh, that looks nuts Holy Young score, this is madness bro He's firing the first shots Whoa, he can just like manipulate like space time itself.    They have a path to the land though This is it, dude Really?  So it begins Look how confident this man is not even faltering the definition of giga chad. Look at him. They just like another tuesday Oh my god, it's starting. There they go Everybody. Oh, what about all the other ships too?  Oh, she gonna bite him. Oh, dude I have a smoker right behind her. I actually do care so much about smoker and dashigi too Yeah, they're the white beer crew man. Nobody's ever met. I like them guarantee it except maybe the straw hats Yeah, kichi inherently kind of helped them Oh, there's one of the vice though.   No shot, I would I would hope he doesn't fight for the navy man.   It's so beautiful. No Hey one of the good ones He's gonna stop it. One of them is gonna stop it Maybe why why beer can't do everything? I guarantee you that will not hit him though This show is cruel. It's genuinely cruel and so the god dang war begins, bro The stakes have never been like this in all 462 episodes. These stakes have genuinely never been higher It's so awesome that we built to this point where we know such a Wide cast of characters and care about them in different ways and know all their abilities Individually one by one and can weigh fights here and there Mihawk from episode. I mean when was it was Baratier like 14 or 15 of the show We know how powerful he was it was established way back then and it comes into play now Al Kiji who we met before water seven we know his powers It's how I was able to be like, okay, he has the ability to stop this It's just like it's it's a balance of knowing what you know to guess how the situations are gonna go And then just the surprise of however fights end up in each person's favor It's chaos and I just love it so much But that's the beauty of one piece is the world building and the building up of fights and characters That sounds like there's such a fan boy right now, but it's just it's all built to this This coming off the back of embell down Which already felt like a mini version of this But guys that's been it for episodes 461 and 462 over one piece watch through the Wars full-fledged now people are clashing if you knew the channel Don't forget to drop us up and I will catch you guys in the next one. Peace. Peace


I was fortunate to witness the birth of the Internet up close. When the web started, it had only pages of text interconnected with hyperlinks, but it had no people. I formed one of the first Internet startups with a mission to add people to the web. Exactly 20 years ago, the company launched perhaps the first social networking software, which included instant messaging, voiceover IP, chat rooms, web-based events, collaborative browsing. You see the interface from 20 years ago, and that's where we started. I sold the company. I bought it back. I sold it again. Then I got tired of buying and selling and decided to go back to basic science. I was very fortunate to receive two ERC advanced grants. The first one to work on biomolecular computers, which are molecular-scale computers that can be programmed to release drug molecules when and where they are needed. The work received a broad recognition following. The second ERC grant was to discover is to discover the human cell innage tree. Knowledge of the human cell innage tree will address many fundamental important problems in biology and medicine. For example, what is the origin of metastases, which are the root cause of cancer lethality, and that's an ongoing project. But what happened in the 20 years I was doing basic science? The internet has mushroomed from zero to more than two billion people. But what kind of civilization did it become? If a billion people decide they want to change the rules of a social network or replace its management, can they do it? I don't think it's even conceivable. So I think it's fair to say that in the 20 years that have passed, the internet has matured into its middle ages in the sense that it now consists of feudal communities with feudal lords that control everything, and billions of serfs that have no civil rights and can vote on nothing. We know from history that the middle ages were followed by the age of enlightenment. And one of the great thinkers of its time, John Stuart Mill, declared three basic rights, the right of thought and expression, the right to pursue one's taste and interests, both are supported by the internet in three countries, and the third, the right to assemble or to unite. The right of assembly is a precondition for democracy because without the right to assemble you cannot take collective action, you cannot form political parties. My main point is that internet technology today does not support the right of assembly and therefore cannot and does not support democracy. The reason is that even though we can easily form groups on Google, Facebook, you name it, we don't know who the people on the group are. A person cannot be the person he says he is, or maybe multiple persons are really fakes operated by the same person. Fortunately, help is on its way. The United Nations and the World Bank have a goal to deploy electronic identities for all of humanity by 2030. With electronic identities, one can easily verify the person who is on the internet and have confirmed identity and therefore support eventually the freedom of assembly on the internet. And then following it, we will have also hopefully be able to form internet democracy. But what kind of democracy should the internet follow? The internet does not have the size and distance limitations that require representative democracy. On the other hand, everyone voting on everything all the time, although technically possible, is not practical. So which way should the internet go? There is a new form of democracy emerging now on the internet, which is a hybrid of representative and direct democracy in which people can either vote directly or delegate their vote to someone else they trust. Delegation can be once or ongoing and can always be revoked or overwritten. It requires very complex software and algorithms to do it. But what's the internet for if not for that? Delegative democracy is like direct democracy in that every vote is done by everyone, either directly or via delegation, and it's like representative democracy in that most of the time votes are done by delegates that you delegate your vote to. There's a very small group of efforts in this era right now, but I believe that once electronic ideas are broadly deployed, there will be a cumbrine explosion of democracy on the internet and will have amazing democratic forms and communities that greatly surpass internetless democracy. Try to envision a future in which the entire humanity is united by, say, a Facebook-like democratic community. It's like the United Nations, except the members will not be nations. They will be the people themselves. And what I'd like to ask you is whether this vision of united humanity is compelling to you and what would you be willing to do to make it happen. Thank you very much.


But nitrates, concentrated in green leafy vegetables and beets, underwent a great makeover a few years ago from inert substances to having profound effects on the power plants within all of our cells, reducing the oxygen costs during exercise, meaning we can bust out the same amount of work with less oxygen. So one little shot of beet juice allows free divers to hold their breath for over four minutes, they get about a half minute longer. For others, this improved muscle efficiency allows athletes to exercise a higher power output or running speed for the same amount of breath. I profiled this discovery in an unprecedented 17-part video series, the longest I think I've ever done. It's just so fascinating. But that was back in 2012. What's happened since? Well, this all led to many athletes elite and amateur alike consuming beetroot juice prior to competition. Well, what does the new science say? Well, most of the studies were done on men, it turns out it works on women too, even African American women, and even more neglected research demographic. Same workload power outputs using significantly less oxygen after drinking beet juice. But forget beet juice, what about whole beets? Cheaper, healthier, can find them in any produce aisle, but there had never been any studies on actual beets until now. Whole beetroot consumption acutely improves running performance. They gave physically fit men and women a cup of half of baked beets, which is equivalent to about a can of beets, seven to five minutes before running a 5K. They started out the same, but during the last mile, the 5K race, the beet group pulled ahead, compared to the placebo group who were given berries instead. Though they were running faster, their heart rate wasn't any higher. If anything, the beet group reported less exertion, faster time with less effort. They don't call them block rock and beets for nothing. But if nitrates are so good, why not just take them in a pill? Nitrate supplements with names like Hellfire. Although they can work, their long-term safety is questionable. Non-vegetable sources of nitrates may have detrimental health effects, so you want to improve our performance. We should really ideally obtain nitrates from whole vegetables. The industry knows this. Instead, the market's an array of nitric oxide stimulating supplements. However, there's little or no evidence of the performance improvement following supplementation with these so-called NO boosters. The evidence is with the vegetables. How much money can companies make selling beets, though? How about a novel beetroot-enriched bread product? We've tried to get people to eat their fruits and veggies, and where has that gotten us?  And indeed, it worked. Red beet bread bought down blood pressures, improve the ability of arteries to relax and dilate naturally. Bread, therefore, may be an effective vehicle to increase vegetable consumption without significant dietary changes, because heavens forbid people should have to change their diet to improve their health.