Mae'r braffon wedi fynd ar y amddangos. Yn oedd hwyl iawn yn ddófain o'r gwerth i fynd ar y bwrdd iechyd. Ond yna'n ddod o'u bêl i'n ei bod yn hyn o'ch ddau'r hyn. Fyrydych chi. Fei'ch angen i ddelfwylio a'r dyflawn ei ddelfwylio. Yn raen ei ddelfwylio, dyfio'n cydwell gael, mae'r bwysig ar fynd i'r waith uch i ddadol. A dyna'n gilych cais ei ddelfwylio a'r hanes, ond yra'r gwahanol yn ydyn ni wedi bod yn arsu. Rwy'n dechrau'n meddwl o'r ddat fy modledd. Rwy'n meddwl o'r ddiddor o'r awm. Dw i'n edrych i ddataeth, ond o'r ddau cymdeithasol èu ddataeth ac oed yn dda i ddoedd bod ar y pannol, diwethaf, ddataeth. Dyna y gallwn amddunydd i bawb a Darren angen pa y bydd y ddau heb. Ond rydym wedi bod rydw i. Efallai rydw i'r bodyn bynnag Waiting Tony yn 3 poynau gallwn i gael yn ddau o'ch ddaiddau o'ch ddau oeddaeth, ddweud o'ch ddau o'ch ddau oeddaeth. Felly mae gennym hwrnod y gweithlwn i'u ddod i gweithlwn iaith. Byddwn i ddau, dyma ar gyfer gyffredinig a rwy'n wedi gyda gweithlwn iaith, ond mae cyd-deddygiadau was眼ol gwrthoedd yn erbyn hyn'r gweithlwn iaith. Y ddweud y gweithlwn iaith y gweithlwn iaith y gweithlwn iaith yn ei gallu'r gweithlwn iaith, yesterday I'm not updating my paper and there is the swid which dates from late last year so put out by you and you wider and Frederick salt so basically swid is wid plus some extras and Nora gave you some things about that they are great people like them because they have they cover a lot of countries and you can see it's around 170 countries in both cases they cover a lot of years wid goes back furthest and swid goes forward a bit more because he started later and has had the chance to operate some more but he has a 1980 cut off wid is has got four quality ratings so things rate from one very good down to two and three down to then four don't know whereas quality ratings are not really used in swid at all except maybe for the 1980 cut off in the sense you might argue that the past is something we don't know about so much one thing you'll find out immediately using wid is that there are genies that are based on a huge number of different definitions and sources and I'm going to come back to that issues a lot in what I'm going to say on the other hand you put up the swid fantastic guys there's just one genie or several one for net income and it's standardized on a list definition so the standard list definitions that Marcus will probably remind us about later there is the net income genie there's a gross income genie and the difference between them is redistribution I'm only going to be talking about net income genies today because there's quite enough to say about those if you use the wid you're one of the problems you'll immediately find is there are lots of gaps in terms of countries in years and that that might be a problem for you if you want to address particular issues so swid may seem an amazing bonus to you why the gaps are all filled in folks there are no missing country year observations basically what is done is that as Nora has hinted there is a multiple imputation model that is used to fill in the gaps annish as Nora reminded you every number in the swid is made up using an imputation model and I'm going to come back to that in fact so with the multiple imputation there are in the main file there are 100 multiple imputation values for the genie and there is a summary file which contains the mean of the imputations and I might also show you that that later and so people in the previous versions pretty much all the time have ignored the multiple imputation aspect of the data the imputation variability and focused on effectively the mean values so I've talked about the advantages and disadvantages in the paper I just basically assume that you know all the advantages I also talk a lot about file content and documentation I'm not going to talk about that at all today but basically I'm going to focus on potential disadvantages problems illustrate them and suggest what you might do make recommendations and because Tony's going to be pushing me for time I'm going to give you my conclusions first and work on from there so the first thing we we've been in this place before Atkinson and Brandolini in a couple of very good papers have reviewed the width predecessor the dining and square data set and all the issues that they raised there about comparability and data quality I mean basically the first task I set myself was to say are these have these issues gone away with more modern data sets and I'm afraid the answer is no that the issues remain very relevant I've got two conclusions for with users that people must report the details of their country year selection algorithms and justify the choices that they made there is an amazing number of papers out there where it's very difficult to find out how people have chosen the observations and I'm going to show you that's actually very important to do secondly people do actually acknowledge most of the time that there are these non comparability problems and a lot of the time they use something called a dummy variable adjustment process which I'll talk about a bit later on but basically it's too simple and people need to get wise up and use more sophisticated approaches the swed well I'm afraid I'm going to disappoint the IMF or I'm basically going to suggest that they should rethink their strategy my headline conclusion for the swed is that it provides plausible data but not sufficiently credible data unquote there are two things you could think about one is basically about the point estimates bias in other words and that's driven essentially by the imputation model and that's where I've got my main concerns the other aspect of it rather interestingly the precision issue that is if you ignore the multiple imputation nature of the data the when you derive your estimates that doesn't screw things up very much which is pretty amazing really but that's how it seems to me so overall I recommend the weed rather than the swed but that support is very conditional and it refers back to points two and three which are major points we've already heard a lot in the talks about where we can get differences across datasets and non comparabilities issues of data quality I've summarized them on the left hand side in terms of differences of distributions and on the right hand side in terms of differences in data sources and sorts of adjustments that people might make so for example in the resource measure income blah blah blah a big difference that will come up is the difference between gross income or market income and net income but there are all these other headings another thing to know about of course is that I mean the weed provides a series of variables which help you identify the differences on these various definitions what that also means is that you can take different combinations and work out how many data potential data series you have and the answer is a lot as I shall show you but for the first thing we have to remind ourselves about all this is a real trade-off problem and that is between quality and coverage a lot of people coming into this area basically want to have global coverage uh but the headline message is here and we've heard it already today is that the more global you want your coverage the greater the prevalence of poorer quality data that are included so I've extracted a table from the paper that has across the top time periods on the vertical on the vertical axis and in rows is regions of the world and the difference between the top and the bottom panel is that the top contains all the observations that are in weed and the one at the bottom is just focusing on the good quality observations the quality equals one and the first thing you'd note in the the top is that all cells of the matrix pretty much are populated and boy there are a lot of numbers however if you go to the second panel you immediately note that there is a substantial drop in the number of observations so that means if you work with the top you're including a lot of poorer quality observations moreover that that uh selection is very selective look where the the entries are concentrated in the bottom half of the table basically you start losing all the observations for africa you lose for pretty much you know a lot of um developing countries which might be the ones you're interested in so that is a trade-off conundrum if you will that has to be faced up and I don't think any matter of adjustment can get around this issue but it needs to be thought about a bit more so this might multiple data series thing so my headline conclusion remember was we need to know about algorithms I didn't know about these data at all before I started in this so I but I know about UK data so I looked at the width for the UK that's the 99 observations on the left hand side time on the on the horizontal axis genie coefficients on the vertical axis each dot is one of the observations the black diamonds are the quality equals one and the hollow ones are the quality the other ones and basically you see that uh we get this concentration issue and moreover there are a lot of black dots um over this but moreover for each of the different years you can still find repeated observations per cell okay just to round that home let's go to Finland why should we go to Finland rather than fact that we're just we are here of course um is that part of my point is that these are countries where it's typically thought that the quality of the income series over time is relatively high quality so we could you know so things we've got problems here we're pretty much going to have problems any other country so if we just focus for Finland on the quality equals one observations we tidy up some of the variable names in wid and do things like that we can still come up with four times three plus one is 13 different series okay this is just out of the wind so which one do we choose we need to know and quite often folks we don't know and so at each of you know any given year here although you tend to see a sort of view shape there you'll get different views about the precise picture about levels and about trends what about comparing with external benchmarks well this has been a theme already in many of the talks have things changed very much the answer is well things have got better since the ackinson brandolini jl article but even then there are some quite mark differences that exist so here this picture shows focusing on one year around 2000 where i'm comparing wid observations with observations that come out from the europe stat online database and from the lists key figures and here we're all restricting ourselves to observations that are essentially the same as the list key figures one so it's all pretty modest supposedly in terms of definitions and of course that restricts the number of countries if we want to have three observations but if you look at the the heights of the different bars for for these european countries you can see that there are some quite large differences in terms of percentage points you know if we take two percentage points in the genius quite a large change most countries don't change by that much every year you can see we get differences of up to four to five percent in some years so even then you know there are differences and and if you were to use the different series it would change rankings and so on what about a developing country well this is china in the wid and this is even if you're focusing on the observations where uh we're not taking account of the differences between rural and urban and so on this is just focusing on the whole country everybody we have this quality coverage conundrum even within this country so if you want to look at a long time series of inequality that includes china then folks you have to go down to quality equals three rather than quality equals two that is the triangles rather than the squares okay so that gives us the series with the the funny drop down here which you wonder what's going on moreover this point about having multiple observations per year even when the the wid definitions suggest that you've got exactly the same income definition you get really big differences look at 1995 huge difference in the genies that are going on here and even if you focus more and more on observations that are have got even more consistently dark divine observations so these are the ones that are filled in rather than hollow and there's a few of them around in these pictures then you still get big differences 1995 here you've got some oddities and so on so there are big differences in it if you pick up an article for example by these guys who are quite like the article in many ways but they also do some benchmarking against wid and their picture looks quite different from mine i've no idea why okay so that's wid what about the swid okay so the swid um how's it generated remember the the key thing is that all the observations are imputed and the idea is to use an imputation model so first of all the selections and exclusions as i said focus on um the pre 90 get rid of the pre 1960 wid observations and so on then okay here's the the imputation procedure it is really complicated so um there are pages in my paper about the the details because the details are very important but the idea is actually very simple so let's just suppose we have two data series for the genie coefficient for a large number of country year observations one is both based on gross income or market income if you will or just let's call it gross income and the other one is on net income but the problem is that some of the estimates are missing for the net income genie so what you do you are identifying assumption is the following you assume that the ratio of the genie for net income to gross income is constant the same common to all countries within a particular group of country year observations so that that provides you with donors if you will and that gives you an estimate of that ratio call it rg and then basically given that ratio you go to the missing folks in the cell multiply the value that you do have bind the ratio and out comes your number that's an imputation it's much more complicated this it's regression based the more than 20 different data types of so many different series lots of different definitions of groups and are rather unclear various other steps including smoothing and as a bonus salt also provides share of the richest 1% in top income database sense there's a basic problem though with this imputation idea about this constancy within groups of observations and by the way it is just a multiplicative version of the dummy variable adjustment method that people use there's basically I would argue that there are two competing the demands that can't be met basically you have to group observations in order to have donors okay to provide the values that are going to be imputed to the missing observations and of course you want the groups to be as big as possible so that you get a reliable estimate within the cell okay and to have some observations after all but then of course you need lots of observe as lots of groups is possible to take account of the acknowledged variation in the difference between the genies for the ratio of gross income grossing town to net income but the trouble is that if you have more and more groups that means the average group size the number of countries goes down country and country years so in the limit you have no donors so it's this sort of problem you know and yeah so basically I don't think you can solve the problem given that the data they're available I don't think it can actually be met satisfactorily in in practice so the assumption that's basically built into with is us with is likely compromised so I don't think with users should however smirk the fact that there is this non-constancy reminds us that with users who work in terms of genie differences with their regression adjustments need to look out and they need to be much more sophisticated than they have done in the past so it's a judgment call on both groups I understand okay there are other issues with the swids imputations that I don't like imputations of smoothing definition of the series there is a genuine bug in the computer code for the share of the top one percent series so simply don't use these data and it's unfortunate that salt who knows about the bug has not advertised it on the other hand do applaud the fact that he provides replication material I'm going to show you some evidence from the swid to explain or show you the sorts of things that you get out of it so this is for a net income genie so how can you benchmark the swid well you can try and do this benchmarking exercise again and see if for situations where you think you've got good data what does the swid show you for it so the sort of thing you would get is so here's genie his time these dots here the dark dots with the squares are the means of the hundred imputations for each year so for people who have not taken account of imputation variability in the past I think IMF those are the numbers that are used in their regressions okay now the and there are good probably reasons why they didn't because in the previous version of swid the multiple imputation bit was not as easy to use as it is in this later version okay the gray dots are summarized the imputation vary variability in this so the whole this is all the range of the imputations that's 100 gray dots in each years I much prefer to show it this way salt refers to confidence intervals that's to me is inappropriate language because they're not confidence intervals based on standard errors in the sampling variability sense the these are different okay so that you can see the series here for Finland it's benchmarked against list key figures what do you note here is that here we're going before the wids series so this is where we're drawing on the imputation bit drawing information from across countries in years elsewhere and it's well reassuring that the imputation variability is a lot larger if we look at the other end of the series again we're pushing out and here we have the the swid imputations but here he's not even online with the list key figures what's going on here and the difference the difference that I'm going to finish Tony like for us while finished and the difference is here is that these list to two list key figures were not available to salt when he generated the data so he wasn't able to standardize his series but however his out of sample prediction is a bit way of them out of the mark the other thing is that in previous years the levels and trends are also different so if you think about throwing these numbers into a regression model the numbers and the patterns the relativities compared to different countries different time periods are different and that's going to affect estimates if you do this for the uk you get a similar message i've suppressed the imputation variability in these pictures these numbers are the official income statistics in britain the only difference between them is a change in the equivalent scale so the series marked together in parallel virtually the same the swid gives a rather different picture and i don't believe the swid story china in kenya okay so you might have been quite impressed by the relatively narrow range of imputation variability in the swid that came up from those earlier pictures this is china earlier years look at kenya here look at the range on this picture by the way from a genio of 20 through up to 90 so you can get huge imputation variability in some countries and so the more that countries like this are put into your imputation model it's going to have an effect on your estimates and moreover there are differences in levels and trends to the extent that you can trust the wid observations in these two because remember when you move into the developing countries you're moving down the down the quality scale but interestingly for example for china this is the wid the swid estimates here correspond to the trend that's shown in official statistics but in fact if you go back to the xin zhu article that i was referring to before the penis one a nice part of that article is working with recent household surveys and suggesting that the trend is in fact better represented by where the wid one is pointing which is which is further up so the final part of the paper is to do a series of regression illustrations to investigate the extent the sorts of things that are going on and i've taken an illustrative example based on the blind or isarchy type of literature about the relationship between inequality and several other things macroeconomic approach and done some benchmarking substituting in other information good quality information when we have it and see whether it makes a difference the bottom line is it does make a difference part of that is because you're focusing on a homogeneous set of countries but once you get into a homogeneous set of countries you might as well not use the other sources um the other thing is that uh partly with the swid in the regressions nor a wants an answer to a question can you still use them in the regressions we cannot tell because by definition for a lot of the other countries we don't have a bit external benchmark reference point the observations are missing on the other hand given the benchmarking that we can do against good quality series over time in year you've heard what i've said but also if we look at precision if you simply ignore the multiple imputation variability interestingly if you take um proper account of it using for example the mi estimation suite in stator then you get the same answers so you know the issue to me is potential bias not precision uh so i've come to the end and there are the conclusions again thank you very much


