 Well, it's that time of the week again. It's time for chitchat across the pond. This is episode number 771 for June 24th 2023, and I'm your host Allison Sheridan This week our guest is Bartmuse shots back with another installment of programming by stealth number 152. How you doing today Bart? I'm doing mostly okay. I'm mildly cranky at the universe because a piece of glass made my day unpleasant. Oh On the bike wheel bike tire Yeah, and it turns out that I have three spare tires for the mountain bike and zero spare tires for the road bike I thought I had two and one I'm not have what I thought so you carry your bike home. I Was very close to home. So I sort of limped home on it, but it's ruined like I thought I'll just fix this puncture Oh, no. Oh, no So Amazon Prime is gonna get one to me as quick as possible Oh, I bet Steve said something funny when he heard you had a piece of glass. He goes. Oh, man, don't you wish you did? You know why because I have a slow leak that they can't find Yeah, yeah, if it just had a big gouge in it, but they can't figure out what's wrong with it But it just we were gone for five days and it lost five psi. So I can't keep pumping it up every day No, and yeah, they're hard to pump up test the tires some of our garages aren't strong enough I've discovered we've got just a we got a little home unit. It's real easy. It's just plug it in. It's just a regular tire Yeah, it takes as much as a heavier vehicle tire does maybe all your maybe all your pumps are stronger than ours But here I have to be careful. This I'm holding my hand up It's like the size of a loaf of bread my pump that I use at my house. I plug it in the wall And it does it. It's not real quick. The Tesla needs 45 psi and a lot of our stuff only goes to 30 Really? I'm really a spotter cars going to that. Yeah, I guess your little bitty adorable cars Well, anyway, we should probably get started because we have what I think is gonna be a challenging lesson I have pre-read the notes and I have lots of questions. So we better dig in Yeah, and we it's been a month. So that isn't helping things So we we are in the stage of our story where we're very close to being done Which means we've basically covered an entire language almost I mean We are 90% through and we've done a lot more bash than I thought we would because it turns out the community love it I really got into it. Everyone's kind of got into it even though it's such a strange language. So this installment or this challenge gave us a lot of room to reuse Pieces we've learned and to assemble them in perhaps slightly different ways So the same Lego bricks, but we've built a different house if you'll excuse the analogy and I don't know how long it's going to take us to describe this and how many questions you have but you're you're in your most important role here you are standing in for the audience and Given where we are in the series now is the perfect time to stop and ask the questions Okay, so before you start I want the audience to know what I told you before we started a lot of these commands look familiar But I so I know you've told me them before but I feel like they're so fuzzy I dreamt them so I may stop you more on things It's like you're not allowed to say Allison I told you that because I know you told me these things. I'm sure let's take that as a given Apart from the point where I say and this is new Everyone understand that these are our old friends or Lego bricks, but there's just a couple things going on here so I've thrown a lot of bricks at you in the last couple of installments and I don't know of very many languages that are more dense than shelf Well, yeah, I'm looking at the commands going yet percent D. I knew what that was a couple of weeks ago I've gone back and read and brought up a cheat sheet while we're talking But it's so it's so concise that there's there's not a lot of clues to what it is a Lot of document reading right when I'm running shell script for real in the real world. I have the docks open a lot Because I have to remind myself what the different operators are a lot because Like I say it's dense and it's like, you know percent Percent single quote D. What was that again? I'm gonna find that out single quote. I said they're going put that and also and I went it's a comma. Yay I got one the anti gravity comma as I try to make it funny. Yeah, exactly But you you need to go read and that's not a failing right the skill of being a software developer is to not feel bad about reading The docks and hopefully to get to the point where you can get to the right bit of the docks more quickly. I Don't remember and you're not allowed to tell me you told me Unless I asked you directly. Did you tell us where the docks are other than just man? I I'm pretty sure I linked to them Um, I generally stick bash documentation into Google. It's a horrible site because it looks like it dates back to the age of bash It it's barely formatted white black text and a white background With no sidebars or nothing. It is the most primitive looking thing you've ever seen. You're like, is this the official documentation? Oh So it is Okay, well as long as it's a little language that's dense not me Right and I like I say it is normal to need to go read the docks That is that is not a bug that is that is how this language works So our challenge a month ago, right? That also doesn't help our challenge a month ago Was to write a script that would print out a pretty version of the multiplication table So we had done multiplication tables when we learned about looping and the point of the exercise then was to learn About loops because they were new to us Whereas now the point of the exercise was to practice string formatting using print f and So this is a bit pretty right? We've done just print the numbers This is a bit pretty and I kind of went to town on pretty in my sample solution and I use it as an opportunity to try to Bring in lots of pieces from the past So I sort of intentionally went this is a Bell's whistles and maybe even a cherry solution Okay So what you needed to do was to write a script that would take one required argument, which was a number So if it was three, then you wanted the three times tables if it was a four you wanted the four times tables By default that you'd go from one to ten like you would have done in school But you could optionally give it a minus s for start or a minus e for end Although I believe I very foolishly gave them terrible names in the actual challenge minus lowercase m and minus uppercase m And I literally start to show us by saying I was an idiot So my sample solution uses start and end. I actually Didn't care which they which they gave me whether they were men or max in my solution But in lowercase m was men and uppercase m was max you wanted start and end and that's fine But it does mean that the solution won't look anything. It is does have different things in it than ours But I think we can I think we can run with that Yeah, and like I say it was after I started writing the code I realized that I don't actually care whether we count up or count down and therefore men and max are silly for a start and end They're actually what we're doing and your solution test to see whether they gave me the first whether the Minimum was less than the maximum and if it wasn't I just did it in the other order Well, it's another way to do it is yeah flip them. Yeah, this is that how USB see works It basically it checks the wires and sees on my plugged into the other round I'll flip myself instead of the old USB a way of making you flip it There you go The other thing I yes And so we could be one to 10 by default or to the value to specified now This code took me a long time to write so that's that's another important thing to say the sample solution here Was not something I threw together in five minutes and while I was writing it I was I pulled my hair out a few times and I don't have much of a left And so one of the things I would do in the real world is Give my code a debug mode where it would tell me what it was doing under the hood And so I decided to show instead of tell So my sample solution accepts an optional flag minus D, which makes it chatty It tells you what it's doing But so as not to pollute my output. I made it chatty to standard error That way you can pipe it to different places Depending on what you want Okay, and if you don't put the minus D you don't have to see all that garbage Precisely, so basically if you know about the minus D you can see what it's doing Which is really useful when you're building up format strings and things because like I said the syntax is a bit, you know dense So you'll find the full solution in PBS 151 dash challenge solution that sh in the installment zip and it's a long one Now I have I pasted it all into the show notes because I figured that way people don't have to download the zip file to see everything but ultimately big picture wise We start by making sure you've given the correct arguments using the Get ops that we've now encountered a few times and so we basically would do our little dance to make sure that They've given numbers and then we save the values for use later I'm saving the number The thing we want to do the table for as n because I just couldn't think of a better name for a number and The end times tables. I was very low in imagination Can I ask you a dumb question? No, you're in your code. Do you do you assign the the value that they're gonna multiply? To n I literally couldn't find it Okay, so you see we have a while get up to do and then a whole bunch of stuff and then we have a done and and none of them are n Correct because the n is not minus n. It's just the first normal argument So okay after we're done with the optional ones. We do that shift copy paste thingy to make them Therefore what's left is dollar one So then we say n becomes equal to dollar one Okay, gotcha. I see it now. Okay And so at that point at that point I was already getting things wrong So at that point I put in my first debug statement So what I chose to do was make a variable named to do debug so that my code would read nicer So if minus n do debug then my various debug statements So I'm gonna do one of my first I'm sure you've told me this but so it says if and then it's got the double brackets This is gonna be the test. It says minus n space dollar do debug. So dollar do debug is gonna be a Function It's a variable. So variable it has a value of one if they gave it to us correct Okay, but what is minus n got to do with that? And so is the the number they're giving us No minus a okay, so dollar n is our variable We're now inside square bracket universe, right? We're in the test so square bracket square bracket means we're doing a test and all of the Right square bracket square bracket means test. So minus eq for equals Minus gt for greater than What about getting there? I'm getting there getting there So minus z is for empty string and the opposite of minus z is minus n for not empty string So it was one of the ones that I made that I basically said you're going to hate this one Because it's not obvious. So minus n is not empty string So if so of all the variables you could have chosen for the input number to be n and then use n there And I I mentioned this about before you use n two more times below where it doesn't mean the same thing So there's four different the letter n means four different things in this code Maybe back to the fact that the language is dense But I don't think I would pick n. I would not pick n because n has four meanings here I Okay, my mind dollar n is a thing. I get the variable n is dollar n and In other places, it's whatever it is. So minus n is a test. So right minus minus anything is a test I guess is sort of the demonic When you went to you tell me when the n is the number and then I'll learn all the other things It means as we go because I know use it three two more times. Okay. I'm curious. Where else I use it? I'm not Well, we'll keep I don't remember where but there are 150 lines of code here. So so this so this says if if If do debug is not empty in other words, if it's one Then we're going to do this set of code Yes, okay, which is just print out now I prefix my debug statements with debug and all caps and a colon so that when I'm looking at the output I can easily tell when I'm just telling myself things versus when I'm you know when it's part of the program You you might like this in visual studio code There's a plugin called to do tree and you can have it format different kinds of things you write in different ways So I have one that says debug and it highlights it in like bright yellow So when I'm done with my code and I've got everything working I can find them all Yeah, oh that is yeah, it's actually really nice in this case you want them in there, but okay, so now the do debug is so we say We're printing out strings inside double quotation marks, which makes them in interpolated strings So in that case, we're printing out the letters d e b u g colon space and space space space equal sign dollar n Okay, that is the letter n Yeah Okay, okay, but I'm showing the value of my variable So I give the name of the variable equals the value of the variable I mean the point of the print statement is to show the value of n if I name that anything would end I would it would make the world's worst debug statement if I'm telling myself n has this value I need to say n equals dollar n Yeah, you know that I I'm just thinking when when teaching somebody who doesn't know what all these things mean n was was a choice that makes things harder But I see what it means because then you say echo debug start equals dollar start and equals dollar end and then you Do the greater than ampersand to which I think is send it to standard error No standard out which one error okay, so Before the greater than sign is is the default output so that's standard out and then we are saying make standard out go to Number two, which is standard error. So we're redirecting So echo would normally go to standard out and we're saying no no no don't go to standard out go to standard error instead Got it. Okay. I'm with you. Okay, so we make sure everyone has given us everything We want right we're quite a few lines of code in and so far all we have done is ask for all of the different arguments We are all of the different variables for everyone saved them for ourselves into three variables dollar end dollar start and dollar end And if they've given us garbage, we have been cranky at them And it is generally speaking good practice if your script can be cranky for multiple reasons to use different exit codes for each reason Because you have two hundred and fifty five of them at your disposal. So that gives you two hundred and fifty five different ways To be cranky So it actually can be useful the one thing is you should write a comment at the top of your script that actually says What your exit codes mean? So you'll find that they're very very tough I have listed my two exit codes exit code one is for missing a required argument or using an unsupported flag or optional argument Error code two means you gave me the right arguments, but they have silly values So I needed one argument you gave me one, but you gave me pancakes and really I wanted a number and Yes, you gave me a minus e, but you gave me wobbly and what I actually wanted was a number All right, so that's the difference in one and two and So you'll see in my various bits of code I say exit one or exit two depending on why I'm cranky at the user Right okay And let me ask you a procedural question should I I'm scrolling up and down and up and down right now Am I supposed to be down where you're explaining it in text or am I supposed to be looking at the raw code? I've decided I'm just going to walk through that I'm walking through the raw code because I say the same things Okay, so I Because I think we should talk about the bigger structure So at this stage of the code we have we have just we have basically gotten our input We now have three variables all of that was to make sure we absolutely positively definitely have three numbers So then it's about starting to make our pretty strings And I'm trying to print My table out so that it's always the same width and I have framed it with the ascii characters for a table Because if people can remember to the days when there was no gooey You would have these really pretty menus with perfect little frames around them and stuff and that was all done with ascii characters That are not yeah, they're not the pipe symbol. They're a little bit taller. They touch the very very top of the character You can still get to them if you go into the bios on windows, I think You should see what exactly what you're doing. Yes. Yes. Yeah, that's exactly it And the macOS 10 character viewer will show them to you. Um, and so I basically went in and I found the ones for top corner The four corners horizontal and vertical and stuck them in my basically stuck them in my clipboard Um, and then I use them in my format string. So my table gets printed out with this very pretty ascii table around it Um, but if you're going to print a pretty table It's really important that every row is always printed out the right length because otherwise your table the illusion breaks immediately If one of your rows is the wrong length So again, we're talking about making things pretty So we actually have to calculate the biggest possible width of each piece So we're printing a table of you know our number multiplied by the one in the sequence equals a value So there's actually three columns there that could be different widths depending on whether you call the script with the three times tables That are three thousand times tables right And the fact that we have thousand separators because we're now pretty printing strings using printf It means that we can't just say if it's a thousand is three y it's four wide if it's a hundred It's three wide because the commas and stuff so I thought about trying to figure out an algorithm And then I went no I am going to run each of my numbers through printf And then through word counter minus c for character and just ask it how long they are And then whichever the longest one gets saved So I have a variable called max m length for the maximum length of the multiplier and max p length for the maximum length of the product And I have a loop that goes through all of my numbers And it just says if the current one is longer than what I thought was the longest before Update the longest before and at the end of the loop My max will be correct So I think I just figured out another confusion. I had reading the code the product is the answer 73 equals 21 21 is the product yes The multiplier is what changes so okay Okay, but you never ask for the in well, we'll get to it in the code But you never ask for the length of the or store the length of the number that was put in there that I could find Um, I didn't see it in the challenge It doesn't change it must count it somewhere then I do there is a little one liner, but it's yes actually here So n len equals the character length for the number All right, so it's the very first one I do calculate the maximum length of each column when nicely formatted n len becomes equal to Okay, so n len is the length of that I'm going to do something very mean allison. So remember I said everything apart from one thing is not new The one thing Wait, I'll have too many negatives in that sentence haven't I one thing is new One thing. Yeah. Oh, yeah. Thank you. There's one thing new. It is a command which is simultaneously Trivially simple and yet the most difficult thing to explain that makes most people's heads explode And I don't understand how it can be simultaneously simple and confusing But it absolutely is and I was in that boat. It took me years to not run away from it I've ran away from it for years. It's actually really powerful and really useful It's the command x are we are going to learn about it In detail for now I'm going to say stick your pin in that line of code because that line of code Is actually illustrative What I can tell you for the for the listeners is the line of code that calculates how long the the length of the variables Yes, now The vast majority of it is the pieces are all are, you know, you have a print f percent d with the single quote, which we now know is the anti-gravity comma So we're saying we want to print a d a a whole number with a thousand separator And then we pass it dollar n So dollar n will get printed with a comma separator We pipe that to wc minus c so wc is the word count command and minus c says give me the character count And if we stop listening right there, we're fine Yes, we should know what you just said The the comment tells you the important piece the actual length of the number in characters is stored in n len Oh, we're in formatted. So because you've put the the anti-gravity comma in there Correct exactly. So if you wanted to do the three thousand times tables, it will correctly say that it is Five characters long, okay, which is one more than you might have thought And so there we just assume we just make a guess max m len one max p len one Right, they're obviously not gonna say again max m len and max p len Again, so the maximum length of the multiplier. So we have our three times tables It would be three times one So then one is the multiplier three times two then two is the multiplier three times three three is the multiplier okay Because that changes right and every row on your table that one changes and so does the answer So those two have to be calculated Therefore we have to have so max p len is the length of the product the max length of any product in the table In the table. Yeah, and and we're gonna we're gonna define them as one not really assume We're gonna define them as one. Yeah, and then we're starting. Yes. It's coming. Okay. Yeah And so then we have a for loop so a good example of a typical shell script for loop for m in And then so that m is not minimum. That's not the minimum. We were What would be in our code? It's what we're looking over the multiplier We're looping over the multiplier here, right? So we're going to go from three times one Then three times two then three times three. So that m is indeed the multiplier Okay, but that's not the No, it is the multiplier. That's not over every possible defined Okay, this is a new variable. We're defining here for m right because we we got to go through them from the start to the end So we're saying sec is the sequence command dollar start dollar end So we are going to so m is going to go from the start to the end one by one Okay, it's time to the loop. It's going so we're simulating the table, but we're not going to print anything So we're effectively going through our table in stealth All right, we're going from start to finish in stealth and each time we're calculating the length So m line becomes equal to print f with its upside down comma Pipe it to word count minus c and then hocus pocus and outcomes the length stored in m line And then we have to decide is what we got now Bigger than our previous biggest Okay And so one of the things we learned early on that I wanted I intentionally did this to reinforce old knowledge is You can use the ampersand ampersand which is the and statement to work as a really quick if Because remember I said bashed as a lazy evaluation sure Okay, so with lazy sure, I remember is what I mean. I believe you okay, well Do you want me to explain lazy evaluation or not? I want you to explain this line. And if you need to explain lazy evaluation, then yes Okay, so the ampers for something to be For the final result of an and to be true Both sides have to be true Okay, as right as it always is. Yeah So if the first side of the and is false Then lazy evaluation says don't execute the second side Okay Which is why it works like an if because if the condition m line is Minus gt greater than Max m line So if the length we've just calculated is greater than the maximum length Only when that's true Does the second statement happen? Okay, I had forgotten that And then the second statement is now take our max uh, uh, our maximum length of the Multiplier of the multi of the multiplier We're just doing the multiplier right now the maximum length of the multiplier update it with what you just finished calculating m line Precisely the current value for the length of the multiplier. Okay correct So and then we do the same trick again But we have a little bit more work to do because to get the length of the product We have to actually calculate the product right I can't get you the length of three times ten unless I do three times ten first Okay, so the first thing I do is I print dollar n star dollar m Which is Whatever our n is multiplied by m and I pipe that into our basic calculator the bc command for doing actual math Then I run it through print f with a little bit more hocus-pocus that we are absolutely going to learn about in the future And then I count its length Okay, so multiply it count make it pretty Then count its length And until it's pretty drop so you're you're calculating it Actually, you're you're calculating it you're echoing it you're sending that to the basic calculator Which will run the math and now it knows what that value is um And then you run print f to find out how long To print that value out and then you can pipe that to word count dash c which counts it With two hocus-pocus is on this line Yeah, this is this line. This line is This line teaches you everything in the world of an x-arug. This line is This line is this line will be how I teach x-arug Okay, this this line is the line. This is the line of the entire script. This is it This is the line. Okay But we're not going to talk about it yet. Okay, we will we will in after we put it in its bigger context Okay So we do the same trick again, right? We check to see whether what we found is bigger than what we had and if it is then we update our biggest Okay So now we can do the math to figure out how long is the top of my pretty table Which i'm calling the cap length because it's the cap on the table. I wasn't sure what else to call it Okay, okay. That's what you meant by that. All right so It's basically It's eight characters because of the various spaces times the maximum length of n Sorry eight plus the maximum length of the number plus the maximum Sorry eight plus the length of the number plus the maximum length of the multiplier plus the maximum length of the product Calculate that and that is the length of the Middle piece. I counted the spaces because it's So when I look at the table that you create you only have six spaces Uh, there's an extra space hiding. I think either side of the table It is right you say in your code And I went back and looked at the code and there isn't I can't account for that extra space But that's it. Well, I know that's needed because I ran it with my debug statements and Until I did it that way it was broken We'll get there. I'll point you where I'm going. I don't see it. But okay All right, good. So now we now we know the length of The cap and that's going to you care about that because that's going to tell you how many I'm going to call them dashes you're going to need and how many and two corner pieces Correct. That's it exactly So at that stage we have another debug statement to print out all of these lengths I've just calculated and that that took me a long time to get that right because that has all the x-args and stuff up there That that was really hard work to get this far in the code So now I do myself a little bit of work and I need to print I need to make my formatting string for each row in the table So we have a space followed by the character for the side of a table followed by another space followed by A placeholder for a number which we will look at in more detail in a moment followed by the space Followed by the character x because that's how we humans right multiply. We're not computers We don't use a star Followed by a space followed by a percent And then add some stuff and a d that we'll get to in a moment followed by a space the equal sign a space another placeholder a space The edge of our table a space and then our new line character so That's where we're worried You start out by saying that there's that there's a space before that first I'm going to call it a pipe, but it's not sure that vertical symbol There isn't one in the code It says s drink equals quote pipe There's no space in between and I kept looking at that going. Where is he saying there's a space? Uh Sorry, the space is after the pipe. It's before the percent. I'm sorry. I'm stepping through it here with my cursor and the shift key okay Okay, I think I think the notes below say that there's a space before that vertical line and that's where I I couldn't understand other stuff. So I spent my time counting spaces And yeah, that character actually is really wide because when you select that character So it goes blue that's really wide. So it looks like there's a space there, but there isn't you're right The space is after the table edge Okay, sorry about that um so one of the things that bash does that is confusing to people Is that if you want to concatenate two strings You don't use an operator. You just slam them together And I remember using the word slam them together many many many months ago to try to make it funny and therefore more memorable so The first thing we get here is a string from the first double quote to the second double quote is just a string And then we get the value of n len. So that is going to be a number. So let's pretend it's three Right So what we're actually getting there is percent Our upside down comma 3d So if we go back to last week if you put a number inside your percent d What you're saying is the minimum length for this number Is three and it's going to be right aligned So if you can imagine I forget which called caused it to be right aligned Doing nothing makes it right aligned. You have to go out of your way to make it go the other way Yes, so what I'm looking at is Bart is talking is Percent single quote double quote dollar n capital le and double quote d Yeah, and that does like 700 things right there. Okay, we know it's a we know it's a whole number Yes dollar n Leng is that's our variable. So that's like three We're saying and it's a quotes because we have to do it's not in quotes, right? The the quote starts f string becomes equal to quote Pipe space percent single quote end quote. That's an end quote Oh, good Wait, right Yeah, so the quote starts. Okay after the equal symbol the quote opens Okay, that quote ends before the dollar n lend Okay, and then we start another one Right, so we're smashing our strings together because that's how in any other language like java script We would have a plus in there, but bash if we put a plus in there bash will go nuts Right in bash you smash them together to stick them together. So they're like magnets So it's like we have our string from the first the double quote to the double quote and then magnetically Three or whatever the value of the variable is and then we start a new quote Which goes all the way to the next variable which is magnetically connected to it So this is bash being very very dense Yeah, I believe you Bart And and I know we've learned every atomic piece of that but boy is that nasty to look at Right, but that is what I was so excited. I thought I knew what it was doing and I don't I didn't I should say okay But when you piece it together what you end up with is percent single quote a number d which is Percent d means print me a whole number The single quote means put in the thousand separators and the number means make it so long so it does collapse down to sense But it's a dense language Yeah, right it sure is And again, this this caused me so much trouble that I threw a debug state within there to print out my bloody string Because it took me a while to get that string not to be garbage Right, so that's why there's a debug statement there. You can tell where Bart got stressed is where Bart put debug statements in Okay All right So now what we need to do is make a middle piece for the top and the bottom of our table So we're going to have a corner pieces and then we have a slab That is The door frame the top and bottom door frame of our table, right? So it's it's not a bunch of dashes. It's a bunch of dashes. That's exactly what it is But it's a different length every time so I need to build it with a loop So you're calling it a cap insert? Right because it's you call the cap mid Right because at the top of the table, it's a downward pointing end On each end and at the bottom of the table. It's the same middle piece Okay, but it's it's it's start and finish characters are the opposite of each other So I use you call the cap insert, but then you had cap mid and I thought that was something different So cap mid means cap insert Uh Yes, because this is the first time I actually build a variable. Yeah, you're right. I should have Okay, and you do yeah, I call it things on one line here with semicolons Yes, so this is again me finding an excuse to to to show things so Normally when I do loops and stuff and if statements I do something that google results and when you go to stack overflow doesn't do I space it out for Something new line do new line some stuff new line done If you go to stack overflow, you will generally see that collapsed with 4 m Whatever semicolon do at the very least And so if I don't tell you about this The more you google stuff the more you're going to think I've let you down Because the google results are going to be full of semicolons And all a semicolon means is pretend it's a new line That's it. It just tells bash treat this like it's on a new line And so that is a read your code Yeah, I can take this and just take out these semicolons and make them new lines Correct, and then you're left with A for loop that just plus equals is the dash into cap mid Okay So you're going to do that But how how long are you going to do that from one to the length of the cap? Sec one dollar kaplan Okay, I thought the cap length was just the middle piece, but you're saying it's the It's it's a little more than the length No, no, I mean we're building the middle piece, right? So it is it is the length of the middle piece So I just need to I need a string If the middle piece is 10 more than 10 Kaplan Is the length of the entire thing not just the middle piece No, no, no, it's just a middle piece. So this is just a loop to make my middle piece, right? It's I need 10 dashes Okay, and I'll put a little corner on them. It's it is literally just a loop to go from one to how many dashes I need Okay I follow you again the variable names are killing me, but uh, I'm trying to keep up. Okay Okay, so now The next step of the code says print the table So I'm going to stick my table into a variable which I have named table. Do I get points on that one? That one Okay, well, I don't know what table is yet. We'll see whether I like an empty string, right? Table becomes equal to an empty string. We'll find out what it's very able to build a table in it Is the table so the first thing we print is the top right so render top cap row So we have our brackety symbol So we're using print f So what we now this is this is very new to us, right? We're this is reinforcing last time's knowledge This is not something you've known for ages. So print f by default writes the standard out But it if you use minus v it writes to a variable And the variable will be the um Print f minus feet. Yeah, the variable comes next. So the variable here is called row So we're saying print f minus v row So render this string pretty into the variable row Then we give her to find we never defined row before now This is we're defining it now. Yes. Okay. I think I remember that. Okay. Yeah, all right So we have our string that is the pattern for print f which is open Which is a funny character for the corner of a table Percent s is a placeholder for a string Then we have the other side of the funny character for the other side of the table a new line character And then we pass it one argument which is cap mid, which is that number of dashes. We've just made a loop And that gets substituted in between squirted in for the string in between. Yes. Okay. I didn't remember that. Okay So we have now made an appropriately length top of the table And then we say table plus equals dollar row So a table has now has one row in it. It's the top of the table Okay, so then we do our loop for m in our sequence from start to end So each m is our multiplier to calculate the product Yeah Calculate the product p becomes equal to and then we use the basic calculator again to calculate dollar n star dollar m And then we need to print it into our pretty string So again print f minus v row. So again, we're saving it to dollar row Our string is the horrible string that we built in that horrible line of code We both hated with all of those percents and quotes and stuff. That's our patterns We're just using it now And we pass it has three placeholders. So we give it three values n m and p the number the multiplier and the product and they get dropped into the three percent d's So we already used the variable row And we we defined it with the print f minus v command and then we Plus equaled it into the table and now you're defining it again Is it writing over it or did it cease to exist? Is that a philosophical question? It's it's still no, I mean like you know what I mean like we're always worried about scope So does it not exist at that point? No, it's the same variable. It's stomping on it. Yeah, so effectively I'm using it as a as a carrier To get from the print f into my table Okay, I I do a lot of tabular stuff in in my uh time matter thing and uh The word row exists at least 700 times in there with different things in front of it because I keep coming up with new names But I like stomping on it. That's good. Okay. Yeah, so we're just saying I want a row sticking in the table I want a row sticking in the table. I want a row sticking in the table So we print f our row with table plus equals dollar row done, right? So that that gets us the body of our table So now that we've done all the hard work above the actual printing of the table is trivially simple code Right, we have a pattern and we give it three Substitutions great. Yeah, then we we invert our logic from the top We do the same thing again to make a bottom cap But this time we use the the other corners of the table percent s and then we send our mid cap in again And then one last time table plus equals row All right, so now we have our full table So dollar the variable table now contains everything we want And then what I said to get bonus credit was that if the output was a terminal We should put our table through the less command So that it will if we say give me the one give me the thousand times tables from one to a hundred It should give us a page that we hit the space bar. It gives us the next page We hit the space bar. It gives us the next page Like happens with commands in git If you do a git log on a repository with a lot of things it will page it for you nicely But if you pipe that same output to a file It doesn't do that. It sends everything to the file and the way it does that is by detecting Is standard out a terminal? Or is standard out anything else? Okay, so that's why we have an if statement here That's the if statements job. Are we a terminal or are we not a terminal? And so what jill told us, uh, which I then included in the show notes last time because jill is cool And jill is right jill of k. Yes. Sorry. We need to say which jill. Yeah A kent is in the uk by the way folks. Um So minus t is the test for whether or not something is a terminal And it demands to be told what stream it should go and check And so standard out is the stream one So minus t one means is standard out a terminal then We echo the table and pipe it to less Else we just echo the table Now that's pretty simple It is now less has two optional arguments two optional flags showed on the end of it because less's default behavior is annoying If you just pipe something to less that's less than a page long Less doesn't just print it out and then exit Less locks up your entire terminal Prints the thing you want at the bottom of the page and waits for you to hit q That's annoying So the minus minus quit if one screen Takes care of that problem The other thing less does is when you finish less So if you if you like the man pages use less if you go into a man page and you hit q What happens the man page you are looking at it vaporizes it vaporizes Now do you want your table to vaporize when you got to the bottom? No The minus minus no minus in it stops the vaporizing Yeah interesting can you man You can man less that is how I know dash in it Well when you man less and you start looking for basically start reading through how to make it not suck I basically read the whole man page for less I mean, can you do the can you make the man pages be minus minus no dash in it? I don't know and do you know how you'd find out man, man No, man, man because man has a man page I like it. I like it. So There's an odd side effect I discovered from what you did there and I'm wondering whether you didn't notice it I gave it a big number. I I told it to go from three to minus seventeen And then I made my my terminal happened to be very short in height And it drew the table three times and it wrote colon dot dot dot skipping dot dot dot in between each one Why does it do that? That I have I didn't see that that must be some behavior of less Yeah, and it appears to be related to this quit of one screen because if I make it tall enough if I send the exact same command uh, and It just prints it once Hmm. I'm not That my terminal didn't do that. Um so definitely, uh Give it a minus s three minus e minus seventeen minus d space seven So you're saying minus s three Three minus e minus seventeen. You make it twenty seven. Okay. Yeah, and then I did minus d seven Uh, okay. See. Oh, you put it in debug mode then the No, yeah, okay. So And not as I'm not gonna put it in debug mode Yeah, try to write the debug mode and it should behave properly Let's see. I gotta make it Short enough You gotta make the table or well the other way is to go to and on a hundred and seventy and then I'll definitely No, it still does it without debug. It's it's if the window is shorter than one table height So if it if it's scrolling partially off screen that it causes it if you if it's tall enough it doesn't doesn't do it But it skipping. Okay. I've just tried to reproduce that with a tiny terminal window and it's not doing it for me It's behaving perfectly Well, I can send you a scrolling screenshot of it if you would like but it's it's a hundred percent predictable Actually, it gets it's you know what it does it gets down to minus fifteen That's what it does and it never so it doesn't get to minus seventeen Which would be the last number and it and it cuts it off It doesn't get the bottom cap and it says skipping and it did it again minus sixteen it skipped it again Uh, minus seventeen. Yeah, it doesn't how are you paging for you hitting this space bar? Enter Well, I can I can show Bart after the fact, but it's yeah, no, I cannot re-create this because if I had enter I get at one line at a time Until I get to the end and then I hit cutie the exit out of less interesting Yeah, no, mine is That's exactly what I'm what I'm typing and if I do the screen height has to be smaller than The height of the table I made mine like three three letters tall and it still worked Hmm, and you've scrolled back and you don't see this skipping thing Uh, what did I oh hang on I didn't try scrolling I just Did my lesson it Went through So you're saying if no I my scroll is working, but I'm using warp. So maybe warp is a nicer turn Oh, you're This is as much as I can get on screen. Whoo. Hello Uh, this might not be the most interesting thing for everybody else, but I just sent you a screenshot of what I see That's as tall as I can it keeps going past that If you scroll it's so the scroll it so the weird stuff is if you Roll it's after the command is finished when I scroll back up. I can see all the skipping skipping skipping stuff And the tables get imprinted longer and longer each time That's the mac terminal Handling its history in a strange way Uh, I don't know Now you it should page the table perfectly for you as you're going, right? I'm using the default terminal. I'm not in warp. I'm in Right sure sure sure, but I mean less is doing its thing that as you're looking at it You're getting it line by line and you can move up and down and it's behaving like less should Hmm Like no, it's all this it just prints all this all out to the screen But you're saying your screen was set to three characters high Ah I had I you did three characters high I've got a shorter than possible screen and then I increased the height And that's when I can see and it finished it pops out of the less command as I increased the height So I didn't know I was supposed to be hitting the spacebar Right, so it's yes. So the paging me Yeah, so paging is that standard scrolly behavior that you get from less or more So, yeah, yeah, don't don't hit the spacebar Just heighten your when it's partially drawn. I that's when I lengthened I was still inside less and I lengthened it and that's what created it Ah, okay. Yeah. Yeah, okay. That's yeah I didn't notice I was inside. I didn't know I was inside less Yeah, because I was trying to understand how the script works Okay, right. No, sorry that explains the jail. That's gets very confused if the universe changes midway I was like, but I was making it this size and then Okay, well, I'm glad we covered that All right, where did we go from here Bart? I was going to say I need to find my show note window again after all the telegram windows and stuff Okay, so at this stage the script is at its end now I'm just going to check my own notes to make sure I have said everything to you that I wanted to say Uh pretty ascii tables check calculating the width check Building our format string check Sep character did work command separator check conditional paging of the output check Uh, and then Yeah, so this is a decision point. Alison. So Either we get into XRX now or we save ourselves and we make a part two where we get into XRX So, um, it is 52 minutes long. It's uh, it's your call. I've got the time but uh I have a strange suggestion for you move on We should do it next. It feels like we should what do you think? Well, how's about we keep XRX until next time because XRX is going to take a lot of mental energy And how's about we skip on to what I put in as a second topic, which is arithmetic because it's easy Okay, good. That's the only part. I didn't read in the show notes because I was tired But I got down to that far. Okay, good Okay, uh, sorry, I did I'm bothered picking up uh signal. So is that good? Yes. Good. Good. Yes. That's good. Let's do let's Let's do some arithmetic Let's do some arithmetic So you have probably noticed throughout our code that we have been doing math Indirectly we have been making a string using echo and then making a string and then piping the string to the basic calculator Which is bc just well, you know bc stands for basic calculator And then we've been using the dollar open bracket close bracket Subshell to capture standard out and shove it into a variable So to calculate the product we say p becomes equal to dollar open bracket echo open double quote dollar n star dollar m closer double quote pipe bc closer bracket Which is not Short or elegant or frankly that easy to read So debugging that code six months from now is unpleasant Especially compared to other languages that we've met along the way So you're probably saying but there must be a better way And there is but I've intentionally avoided it because I didn't want to flood you with too many brackets at once. Uh-oh So just to remember now you're gonna flood us with more brackets. Okay I'm going to give you some more but a little recap of where we got to so the we learned that single square brackets are the old style sh so pre-bash tests and we should never use them We're going to see them in google search results, but we know better So we never use single square brackets The double square brackets are our modern test command. So they evaluate to true or false They they will become an execute of zero for success Anything else for failure and we use them as booleans. So they're the square brackets and inside the square brackets You have minus all sorts of things eq for equals gt for greater than n for not an empty string z for an empty string. There's loads of them So that's our square brackets two of them We also know that we can group multiple commands together inside roundy brackets So whenever you should have one command, but you want more than one you just pop them in brackets and hey Press so now they're together and what I may never have explicitly said Is that when you do the roundy brackets without the dollar symbol the output is the exit code So if you saved The output of a roundy bracket with no dollar, it's the exit code you'd end up saving Which is probably not what you want Which is why we almost always say dollar Roundy bracket and then we capture standard out into the variable So if we go back up to our example p becomes equal to dollar roundy bracket echo whatever to bc So bc writes the answer to standard out the dollar roundy bracket shows standard out into p That's how it works. Okay. All right. So there are all the brackets we've met already and that's quite a few Now I'm going to introduce you to double round brackets Okay So double round brackets without a dollar sign will do the arithmetic and there is the output will be the exit code of Whatever the arithmetic is and the arithmetic can include conditions. So the exit code could actually be useful A dollar sign means no, no I want the answer from the math So if I multiply so it it sort of works the same way a single round brackets Yes, that there's logic to its Very denseness, but there's the world of difference between Run me a sequence of commands, which is single bracket or do some math, which is double bracket Okay, so it is important to build this up because Boolean tests are more like an arithmetic thing than not an arithmetic thing. So With those two together, I'm I'm screenshotting this with my mind hoping dorthy puts a a pointer to it in the pbs index She will know So Like inside the double square brackets, the rules are different So remember we said that inside the double square brackets You can do things like minus f or does this file exist and that doesn't work outside of square brackets, right? The square brackets are like a universe where there's different syntax The roundy brackets put us into a math universe. So we enter into math land and in math land The universe is a wee bit different So the first thing is we do not prefix our variable names with a dollar So if I want to access a variable named p, it's just p Which if you think about every bit of calculus you've ever seen in your life, it's just the letters so, but okay I Freaked out when you said that we're not going to use dollar symbols with our variable names But only when they're inside double roundy brackets Correct that is only in math universe. It's a sacred ground It's a sacred ground. The only thing in here is variable names and numbers, right and the various, you know operators no strings No, can't have strings in here. None of that because this is math universe. Okay. Everything's numbers, right? It's all numbers. I'm happy you're there Yeah, okay So our variables do not get prefixed with the dollar symbol and if you're looking in the documentation This is called automatic variable expansion That is that is what they call that fact. Hmm. Okay We can also use the assignment operator without having to cuddle it. So in normal bash universe you have to say p Equals a value no spaces are the whole thing explodes Inside round your bracket universes. You can space your code out and it's all fine Can you cuddle it if you don't want to be scared and maybe make a mistake? By all means you won't care. Okay. By all means. We don't have to space it, but they'll start screwing up the other ones. Okay. All right Yeah, uh, we can also use a whole bunch of mathematical operators that Have their purely mathematical meaning in here. They have no other meaning So plus doesn't mean concatenate. It means Mathematically add these things together Minus means do the actual arithmetic slash means divide star means multiply We also have our plus plus and our minus minus for incrementing and decrementing and we have our percentage symbol for modulus just like in javascript And we have something that not all languages have star star means raised to the power of so two star star eight is two to the power of eight Which right, you know can be useful We can also do comparisons in here in arithmetic land So double equals is a numeric comparison. Are they numerically equal? Not equal so exclamation point equals is not equals is are they numerically not equal? Less than is numerical comparison greater than is numerical comparison. We have greater than or equal to or less than or equal to And so just like normal Just like normal exactly in here. It's like any other language we're used to Right inside the double brackets things are a lot simpler We can also assign valuables to variables in here So we can use equals for a simple assignment plus equals for increment assignment Minus equals for a decrement assignment star equals slash equals and even I've never in my life used up, but it does exist modulus equals percent equal what that what would that do So it is the equivalent of saying x equals x modulus the number So if you say x percent equals three that is the same as saying x equals x modulus three Okay I plan on never using that. Okay, so far I've gotten to life without using it. So, you know And then the last thing our friend the ternary operator from javascript makes its first appearance here in bash land It can only do numbers. It's very annoying. I wish I could do strings, but no it can only do numbers So we can say the variable p becomes equal to 40 Supervility becomes equal to one if Oh, let me say all that again. I made a complete mess of that example Um, basically it's condition question mark answer one colon answer two so The outcome of dollar around your bracket round your bracket p double equals 42 Question mark one colon zero will be one if p is 42 Or zero if p isn't 42 Okay Good. Yeah, sorry. I said that terribly, but yeah so All of this means that we can take a horrible statement like p becomes equal to dollar open round your bracket echo quote dollar n star dollar m close quote pipe bc We can replace all that with bracket bracket p equals n star m bracket bracket Nice That is so much more readable like nature like nature intended bart Yes Now because when we don't use a dollar the result is the exit code We can use it in if statements So if roundy bracket round your bracket p double equals 42 close our round you brackets Then echo life the universe and everything Feed and or if statement Okay, okay, um, so So Just just a darn second here. We can't replace p equals dollar round bracket all that glop with Round bracket round bracket p equals n times m. Those are not the same thing the one with the dot the single um roundy brackets is uh, that's the actual value not the um Uh, it's it's not the exit code. So those two statements are not the same Uh, sorry, I'm not with you at all anymore Okay, this you wrote this means we can rewrite a statement like p equals dollar round bracket And you said we can replace that with Round bracket round bracket p equals n times n round bracket round bracket Those are not the same that you would have to have a dollar sign in front of the second one for it to be the same That is not correct because The end result of the first statement is that the variable named p will contain the results of our math Correct, but the one with the two roundy brackets will is the exit code. So they're not the same. Ah, they no no Where are the roundy brackets? The result of the roundy brackets is being completely ignored in the shorter example It is roundy bracket. It is not something becomes equal to a roundy bracket roundy bracket It's just a roundy bracket. So the exit code is ignored We don't use the exit code inside Roundy bracket universe. We do the assignment p becomes equal to n star m. It's all inside the brackets Right, why did you bother telling us that without the dollar sign? Because if okay if we wanted to if we wanted to use Okay, we'll see if we need to use the result of the math straight away We need the dollar to say give me the value, but we're not we don't want the outcome of this We just want to be in math universe to do the assignment Right, everything we need is happening inside math land So we we don't use the output The output from this statement is irrelevant So if you've you've got Roundy bracket roundy bracket p equals n times m if the next line said echo dollar p Would it be the value of n times m? Yes, it would or would it be the exit code? No, no, it will be the value because inside the brackets the assignment has happened Right, you have you have made p to correct. I'm not buying it. I'm not buying it. You said Well, then the the explanation doesn't make any sense. Okay, if you said q becomes equal to round you bracket round you bracket p equals n star m Then q will have the exit code and p will have n star m Oh, oh, so p would still the value in p would still exist even though Assigning it to something tells it the just the exit code That is very weird So the output of the round you brackets is the exit code But inside those round you brackets the thing we did was assign a value to p So that's done and then the exit code happens. Well, we don't give a bleep about the exit code Right. We're not doing anything with it. We wanted to get p to become equal to n times m without Fafn about with pipes Do we have to initialize p beforehand or does it just come into being because this We've just made it come into being there because you said p becomes equal to Okay Okay, that's Not any chance. I'm going to remember that one, but I believe you right now Well practice because Practice is going to help you there because you're going to do math a lot Yeah, I need lots of homework to do practice though, but you Remember, I don't have any reason to use this so weeks go by where I don't do anything But you are going to get your homework even though we skipped over x are you still going to get your homework? All right, good now So we then say that we can use this inside conditional statements, right? So because the result of the round you brackets is the exit code You can use the round you brackets in if statements because if statements need exit codes So if round you bracket round your bracket p double equals 42 So that's a comparison not an assignment single equals as becomes equal to double equals is is equal to So that gives us the exit code which is what the if needs Then I can correctly print life the universe and everything only when p has the value 42 Okay We can also use the same syntax in our little shortcut with the ampersand ampersand Because the exit code is a true false value Therefore if that is true, then the second statement happens echo life the universe and everything So that is a shorter version of the same if statement Yeah, I like that. Okay good Now by using the dollar we can get the answer from the math So to get the sequence from one to whatever n times m is we can say sec for the sequence command The first argument is one the second argument is the value of n times m Wait, what's what's one? So the sequence command takes two arguments where you want the sequence from and where you want the sequence to So to get a sequence from one to n times m the first argument is one. So, okay Okay, and the second argument is the value of the math Okay Well, I like it I do hope to use it to submit it Well, your challenge is to redo your table using round bracket math So that means I have to have a reason to use math. Mine didn't have any math Yours had you must have had math you oh, I'm sorry. I'm sorry to just do the multiplication. Yeah, okay Yeah, so yeah, whatever whatever math is in your solution Do it with the round you bracket land And it should make your code cleaner. I hope That is the intention. So in the next it's been More than four weeks since I did my homework. So that's why I forgot I I do actually do math Yeah, I remember it being nearly as complicated as what you're doing though Yeah, I just said echo range min times uh The number Pipe it to bc And then print the answer print it out. It's all it said Hmm. Okay. Well, anyway You I'll change it you change it exactly So in the next time our part two of this is going to be that one line of code Where we have the two x-rx and it is going to take us Probably 45 minutes to explain that line of code Really? Okay. Good. Well that that explains why it took me close to two hours to read the show notes earlier today Yeah So and it's important x-rx is very powerful. So I I don't want to rush x-rx Good. Good. I'm glad we did the arithmetic. That was fun. You were right Hey, okay. Well with that, I think we have we have certainly given people enough to digest for a while So let us hope they have lots and lots of happy computing between now and right next first But but first part where should they go to talk to other people who are doing the programming my stuff work They should go to potfee.com forward slash slack where all the cool people hang out There you go. And there's a pbs channel if you haven't been there There is no gatekeeping to enter this and I don't understand why But nobody mean or nasty has gone into our slack knock on wood If you're still listening after the how are we even recording this or more? You're our people Exactly It's a filter it works All right, now you're allowed to tell them to happily Compute Bart good good good. Okay folks. Well, there's lots there if you digest so until next time happy computing If you learn as much from Bart each week as I do I'd like you to go over to let's dash talk dot i e And press one of the buttons over there to help support him He does 98 of the work here I'm just the stooge that listens to him and asks the dumb questions If you go over to let's dash talk dot i e you can support him on patreon You can donate via paypal or you can use one of his referral links I really hope you'll go over and help him out In the meantime, you can contact me at pod feet or check out all of the shows we do over there over at pod feet dot com Thanks for listening and stay subscribed