Hi, my name is Melissa. This is our smartwatch. You can see it's nice box. Let's do unboxing. Yeah. So we can open the box. This is how people will get it. What is the name of the smartwatch? This model number is 06 and this is smartwatch and this user manual and accessories. The micro USB. Right here. Yeah. And let's take the watch out. Okay. So right here. Cool. So what's the functionality right here? Let me introduce it. This smartwatch supports both iOS and Android system. Yeah. Let's go around in the UI a little bit. So it's building 1.3 megapixel high-definition camera. You can take photos and save the photos on the watch. The parameters is LCD resolution is 240 plus 240 which is IPS for viewing capacitive, curved surface, capacitive touch screen. You can see some functions on it. So it's UI like this and people can go in the settings and do different things here. Yes. When you have this smartwatch you can answer the phone call and make a call on this watch. So it's pairing with Android and iOS right? There's no SIM card inside. Yeah. And how long is battery life? The battery life is about 5 days. 5 days. And you can talk in about 4 hours. Cool. Can you try to put it on? Yes. Of course. So stylish. And what's the price? The price is around $50. And also I can show you the other functions like the Produmter. This is really your healthy housekeeper. It will monitor your health. You can set your height, your weight, and the goal step you want to take. And it will help you achieve your healthy goal. Life's there. And this sleep monitor and this dentary reminder will help will guarantee your healthy life. All right. Yes. Which other is the camera? Let's do it. Take a picture. Yes, this you can take a picture of me. Okay. Okay. That's okay. That's great. All right. So this you can take pictures of people in secret or with them knowing. Yeah. And then share the picture and everything on WeChat and also you can take the video record. And you can also take a video. So you can take secret video. Yes. At the meeting. Yes. Take a secret video. Cool. Like James Bond. Now this and the series stop. This kind of watch was what I was dreaming about when I was a kid. And you can check. And now it's real. And this one. Oh, nice. Take a picture. I'm taking out this. Nice. That's a good quality display and nice size. Yes. And also have some record. You can see something and receive it. Yes. That's really useful. Yes. So you just have some idea. Just record it on your watch. Cool. Nice. Okay. So. And then we can also show the phone call and call someone like you can call it. And this same because I have successfully connected with mobile phone Bluetooth and call the same. The same. You can see. Yeah. So it's coming. And I can end. And you can just speak in there. Yeah. I can speak it. Make phone call and answer the phone call. And you will also receiving the messages from your mobile phone. Receive the message like your WhatsApp, Skype, QQ and so on. Nice. From this. Yes. So this is how it looks. Yes. This is nice leather style strap. Under this clock display have three kinds of. You can choose the one you like. And plus. Okay. You will choose it. Like this. Cool. In fact, I have made some functions in my sleep monitor. I have used it last night. When I start and in the morning I can check it. My sleep. My sleep is good or well. It's good. Yes. It's good.


going to enjoy this talk a whole lot more. So I grew up doing a lot of web development and hardly any other development, but hardware was kind of always my hobby. But the big thing is that hardware is hard.  It's so hard that I couldn't even find a good picture for this slide because there was no picture that I could find out on the web that explained how hard it is to develop hardware. It feels like everything's against you all the time. So you come up with a cool idea. Like at one point in time I was going to build a heads-up display for my car. Who does not want a heads-up display on their car? Yeah, that's what I see no hands. So I got really excited. I had this idea and I'm like, I need to find all the parts. So I figure out what parts I need, some LED strips, just lay up on the dash and shine up on the window, and some controllers and things that hook into the car to tell how fast the car is going. And then I go to order them. And I'm super excited. And the thing that hooks into the car is out of stock. So, well, that's all right. That's all right. I'm still going to be excited. It'll probably be in stock tomorrow. I'll just sign up for that little email that says, we'll email you when it comes in. So the other thing is that a lot of times when you're doing hardware is money. So a lot of parts of hardware, whether you're doing it professionally or doing it as a hobby, are fairly cheap. But some of them get quite expensive or hard to find, like it's called an ODB connector that connects to your car.  And you really do feel like this thing must be coming from Mars, the stuff that you order. Because sometimes it's coming from China and it has to go through customs. So you're super excited. And then eight weeks later, you get this email that says that it's touched the US border. And you're like, yes, four more days. And that's if you haven't decided to move on. Because if you're like me, waiting draws your attention away. We move on. I was excited about making a heads up display for my car. I still do not have an ODB connector to this day. That was like two years ago. So I got excited. I've ordered half of the parts. They're like sitting around my house or in my office. And the other half I've still never ordered. I've done like five projects since then. And it never gets better. You start to feel like maybe my idea was wrong. Maybe I wasn't that excited. Maybe it doesn't matter anymore. But either way, your excitement subsides. The butterflies come in. You find something else to look at. And you never get to that code. You've never even written a code for it. And then when that happens too much, I actually showed some of these slides. This is often how my wife looks at me whenever I say that I've got this great hardware idea I'm going to build.  And I'm not. My wife is an amazing person.  So hopefully if you get into hardware, you have somebody who can be your voice of reason. It's super important to have that. Oh, I went backwards. And the next thing is deployment. So deployment was working against you too. So you get all excited. You've actually finally get some parts.  And then you compile it and sometimes cross compiling. And it takes a while. I'm currently working in commercial doing embedded development in Elixir. And we have a project that takes like 10 minutes to compile.  And so like 15 minutes later, you get all this together and you get it over on the system. And you accidentally return to OK as your state for your gen server instead of the struct that you were supposed to return.  And you go through this whole process again and again and again. And it starts to get frustrating. The butterfly set in. You'd rather go outside. You'd rather build a heads up display for your car. I don't know. But it's tedious to find these errors. And then part of the errors coming in is our knowledge. So when you start working on hardware development, there are numerous ways that all the little sensors talk to each other. You have to learn a protocol. You have to read giant reams of documentation. This is for one tiny sensor that usually hooks to a system that you have multiple sensors. It's 27 pages long. I know that you probably can't see this very much. But don't worry, you wouldn't get much more out of it even if you were right next to it. So I don't even know what those graphs mean. And some of them are so cryptic that you don't even know what they're saying. But you still need to read them. And after a while, you get used to reading them. The other thing is I found is that our community is very inviting. And everybody's really nice in this community. But the people that are working in the hardware, if you go into the NERVS channel on Slack, they are the nicest people. Because they all know that you just got done trying to deploy on an SD card for the last 15 minutes. And it was your fourth time today because you had a bug. And then you realized that you don't understand I2C communication protocol. And you're about to rip your hair out. And you ask them a question, and they're like, oh, there'll be like five or six people. We have Connor Rigby up there from the NERVS core team. And I don't know how many times Connor has helped me. The other day I had a problem. It was just that the file that I had to get accidentally had .config.txt. And it wasn't supposed to have .txt when I downloaded it. So he spent way more of his time than he should have to help me out. That's true. I guess that's because everybody else in the hardware room is it needs butterflies too. So I just pulled you away from the real job. The other thing with hardware is you have to interact with the real world, right? So you have a sensor that's supposed to sense, I don't know, maybe lightning, right? So you have to wait for this real world event before you can test your software.  See, so Paul Lam, I think Paul's talking tomorrow. I don't know if he's here. He wasn't feeling too well. But Paul says you should start every great talk with a story. So all that other stuff I said, just ignore it. This is the beginning of my talk right here. Well, I guess I'll tell you who I am. It's me, Amos King. Everybody says that I look like 1010. So that's been my handle forever. Adcrons where you find me everywhere. I'm a binary noggin. I run an open source NERVS project called Grove Pi. Well, it's sports NERVS. You don't have to use NERVS. And then I have been in a host of a podcast called This Agile Life for about five years. But anyway, so does anybody know who this person is? All right. Anybody who doesn't know who this person is? Let me help you. Does anybody know who this person is? Oh, good. So Frank Hunliffe is the inventor of NERVS. NERVS is, for anybody who doesn't know, is a system of tools to build elixir run embedded devices. It handles everything from the Linux kernels that you have to deploy, all kinds of stuff. It's a whole set of tools, a whole community built around it. And a lot of people say like Jose is the nicest guy in the elixir community. No, I like Jose. Jose is a great guy. But Frank, Frank is amazing. So I met Frank last year at Elixir Days. I'm from a little town in central Missouri. It's about 4,000 people, about 100 miles outside of St. Louis. And I sit down at this table at Elixir Days and I start talking around and every single person at that table is from Missouri really close to St. Louis, including Frank, who now lives in like Maryland or DC or something. I don't remember exactly. And we started talking. Frank's a pretty quiet guy. But I got a little bit out of him about who he was and what he does. And then when I was on my way out, he's at the airport. And I like to talk a lot. And I see Frank sitting over by himself. And I'm like, Frank likes to listen. He doesn't talk much at all.  And I'm into hardware. So I start talking to him about hardware and asking him questions and trying to draw Frank out. And Frank tells me about this project called GrovePie. And the GrovePie is a hat is what they call on the hook on top of a raspberry pie. And it has a bunch of sensors and a very common interface to those sensors that makes it a little easier for someone who's a beginner to work. It's really geared towards beginners. And Frank really wanted a GrovePie library in the nerves ecosystem so that it would get more people in. And he had already started. So he tells me about it. And before I got up from sitting next to Frank, I had already ordered the Starter Kit and like 70 sensors. And I should have asked my wife about it. But I didn't. And so like the next couple of months, I had a lot of free time. And I worked on this library a whole bunch to the point that Frank actually just transferred it to my GitHub account and said, you're in charge of it now. And but at the same time, Frank sent me acrylic cases that he had laser etched at home because he's got a laser cutter. That's what I'm telling you. The nicest guy in Elixir is Frank. He's like sending me stuff. I cracked it. And he's like, oh, that's cool. I'll send you seven more. But he also sent me a lightning sensor. And I was like, this is really cool. And he said, yeah, and and I start looking at it. And he's like, you know, it'd be really cool if we had three of these because it just tells it tells you the distance when lightning strikes how far away it was. And he's like, if we get three of these, we can triangulate and we can tell exactly where it is. And I start reading in the documentation. This thing right here says that the range is 63 kilometers. And I don't know about you guys. I live in the middle of Missouri. And Frank is in Washington, DC. And I'm not sure how we can even get someone somewhere in the middle that will allow us to triangulate after 63 kilometers. I think that his math is a little off. But I told Frank it's been like a year and I've been talking about working on this lightning sensor. And I said, Frank, I have a really good idea. And he's like, okay, what's that? I said, I can't test for lightning. Like, it takes forever. And I'm not excited. Like, I have to get some code to be excited. And then I can't wait for lightning forever. So I'm going to submit a conference talk. And I'm going to implement all the code for the lightning detector for the conference. And Frank, here's the thing. I'm not actually going to run it on hardware until I'm standing on stage at the conference.  I totally respect you. You're nuts. But I respect you. So if everybody could could pull out their Twitter account, everybody who has one that's available and send one of these two things to Frank right now, that would be fantastic. He's expecting this today. He said that he couldn't make it. But basically, the top one is, I'm right. Or no, Frank is right. I'm always right. Frank's not right. Frank is right. And I am crazy. So if you think I'm crazy for waiting till I'm on stage to even test the software and the hardware, let Frank know that otherwise, my phone's going off like crazy. Somebody's doing it. Otherwise, do the bottom one and tell Frank that no way, this is awesome. And I'm not crazy. I'm completely sane. I personally think that the top one's probably right. So before we get too far, we really need to need to come up with some facts. So I went on to weather.com, which, you know, facts, I use that loosely when we're talking about weather, especially weathermen and weatherwomen because they never seem to get it right. But it says on there that there are 25 million lightning strikes in the United States every year. Now, again, it's according to weather.com. So it's probably just a guess.  And they said there are 9.8 million square kilometers in the United States. And I already said that my my sensor has a 63 kilometer range. So let's do some math. Okay, so with 25 million kilometers, our strikes at 9.8 square kilometers, that's 2.55 strikes per square kilometer per year. So we divide that by 365 days. It's 0.007 strikes per square kilometer per day. We figure out the area of our sensor, 12,500 kilometers, roughly. That means we have 87 strikes a day. So if we keep going through our math and going down there, we see that we should have a lightning strike about every 17 minutes. That's perfect. I mean, this talk, how long is this supposed to be? 40 minutes? We have plenty of time. We can probably get two lightning strikes if we're lucky. We all know that that's how this works, right? Lightning happens every 17 minutes. Like you can say you're watched by it. The great thing about this is even if this is true, and we do get get the SD card put in, plug it in, run our software.  It actually started up. Our GIN servers started up. It didn't crash. Let's hope we don't have a bug. If we have a bug, now we have 17 more minutes. We're up to 34 minutes, and that's just with one bug. I don't know about you, but every software I work on has a lot of bugs. I would hate for it to be the one right around detecting lightning because then we're like 34 minutes out. If you're doing this for a client, they really don't want to pay you to sit around for 17 minutes. But I just go skateboarding or something like that for 17 minutes, come back, why not? But I mean, we all know this isn't how lightning works, but bear with me. So documentation. This is out of all of this documentation, I thought about just putting all 27 pages of this up on these slides and just stepping you through each one of them because it's super exciting. It's like a Tolstoy novel mixed with Old Man in the Sea. So this is actually the communication. Somebody said that I have a moving around microphone. Okay, well, I'll just try to talk from over here. So this is the registers that you read. So this is a chart of all of the bytes that you're reading out. Every row is a byte whenever you're trying to read. So the first row, anything that says reserved, you can basically ignore because it's something inside of this device that you don't care about, can't change, can't do anything with. So on the first three bytes there are settings that we can change. The important one today is that AFE, GBA, it's gain. So gain is amplification. So how this lightning sensor works is that it has an antenna on it. And when lightning strikes, it creates radio frequency, some radiation that is detected by this antenna. And it actually says in the documentation that this device can tell whenever it's man-made or not. I think we can try to fool it, but I'm not sure. And it will, so it reads this RF and it looks at the power of the RF and can tell you how far away. And the great thing is that RF moves at speed of light. So it's instantaneous, even if it's the 63 kilometers away or right on top of the device. So this gain allows you to set this for indoor or outdoor. It only has two settings. So indoor it has a higher gain because you're detecting lightning that's outside and the RF gets blocked by the walls of the house. Outdoor has a much lower setting because the lightning is not blocked by near as much. So basically this whole device works by FM. Does anybody know what FM stands for? Frequency modulation, that's a great guess. It's actually Freakin' Magic. This thing works by Freakin' Magic. I was pretty amazed when I was reading all about it. And I used to do communications in the Air Force, like I fixed radios. So it was kind of awesome to realize that I could have used a radio to detect lightning. Who knew? So I took this chart and I wrote some code. So I read the first eight bytes. After that I don't care. So I only read the first eight. So zero to seven is the registers. The other things that we're interested in is on register three, the far right side is INT that's interrupt. An interrupt is an event that should stop you and cause you to see what's going on. The interrupts can be none, lightning, disturbance detected, which I think is like man-made. It never actually explains what it is. I'm guessing. And the other one is noise floor too high. There's so much radio frequency in the room that I can't read the lightning strikes radio frequencies. And then in register eight, so 0x07, the far right of that has distance. And that's going to be a number between zero and 63. Actually it can go up to 64. So zero, it's going to say overhead one to 63 is going to be an integer. And then at 64 it's going to say out of range. So apparently this can detect further than 64 kilometers, but it doesn't tell you. So I don't know if you realize this, but in order to test this, if I was going to write tests for this, so eight bytes, eight bits per byte that's 64, so I have to do two to the 64th tests. I hired an intern this year. That'd be a good job for him. So I talked to Nathan. He's my intern. I was like, hey, you should write these tests for me. And he said, yeah, no. He's a much smarter college student than I expected. So instead, let's go off the code. So it's binary. We talked about that. And we need, I used, I wish this was easier to, this is hard to do backwards. Nope, not that one. Don't look at that one. That's a secret yet. Hey, here we go. This is perfect, right? Perfectly readable. So actually, I was taking somebody through my slides and they told me I should never show more than 20 lines of code in an example. So if I can zoom in somehow here, there you go. 20 lines. Perfect. So I decided to use stream data and property-based testing using execute properties to actually generate all of this. This is the worst part of all of this code. It's not that complicated to understand, but there's a lot of it because two to the 64th test, I have a lot of data hidden in there. So basically, I'm trying to generate some data here on line nine. Well, you'll see like line six is interrupt. So that's the interrupt field that I was talking about. And line nine is tuple, constant, none, and then OB, zeros, all zeros. I could have put just a zero in there, but the documentation is based on binary. So I wanted it to look like the documentation, so it's easy for me to compare back and forth, which helped me catch a lot of mistakes where I type pro. So basically the constant on the left is what I want my parser to return to me. And the constant on the right is what the binary is that I read out. So this is just generating one little piece of that binary. And actually, this is just generating some data that we're gonna build our binary response. So we have the same thing with game. That there's the end door and outdoor that I talked about and their respective numbers. I don't know why it uses so many bits there when it's only two choices. Like why not just use one bit? I have no idea. I'm sure there's some like amazing engineering, electrical engineering choice that they made that this was the best thing to do, but I have no idea. And then we have distance. There's our online 29. There's our out of range with all ones. Line 39 is overhead if it's all zero. So this is actually made to tell you the distance a storm is away by averaging out lightning strikes. Cause apparently the very front edge of a storm, I don't know, apparently you can tell where it is by lightning. And then the middle one is a known distance. So if it's one to 63, which I pass in later. So okay, so that was just little pieces of the input. Here is the entire input being generated. I'm gonna, a lot of these are the other little blocks in that diagram that you saw. And then I need to put them together into a binary. So like lines 48 to 52 is the very first set of that binary. So the zero, so this is a two bit field. It's value is zero. This is one of the reserve fields. I don't care what it is. So I just set it to a constant because I'm never gonna read it. I'm never gonna care what it is. There's our gain that we talked about indoor or outdoor, but it's gonna be the binary. It's five bits long and then our power down, which this was one part of the documentation that I wasn't really clear on. I think you're supposed to tell this thing when you're gonna turn the power off, if what I'm not sure. So if we add those up, five, six, seven, eight, that's one byte and the next byte. And I'm sure that you guys don't want me to actually step through every single one of these. So just to generate the property, we're down to 81 lines. But I think they're fairly readable. It's easy to follow. You can compare it to the documentation pretty well. If I had run the formatter on it, it would probably be even easier to follow. And then here's our test. So I have gain and gain results. So the reason why I returned the tuples up above is that when I'm generating these tests, I originally had a bunch of ifs in my test saying, well, if the value of the gain was this number, then it needs to say indoor, otherwise this. And Chris Keithley, who spoke today, I actually reached out to him and said, hey, Chris, you do a lot of generative testing. Can you look at my tests? And he said, oh, generate the value that you want as your output with the generation of the input because it makes it a whole lot easier to change later whenever you see problems. And then it feels really good whenever your properties don't really change and you only have to change your input data. And I was like, you're weird, but okay, I'll try it. And he's right, like it feels really good whenever you don't have to change the meat of your test. So we generate all of these gain interrupt, known distance, known distance is used to get us a distance in case it's zero or 64. That's what the known distance integers there in that range are. And then we generate an input off of those. So those are the ones we care about. So we pass them into the input and then let the input come out. Line 91, we take the input, we parse it, we get an output. We assert that our output's distance is equal to the distance result from 87. So it'll be overhead, out of range, or one to 63. Our gain, so it's gonna be input or output and our interrupt result. So lightning, disturbing detected, noise, or none. I think that's all four. And so the test itself is fairly simple. It's the generating of all of that data that was the complex part. But I took it away. Now when I run my tests, all these property tests go and it doesn't run every possibility, but it picks like a random set of possibilities and runs like 100 of them every time I run my tests. So over time I build up a big confidence that this thing is working correctly. I promise that that is the most intense part of this whole thing. Now if I can find my, hey, there it is. All right, so that's not the only testing we had to do though. So I wanna say 2014 or so. Does anybody know who Sandy Metz is? I know a lot of this probably came from the Ruby community. Shh, don't say that. It's not cool in the Elixir community to say I did Ruby anymore. But Sandy Metz gave a talk about the magic of testing. And I really thought that this works with our gen servers and things like that too, is that there's really, I changed her graph slightly here, but not much, I'll get to that. So we have different types of messages is that when we want to query something in the gen server, it's pretty simple to test that, right? It already has some data. We query that data and assert that the data is what we expect it to be. It's usually like a line or two. The test is really simple. Then we have commands. All of our stuff falls under a query or a command. If anybody has anything else that is not a query or a command that they're doing in their software, please show me because I would love to see what this other thing is. I spent some time trying to think about this and I can't come up with anything. So a command. A command is where you're telling that server to do something. And a lot of times it will change some state inside that server. So you tell it to do something and you assert a public side effect to that. So in our case, I set the gain to outdoor. It was indoor. Now when I now use my query command to assert that it is set to outdoor. So I have a public change in my data. Boomerang is a name I gave it. I don't know what she calls it send to self. Basically, if you're calling anything internal to yourself, it should probably be a private method. But even if it's public, you don't need to write a test for it if it's only used internally. And then the bottom. So outgoing query. So if I ask another database or a sensor in this case for some data, I don't really need to test that. I'm actually testing the query of that result. But so that's where she just had ignore there. And I added stub. So a stub is where you fake out a response. So anytime this is called, I'm gonna return this. It's just stubbing. And I'm using the mocks library from Jose Valin and actually to mock this stuff out. And then outgoing commands. So these are important because a lot of times like we talk to an external system and it may not tell us anything. We just tell it to do something, right? You tell the sensor to change its setting to outdoor. And it just, you don't know like, hey, did it work? The only way to figure that out is to query it again. But we actually want to make sure that whenever we call that function that we really do tell the sensor in this case to change its state or do something. Even if it was like turn on this light, like he had the stop lights, you could test out. Like I sent the right message to turn on a light. And a mock is a lot like a stub except for a stub can be called or not called. It can be called 500 times. A mock is an expectation of this will be called at some point and at least this many times during this test which I'll get to an example of that. So let's go back to incoming query. I said this was simple, right? So we have an incoming query. I ask, I call it subjects is the lightning sensor. So I ask it for its gain and I get indoor. I use subject because I grew up like working a lot with RSpec and so sorry for anybody who hates RSpec but so I just, it's really like, there's not much to talk about here, right? Anybody feel like we need to beat a dead horse with this? Okay, good. So we'll go back. So next, so that was the query. That was pretty simple. Now let's go to the command. We have a serving some public side effects, right? So it's very similar. I'm gonna use the game. So here's where I do the command. I tell the sensor, hey I want you to set your gain to outdoor and then we assert that it is now outdoor. Was indoor, we saw the default last slide. Now it's outdoor. That's pretty simple. All right, so now we'll talk about the boomerang stuff. Okay, now that we're past that. Outgoing queries, so a stub. So this is using that library and the library mocks requires you to create a behavior. So I created a behavior for the board. Let me pull out the board here. So this is the actual Raspberry Pi zero board, that the Grove Pi. And what I'm doing is I'm stubbing out all calls to this board because I want to be able to run this without the hardware. It hasn't showed up. It's stuck in customs. It's out of stock, whatever reason. But I want to keep my momentum and my excitement going so I keep writing. So we're going to stub out the board and say that when we read, read is the function that you're stubbing. And here I'm saying the address. So I was talking earlier about this using I2C communication. So I2C communication is where you have a single line, well it's more than one line, but you can only talk to one device at a time and every device has an address. Most of them are hard-coded into the sensor whenever you get it. You might be able to change it by one or two by soldering some wires on there. In our case, the sensor is set up to be address three. So I'm actually in my stub saying it must be address three because I don't want my code to accidentally say address four. And then the eight is the number of bytes that I want it to return. And then the output there is that sensor output from the parser. So I'm faking that too. I'm using a generator, whoop, a generator up there at the top where, and so now I've stubbed out this method to return output. And so now we go ahead and we make our read. This read bang doesn't read anything. It's cache, it actually forces it to talk to the sensor and then I assert my results that I actually got my expectations based off of my output. All right, outgoing command. This is gonna look really similar, but not quite. And you'll see. So we have our expected gain. So the gain earlier in the system, I have it that if I tell it to set the gain, I just assume that it's set. And I changed my internal state and idea of what the sensor is to go ahead and say outdoor. Next time it reads, it'll update if it didn't. So that's why I was able to do the test earlier without the mock. This test, I want to make sure that whenever that board, when we call write, and then I have number of calls over the underscore calls, I just put there for explanation purposes. It's not required, but that's the number of times this write can be called in this test. If it's called more than that or less than that, I'll get an exception raised. Again, we're checking that the address is three and then I'm changing the gain to that expected gain from up above. That's my expectation that I want to send to my device. I have a little parser that changes that into binary and sends the whole first byte to the sensor to change its setting. Write always returns okay. This is where I was saying that we write to it and it's like, I hope that worked. And then so I try to set the gain to the expected gain and then this verify right here, just make sure that that mock was called the correct number of times. That's actually the assertion. So we're kind of asserting a side effect a little bit. All right, so somewhere over here. Hey, there's my test. Okay, so this is the really exciting part. We're gonna run some tests. And there are property tests, so they take a little time because they're testing hundreds of different tests. Crushed fingers, let's hope this passes. Yes! So I have three properties and three other tests. And they all pass. So hopefully it'll work on real hardware, right? Because all my tests pass, of course it will. Okay, so what I did was I created a little program that uses the library. And really all it is an application that starts up and this is a gen server. It's subscribed for three different events. The light, I don't know how easy that is to read. The line 10 is subscribing for a lightning event. If it detects lightning, it's gonna get a handle info. It's subscribed for a customer, or customer. Disturber detected, which is man-made disturbance. Or noise floor too high, is that what it says? And then all we do is I'm gonna output this. So somebody, I think it was Connor asked me why I didn't put a web front end on this. And it was like, Connor. I'm gonna run this code for the first time up on stage. I want this to be the lowest level of complexity possible because it's probably already not gonna work. But we'll see. So that's basically the code that we're gonna run. So when we run this demo, this is gonna be, we gotta tweet Frank one more time. And tell him either I was crazy or I'm still crazy or it failed or it passed. Because I'm sure he's waited with bated breath after all the things that he already got. So we'll go back over here. He's probably what? Probably is eating dinner. He is on the East Coast. All right, so we're gonna get out. This is the Raspberry Pi Zero. I have an SD card. I wasn't completely honest about not testing this before I got here. Okay, so I deployed it just to make sure everything started up. I didn't actually wait the 17 minutes that I need to wait for lightning. I just plugged in, saw that it started up without crashing and then unplugged it because I'm not completely crazy. So there's the Grove Pi Zero and here's our lightning sensor. And I know nobody can see this but there's a little antenna right here on the side of it. So I'm gonna go ahead and plug it in. If anybody wants to do any light reading I can drop off the documentation for them. Okay, so that's starting up. We're gonna use screen and connect to this. This is connecting over a serial port and we should see an IEX console soon. Oh, it's starting up. Hey, yeah, all right. Oh, whoa, whoa, it's going off. Man, I didn't expect it to go off that much. Whoa, now it's, this may not be good. Well, let's find out. So now we just wait 17 minutes. Maybe, nobody told me that. No, we did the math earlier, Johnny. No, 17 minutes. Hopefully we're close to that 17, probably a minute. All right, I'll be right back. Does anybody know what this is? It's called a Vandegraaff generator. So in the tube that goes from the bottom to the top is a black rubber band. In the very bottom there is a brush that touches that rubber band. And so the rubber band goes around rubbing on that brush, picking up static electricity. Just like me, when I rub my feet on the carpet right before I touch my son's ear, I'm a great father. And it goes up into the top of this ball and in the ball there's a little bitty metal piece, I'll show it to you before I start it, that catches all of the static and distributes it over that ball. The size of the ball depends on the voltage level you get. This will put out about 350,000 volts. So I'm gonna need a volunteer to touch that to make lightning. Brian, you wanna do it? Or I could use this ball here and just discharge it or you could do it with your finger. Yeah, that's what I thought. So let me go get started.  Can you feel it though, when you're around it? Yeah, that's nice, John. So I'm gonna restart this thing. Oh, that's not a good sign. Why is it got question marks? Oh, okay. I don't know what those are, it doesn't know either. All right, you ready? It says noise level too high, but we'll see. Go ahead, try to touch it. What? So I would definitely call this a success, especially if I had to tell Frank whether it worked or not, right? So if, I mean, if you guys could flood Frank, that would be awesome, but I know that some people are like, I don't wanna get on my phone, it's too hard. I don't blame you. We have phones. Everybody should be on their phones.   I probably can't bring this out tonight. So, oh, I was gonna show you guys the inside of it. Does anybody want me to open it up and show you the inside of the top of it? Just out of curiosity, okay. 15,000 volts, you can get about an inch away, but here at Denver, since it's so dry, we can get a lot further away. But down in the end of here, you'll see a little, so this is the black, because amperage killed, you're not going to vote. But I did tease my son. I was like, you know, there's 120 volts in that outlet, and there's 350,000 volts on that. I'm gonna put my face on it. I'm like, ah, ah, ah. He knows better now, he's just looked at me, he's like, whatever, go away. I have five kids, none of them cared that they thought I was getting electrocuted. They were like, mm-hmm, walk away. All right, so, is everybody done with that? All right, so, my next steps, I only supported one sensor setting here, so I want to support all of them. I have a lot more documentation to read to get that done, and just like adding a web interface to it, I didn't want to support all of the settings and then get here and really mess it up, because it was a lot easier for me to focus on one. Test with actual lightning would be awesome. Although spring's coming up, and I live in the middle of Missouri, and we have thunderstorms all the time, so I'll probably get a lot of testing in on it. And then I thought it would be really cool if I could get a website up that other people could buy these sensors and then run some program, some elixir on there, that would connect to that website, and then we could see lightning all over and get everybody's information. But I'll probably never get to that because I might actually build the car heads-up display. Here's the slides are available at that top. I don't even know if you can read that. It's pretty hard to read, and it won't zoom in. I have no idea why. Come talk to me, I can give that to you. The Grove Pi library is actually out on Hex, and this lightning sensor will be added to the Grove Pi library, and whenever I finally get it added, it'll probably be in the next week. I will put a link to where you can buy the sensor if you want to, and then there's a link to Sandy Mett's talk, which is really good talk. You should read it, but really the big thing about all of this is that I wrote this completely without hardware. I had the hardware sitting in a box, but I didn't try it on hardware. I never once plugged it in, but I was able to do this all with testing. So it's important, and I can make small changes and test them in 30 seconds, instead of having to wait 15 minutes by the time I get everything built and get it deployed to hardware and hope that I actually hooked my cables up correctly, because the sensor over here, I don't know if you notice, it's got four separate wires that I have to put in the right place, and I have messed it up, and that's really frustrating too to debug, because you're like, what did I do? And you're looking at everything and it looks right, but you messed two colors, you swapped. I'd like to thank the St. Louis Elixir Group. They let me give this talk on Monday night, and I took them all the way up to the demo point, and then I said, but I can't show you, because I'm awesome like that. So I didn't show them. We did pull that out and play with it. I just didn't plug any hardware in, and it was a good time. I'd like to thank Frank for sending me a lightning sensor and for being so confident in my abilities up here today, and Connor, Connor has helped me out a lot in my nerves questions, so bug him if you have nerves questions, and Elixir Days for having me back again. I had a really great time. This is the legal part, all the images I got on Flickr. Next time I think I'm gonna hire somebody to make my slides, because this is the worst part. So I had to display this, according to their terms of use. So there's all the images if you care. And finally, come talk to me tonight. I'm super introverted, so if you just like to listen, that's cool.  So if you have questions, or you wanna get involved with the Grove Pie Library, there are hundreds of sensors and more coming out all the time that we would love to support, and I would be willing to sit down and pair with anybody, pair remotely, whatever you wanna do. Thank you.


So in the next section, we're going to take a little deeper look at Rapture and we'll see a lot of other kinds of objects that are possible when you're building interfaces. So for one thing, as you start building up tools, you may run into a situation where you have a lot of controls and you want to maybe put things together that are related. There's a thing in Rapture called a group that you can use to group things together and in the builder you just drag a group over. It looks like that little icon up in the right-hand corner there. Just drag that over and drop it into your interface and then you can put other things inside of it. A group sort of acts like a hierarchy level in your program and you can put other things inside of it. In this case I have a group named tau and it's labeled minority carrier lifetimes and inside of it I have two numbers and it actually gets drawn on the screen with like a border around the controls. In the builder, again it would look like this, it's got the name tau, it's got a label minority carrier lifetimes and the description describes what that is. I don't know, you guys probably already know all about minority carrier lifetimes, right? No, if you don't, the description says that that's the average time that it takes for a minority carrier to recombine in semiconductor blah blah blah. Anyway, your advisor will tell you what the science is behind it and you can put in good descriptions. But once you do that, you've got a title for the group and when you mouse over the title it will pop up the tooltip. So if somebody doesn't know what that means, they can use the tooltip to figure it out. Again, the documentation is embedded right there with the tool. All right, now there's one other interesting thing that you can do in Rapture. If you create a group and then you put groups inside of it, you create a group of groups. When you do that, Rapture is thinking, oh boy, it's getting complicated. There's a lot of stuff here and what it does is it renders it to you with tabs. So because it starts to become so many nested groups it figures, all right, well this is better if I just show it to you as tabs. So you'll get two tabs. If you create a group, in this case I called it tabs, you don't have to, but there's a group here called tabs and inside of it there's a group called models and a group called ambient. And geez, inside the group models there's a group tau and all that. Anyway, when you have groups of groups, they become tabs on the interface. So you can see the group models and the group ambient, those are like two separate tabs. You can see one or the other at the time, but not the both. Now, inside the group models, I have a regular controlled boolean value for recombination and then I have a group with two numbers. And as soon as I start to mix things up, I have one control and groups with other stuff, then Rapture doesn't do tabs anymore. As soon as I start mixing controls, it splits them all out. So you can see the boolean value for recombination model and then right below it you can see the group with the two numbers in it. So the tabs only works when you have groups of groups. If you have just groups of groups, then you get tabs. Otherwise, you'll see the groups with headings. And that tends to work pretty well, most of the time when you're building stuff, so that's a good assumption. There's one other thing that's like a group, but even bigger. Sometimes the tools that you build have so many controls. Not only do you have groups of groups, but you need to have groups of groups of groups and kind of split things up. And it's easier for the user if you kind of walk them through the important stuff. So we have something called a phase in Rapture that is kind of like the wizard thing that you see on Windows sometimes. You see a panel and then it says next and you fill out those things. It says next and it kind of walks you through a series of panels. So the way you do that in Rapture is by defining a phase. In this case, I've got a phase with a string in it and I've got another phase with another string in it. So it'll show you the first phase, just that one string. And then there's a button that'll take you to the second page. And then it'll show you the second page with its one string. And then it'll take you on to the next. And at the end, the last button always says simulate, because by the time you've gone through all the phases, all that's left is to actually run the program. So if your tool is so complicated, if it's got like 100 controls in it, then you want to probably take those 100 controls and first of all break them into groups. But you might also even want to break them into phases. You might have two or three phases. One phase is all the geometry that deals with your device. The next phase is all the temperature and pressure and ambient conditions. The next phase is all the voltage that you apply to it or whatever. Things that are logically related and each phase, there should probably be at least a dozen, if not 20 parameters, right? So you want to use phases only when your tool is so complicated. It's got that many parameters to manage. If you can fit everything on one screen, that's actually the best, I mean for the user. Now one screen with maybe a dozen controls, that'd be perfect. But if you get beyond a dozen controls, you use groups. And if you get beyond that, you can use phases for really complicated tools. So anyway, so that's there. You can remember, if you get a really complicated tool, that's one way of managing it. Of course, whenever you do that with groups and phases, the groups tend to hide things from people. If you've got tabs like this, I can look at models, but not ambient. One or the other. So whenever you put things inside the tabs like that, the parameters are a little bit hidden. And when you put them into phases, especially if there's not much there, you're just torturing the user. So again, I'm saying use these things sparingly, but they really help when you have a large program. Now suppose inside my group with the drift diffusion options, I have this recombination model. Suppose I have two other numbers, but when the recombination model is off, I don't want the user to enter those numbers. They don't make sense. But when the recombination model is turned on, well then I have to have those numbers, because I need them. So when I have a recombination model active, I need those two numbers for minority carrier lifetime. And if I don't, then forget it. There's a way in rapture of enabling and disabling stuff like that, based on the value of a control. And let me show you how to do that. So inside the builder, I have this Boolean value for recombination. And in the builder, if I highlight that Boolean control, and then I go down to where the name is, I can click on it and say copy. If I click on that, instead of renaming it, up to now we've been renaming the thing, right? But if I click on that name and copy, that's like a copy-paste thing. It lets me grab that thing, grab the name of it. Remember, this is the same name that I would have used in my rapture program. I'm going to grab that name and I'm going to use it elsewhere in the builder right now. So I'm going to click there and copy the name. And then I'm going to paste it in to an enable condition over here.  In this case, the number tau n, and there's also a number tau p. Each one of those, I want to have this enable condition. What this says is when this control is turned on, this number is active.  So that's the simplest thing that I can do. When the Boolean value is on, this number is enabled. When the Boolean value is off, the number is disabled. And I do that for this number and I do it for the other number too, tau n and tau p. I have two numbers, each one of them has to be enabled properly, right? All right, just to build on that a little bit. Suppose I have a tight binding energy, 2.99 ev. And when I'm 2.99 or below, I don't need the next number. But if I'm at 3.0 or above, then I do need the number. Slightly different, right?  It's more of a numeric value. When I'm at a small value, I don't get the number. But when I have a higher value, reached a certain threshold, then I have something called a high energy lifetime or something I have to include. So how do I do that? Again, there's an enable condition. But this time, the enable condition is not just a Boolean value. It's not just true or false. It's a little more complicated. I write it this way. Basically, I go to the thing that I'm looking at the tight binding energy. And so I grab the name of that tight binding energy. Input.negf.tbe, that's the name of the tight binding energy. If I add colon EV under the end of it, it'll take the value of that thing and convert it to electron volts and drop the units. That lets me take a string like 200 milli-electron volts and convert it to a number like 0.2 in electron volts. So this will give me a number value and then I just look at greater than or equal to three. So if I've got that number greater than or equal to three, then it's enabled, otherwise it's disabled. See these enable conditions that I showed you a second ago. They can be just a simple Boolean thing or they could be an expression. Like this is an expression, get me a number and when it's greater than or equal to three, then this thing's enabled. And when it's not, it's not. So you can write any arbitrary expression there using the value of one rapture component to control another one. You always take the one that has the controlling value and you put it on the enable condition of the other one that you want to control. All right, let me show you another example of that. Again, suppose that I have something called like a choice thing with a drop down list. And when I choose drift diffusion, I want to have those parameters. And when I choose Boltzmann transport equation, I want to have these parameters. And when I choose neg f, I want these parameters. I actually have three different sets of parameters, depending on the model that you choose. And I want to make sure that when you choose one model, you get one set of parameters. But if you choose a different model, you actually get a different set of parameters. The way I do that in the program is I make three groups for the parameters. And when this model is enabled, when the model drift diffusion is on, I enable its group and I disable the other two groups. If you enable a group, it'll show its controls. If you disable a group, the controls will completely disappear. They actually don't just gray out, they disappear off the screen. So this idea of enable and disable is a way of showing controls and hiding controls too. You can enable a whole group and the whole group pops up. And you can disable the group and the whole group will disappear. So the way I do that is for the first group, I look at the value of the choice, input.choice parentheses model. That's the model thing that you're seeing at the top of each one of the three of these, so this is the rapture name for it. And if I look at that model and I say input.choice model equals DD, then go ahead and enable that panel. The next one says, look at the choice and if it's BTE, then enable that panel. And the next one says if the model is neg F, then enable that panel. And sort of, there's some mathematical corollary, I'm sure, that says, when the model is DD, the top one will be true but the other two will be false, right? So it'll be enabled and disabled and disabled. But on the other hand, if I had the choice model was neg F, then it would be disabled, disabled and enabled, right? Because it would be false, false, true. So that way, there's only one that's active at a time. Whatever model I choose using the drop down drift diffusion BTE or neg F, whichever one I choose, it'll pop up that panel of controls and the others will disappear. So the enable thing is really good.  And I can do that with a simple Boolean value. I can do that with a numeric value. Or you can actually show or hide whole groups of controls by enabling and disabling groups. So it's a very powerful thing. On a different note, literally, different note. There's one more thing you can put into your tool for documentation. There's a Rapture object that's called a note. It's not really an input, it's not really an output. But it's an element that's there to help you with documentation. What I found was people would start building Rapture interfaces and they'd put in strings and images that weren't inputs, but they just described stuff.  And then your program would actually receive that as an input, but it would ignore it, right? So I thought, well heck with that, we can do better than that. You can actually have a note object that actually has HTML text that describes what's going on in your interface. So for example, you can see in the builder here I've got a note and then a number and an integer. And over on the right hand side you can see some HTML documentation and then a number and an integer, right? So the note is a little HTML area where you can show images and links and text and everything you need to describe your tool. That area right there is the note. And when you're setting it inside the builder, there's a little button where you can choose an HTML file. So just pretend it's the 1990s and you can create a little HTML file by hand. Any sort of ordinary HTML file with an HTML tag and a body, sort of like the way people used to do it back in the 1990s. But you can also include images and it actually does understand such style sheets. It doesn't understand flash, it doesn't understand Java, all the fancy stuff on the web. It doesn't do JavaScript either. So you gotta keep your HTML pages kind of plain. But if you have HTML pages, you can plug them in right there. And you can test them with your browser to make sure they look right. So this is what typically you do. Inside, if this is where my tool is, I've got my tool.xml and I've got my script for my tool. It's a good idea to make a directory called docs, d-o-c-s. Rapture will look for a directory called docs in the same area where your tool.xml is. And it will assume that all your note information is in the docs directory. So in this docs directory, I can have an HTML file and I can also have images and all that stuff. And then your HTML file can reference the by size.jif image and it's all together. So when you're building a tool, make a docs directory, same place you have your tool.xml and put all your HTML and your images there. And then just choose it in the loader, the HTML file. And you're off and running, there's your docs. That might be useful. It's like a real useful thing for a lab assignment, just saying. Everybody's like, wait a minute, what? Back up, what? The note, I give you the note. This is what it would look like, by the way, if you're not used to writing HTML, if you need a little HTML primer. Back in the 90s, this is how people made webpages. So it starts out with an HTML tag and then a body tag and then some stuff and then slash body and slash HTML. And inside the P's or paragraph tags, UL is an unordered list, A is a link in the web. You notice you can actually embed links in this and you can embed links to other websites in your tool. So for example, in this documentation, I say, hey, here's a bunch of cool sites that you should check out. This is the theory for this tool or something. We can actually reference like nano hub.org resources or we can reference google.com or whatever web URL you want to stick in here. You can do that and when the user clicks on the link, it'll actually pop a web page for them. So feel free to use web links outside even, nano hub. You can also see the image, right at the top, I've got the IMG tag. The IMG tag with SRC equals bysize.gif. That's how you include an image in your HTML. And that was that image I showed you just a second ago sitting in my docs directory. So that's how you write HTML, that's a good example. And that's my bysize.html file that looks like the thing at the top. And the links are active. So when a user is clicking the link, it'll pop up the tool page just like that, which is really great. All right, now the last thing I wanted to, we started already kind of getting to the documentation on the website. And the more you do with Rapture, the more you'll find you need that documentation. There are things that you can do in Rapture that aren't in the builder yet. We've been working on the builder, there's a lot of stuff in Rapture. It's not feature complete yet, it's close but not quite there. So for example, in the builder, if I look at a number object, you can see lots of things. You can see the enable condition, the default value, the units of measurement, and all that. But if you look in the documentation for number, there's even more that you can do, that's not in the builder. For example, numbers have something that you can put in called a preset. If you write this in XML, if you use the builder, generate a tool.xml file and then edit it by hand, you can actually add something like this to the XML. You can add a preset, value 300k, preset value 77k. And what that does is gives you a little drop down menu. The number, not only is an entry widget but it'll have a little arrow next to it with a drop down. And it'll drop down these two choices. That's a really useful thing because sometimes people don't know what good temperatures are and it turns out that experimentalists like to work at 4.2 kelvin, that's like liquid helium temperature, at 77 kelvin, that's liquid nitrogen temperature, and also at 300 kelvin because that's room temperature. And if you weren't an experimentalist, you might not know that. But it's really good as a tool builder to build those things into your tool and that way it makes it easy for people. They just think, yeah, I want to work at liquid nitrogen. What's that temperature? I forget. Yeah, it's 77, right there. So if you build something in the builder, you'll get close to it and with the tool.xml, you can then go into your tool.xml and edit it. And you can add stuff in. Just like we were doing with the driver file when we added in the current values, you can edit the tool.xml and add presets, for example. And that'll add new behaviors. There's other Easter eggs like that that you'll find, lots of other things in Rapture. If you read the documentation, there's extra stuff that you can do in the XML. Okay, so the builder builds your tool.xml and then you can go in and add stuff like that and save it. Now, the only bad thing is that if you reload this file into the builder, the builder will scrape out all the stuff it doesn't understand and throw it away.  Sorry about that, I don't know what else to do about it. The builder sort of throws away stuff that it doesn't like. And when it goes to write it back out, all that stuff that you added by hand will be gone. So once you can use the builder to get so far, if you start adding stuff by hand, then you might as well just keep adding stuff by hand in the tool.xml. So just be forewarned, I guess. This is what it looks like, by the way. If I add those two presets, when I get this temperature control, I'll have a little drop down and the drop down will have my preset values on it, which is kind of nice. On the other hand, you might say, that's not worth it for me, because I don't care that much about that feature compared to losing the builder when I start using it. So there are a few other things that you'll find if you poke around in Rapture. There's also an input called the periodic element. And I think it's in the builder now. So we can drag it over, right? That's good, because it didn't used to be. So now you can drag over this periodic element in the builder. And again, this is what it looks like in the XML. It shows you a periodic table, and it's really good for chemistry applications. If you're asking somebody to select an element like oxygen, or helium, or something like that, you can give them a periodic table and they can click and choose the elements out of the periodic table. You may, in some cases, with chemistry applications like this, you don't want to let people select anything. You only want to select three, five compounds or something like that. Certain columns of the periodic table. And so there's all these different kinds over on the right-hand side, noble gas and transition metals and all of that. So you can activate certain sections of the periodic table, or you can deactivate certain sections of the periodic table. You can say the user can select anything except a transition metal when they're choosing. So that periodic element controls just a nice way of choosing elements. And you can look into the documentation a little bit more, look at what the interactive and the active does and the default. Turns out in the return, has a thing called return value, too, where you can say what you want to get. Do you want to get the symbol? Do you want to get the number, the name, the atomic weight, everything? So you can sort of, when the user chooses an element like helium, you can decide what your program is going to get. Is it going to get the name helium? Is it going to get the atomic number or the weight? So you can choose any of that with the periodic table, too. All right, it's kind of a potpourri grab bag of all weird features. And now I've got a lab assignment for you, which is also a potpourri grab bag of weird features. I wanted you to try a few of those things out in your Spirograph program. You remember the Spirograph program from yesterday? Maybe you still have it sitting around. If not, let me know, we could probably get you a solution. But what I wanted you to do is add a few things into your Spirograph program. If you remember from yesterday, the Spirograph program that we had only had three values. You choose three numbers and you get a Spirograph, right? We're going to add a few things on. First of all, put a note right up at the top and put whatever you want in the note. What I did was I put a note with some HTML, excuse me, an image. The image has an equation, so when I wanted the equation, I used an image for that. I put in some links. You remember there's that link to the article about Spirograph, so I put that in. So give it a try. Try to put a note in your Spirograph, build the HTML page, maybe some images in there, that kind of thing. That's step one. When you're done with that, try putting in groups. Make yourself a group model parameters and a group comments. And a group, usually like a group of groups thing. So you'll get tabs. There'll be a tab for model parameters and a tab for comments. You can try that much out. The comments tab should look like this. It should have a Boolean value with the string. So all your comment controls are inside the comments tab and all your model parameters and the models tab. So do that and get that much working. And then the very last thing, if you're looking for something to do, play with the enable and disable. Make it so that when you turn on comments, this is enabled. And when you turn off comments, the string is disabled. At least on the GUI, I don't know. Your program probably will ignore the comments. It doesn't have to do anything with them. If you're really ambitious, I guess you could take the input comments and produce an output string that has the comments too, if you want to. Yeah, I guess I said that. So when comments are enabled, produce an output string with comments. If you're looking for something to do, you can do that. So take it one step at a time. Start with the note, get that much working in your interface, add the groups, and get that much working in your interface. And then finally, play with the enable and disable within the comments tab. See if you can enable and disable the string. Okay, here's my solution for the lab assignment. We wanted to stick a note in the top. We wanted to create a couple of groups and we wanted to mess with enable and disable. So let me show you what I came up with. Oops, wrong one. Ah, this looks better. All right, so I've got this, I took the tool.xml and the Spyro program from the previous lab assignment. And I made a new directory called docs, makedir docs. And then I put some stuff in it. All right, so I've got two things in there. I've got an overview.html and a Spyro-EQNS.png. And if you're, this is just some simple HTML text. It's got an HTML and a slash HTML and a body and a slash body and some stuff in between. You can look up web tutorials about HTML and it'll show you simple stuff like this. Nothing real super fancy. I know one or two people tried grabbing a web page, like from Amazon.com or whatever, stuffing it in here. Doesn't work so great because modern web pages have so much stuff. First of all, they need this and that, JavaScript from this and that and they need all these different style sheets and things like that.  You gotta keep the HTML here really simple. Think 1990s HTML, but as you're developing that, you can use a web browser to kind of test it. If you have like Firefox or something and you give it the file, you can bring up Firefox or some web browser and you can test and see what that looks like. And then you can edit your HTML and then reload it here and edit it and reload it. So web browser is an easy way of kind of checking to see what it's ultimately going to look like in your tool. All right, so I've got my docs there. So then in my builder, let me open up my solution. In the builder, I added a note and the note is right here or you can find it under the documentation tab. Just kind of drag and drop that over.  Here I have it set to that overview.html. I can just go in here and choose overview. And that sets the contents of that note. So that's all there is to it in terms of adding the note. And then when I go to preview it, there's my note. And if I change the HTML, it'll show me different text and so forth. So the other thing I wanted to do was add the groups. So in order to add the groups, I go over here and there's a group thing right here. And I just dragged and dropped that over. And you notice you can kind of rearrange things. If I want to grab a number and move it around up here or move the number back into there, move it up to the top, oops. You can rearrange and kind of drag things around. So if you have an older tool that you built with the builder with some old controls, you can move it all around. One thing though to be careful about as I'm moving this number around, if I move the number way up to the top and I look at its name, the name is really simple. The name here is input dot number parentheses one. But if I take that number and I drop it down inside of a group, the name changes. Now the name is input dot group tabs dot group model dot number one. And that's important for two reasons. One reason is back in your program, in your skeleton program, we use these names to get the values. And so you have to fix up your program to look for that number, not the old number, the new number, right? Different path. So when you move things around inside your program, be careful, those paths change. And you have to change your main program to use those names. Of course, if you regenerate the skeleton, like I usually do, if I go and save as and I save this out to a different tool dot XML and I choose another skeleton program, maybe like main two or something. If I do that and do save, then it'll regenerate a new skeleton with all the new names. And then maybe I can take my old code and kind of plunk it in the new skeleton and everything's all fixed up. So just be careful of that when you're moving things around, the names change. The other thing I did, inside the group comments, I added the boolean value and also the string. And then for the string, I wanted to set the enable condition. And the easy way of doing that is to say, all right, I want this boolean value to do the enabling. And so I grab its name and copy. And then I go over to the string and I set the enable statement to that, paste, paste. So that sets in enable condition. When the boolean control is on, then the string will be on. When the boolean control is off, then the string will be off. If I want to do the opposite, just like in C language, I can say exclamation point. The exclamation point at the beginning is like the logical not operator. So that would flip the control. I can also do things like, say, equal, equal, and then give it a string like, oops, like yes. You can do that too. I always forget though whether it's yes or no or on or off. And I don't know. It shouldn't matter but it does because when it evaluates it, if I'm trying to compare it to the string yes, it's got to actually be yes, yes. So if you're trying to do something like that, you may have to fuss with it a bit to get it right. But you should be able to do different things like that. The easiest thing for a boolean is just to copy the name in. All right, that's about it. In terms of saving, which I'm not going to save any of that, but that's about it. And then in my program, Spyro, again, if I edited my old program, I should be careful to change these names or maybe I generated a new skeleton and I stuck my code in, either way. But the names are different than they used to be because now it's not just input.number n1, it's input.grouptabs.groupmodel and all that. So I had to be careful to change the name there. I had to be careful to change the name there and the name there. Everything else is pretty much the same. I do my t and my z, just like I did before. And I save the values back, just like I did before. There's one other thing I added for the comments. I checked that boolean value to see if it's turned on. And if comments are enabled, then I went ahead and I put this stuff out. This is interesting. The way I did it right here, I'm actually, I'm putting two strings. I'm saving out the about.label and I'm saving out the current value for that string. I'm doing both of those things. That actually creates the control out of whole clock. Let me show you. My tool.xml, if you look in the output section, I have a curve in the output section, and that's it. There's nothing else there, there's no string. And when I'm executing my code and that ad statement is turned on, this ad statement actually creates a string as if I had created it in the builder. It does that by doing two things. Number one, it creates a label for the string. Rapture has to know what to call it. So that's what the output.string, parentheses, info.about.label, that gives it a label. And then the output.string, info current, gives it some text, okay? So that'll actually create it. Let me show you what it looks like then. To run this, I'm going to copy my tool.xml to a driver.xml. I'm going to edit the driver. I'm going to go in all the places where there's a default value. I'm going to make it a current value. You guys are used to this by now. I do this when I want to have a test case that I can run by hand. Okay, so I've got those three values. I'm also going to set values for the boolean, boolean value. I'll set it to yes, and I'll give it a string too. I'll set the string current value to testing, okay? So that's my driver file. I can run octave, I can set infile to the driver file, and I can run that main program. Oops, what did I call it? I called it Spyro. Oops, what did I call it? Spyro.m, oops, I-R-O, there, okay. So I ran it by hand now, and I can look in the run.xml, and you can see a couple of things. First of all, there's all the numbers. That's great. Wow, there's a lot of numbers. I forgot, I guess there's a thousand numbers, right? Maybe I should start at the top. Okay, so here's the curve in the output section. Here's the curve, and it now has a bunch of values, right? And if we go down, down, down, we can get to the end. Here's the end of the curve. And here's this string info. That didn't exist in my original tool.xml. I created it on the fly inside my program. My ad statement did two things. It created a string named info, and it said it's about label. And it created the current value testing. So that chunk right there of XML, that appeared because of these two statements. When you do RPLibputString, when you put a string in the output section, it'll look for, in the output section, it'll look for a string named info in this case. If it finds it, it'll change it. If it doesn't find it, it actually creates it. So you can dynamically create new outputs in your program, and that's what I'm doing here. This will dynamically create a string with the ID info, and it will set the about label to comments, just like the builder would have, if I would have created that string in the builder. And then also, it sets its current value to the text that I wanted for the comments. So I was expecting a curve to come out of this program. When the comments are enabled, I actually get a curve and a string. And you can see that if I do my rapture-load on that run file. You can see the results, right? This is my interface. You can see the curve, but you can also see the string. So I actually have two outputs there that I can flip back and forth between. All right, and going back to my interface now, seems like all the parts are there. If I just run rapture, I can change the model parameters and tie new cases, and I can put comments on or off. My enable is working properly because you can see the comments turning on and off and simulate, and now I get a spirograph and some comments. Questions on that? That business at the end that I showed you about creating new things in your program, we'll hit that a few more times. You'll see that coming up more. So if it didn't quite sink in yet, it will.