Back to Index

Live coding 18


Chapters

0:0
16:19 Math Notation
16:37 Feynman Diagram Notation
23:51 Grep
33:27 Search and Replace in Destination
65:27 Dictionary Comprehension
75:12 Install Gradio
78:41 Upload a File
78:58 Create a File for Uploading a Generic File
86:47 How Long Do You Plan To Keep this Live Coding Running
94:14 Complex Numbers
94:29 Monadic and Dyadic Forms
97:45 Defining Functions
99:18 What Do People Use Apl for Nowadays

Transcript

I don't know if you saw, but somebody on the forum, not just somebody, somebody extremely helpful and kind being Daniel on the forum, he does these summaries of the walkthroughs. I saw that, Jeremy. I tried to do a little bit, but I think I didn't have time to finish it off.

Oh, yeah. Okay. So did you want to maybe share your screen and get us up to speed with what the problem is we're solving and where the data is for it and stuff like that? You're muted, by the way. Sorry. Yeah, actually, it's just what was in, I think it was the 7/13th live coding.

Live coding. Which one? Live coding. Live coding 13. Live coding 13. Okay. Yeah. Yeah. So I basically, I kind of had a really janky solution. It's not, it probably doesn't work, but what I was thinking of doing was like putting them in some kind of like a file side by side and then sort of indexing it, but I actually didn't do anything.

And what I did is basically this at the end. Uh-huh. So, so I'm not quite sure how to take it any further because I don't even know what it is yet. So let me just, so, okay. So I've got my screen sharing here. And so, can you guys see that okay?

So where do I start? So he, I didn't quite understand, like, Um, I'm finished on the forum. Yeah. Okay. So that's basically like, if you get that note at the end, he's got all the images. Yep. Right. So these are kind of like the, at the end, he's got the actual images in, in, in that dropdown.

And what I did was I actually went in there and I looked at the code or what the HTML is meant to be in the same order as like, do these have names or I just, I don't think so. I don't think so. The same order. Let's see. So this is, this is called at, actually, what we could do is if we click edit, right?

Oh, I see. This is like, got off the edge of the screen. And so let's see. So these have, ah, okay. These have names. Okay. Cool. Like add to class and then presumably there's an add to class somewhere here. Um, let's try searching for that, add to class. Yes.

Yes. Yes. Oh, that's cool. And then the sizes are different a little bit and this is in a couple of brackets at the end. I'm not sure what kind of, um, regex would do that, but I think the one that I got, it kind of, it just kind of captures.

So what I did was, what I actually did was I went to the bottom. I took all of the ones from the bottom and then I got rid of the, um, I just extracted that and that's about how far I. Okay. No worries. Let me just start up Jupyter then.

Okay. Um, all right. So this is our, this is our kind of source images. Okay, so you guys know if you put things in triple quotes, then it, uh, creates a multi-line string. Um, okay. And so then we've got our destination, which is everything else, right? Okay. So there's a good start.

We've got our data. Uh, so like, I guess like, um, the reason I thought this might be interesting to do, um, here is basically, um, yeah, people often ask, like, how do you go about actually solving a problem or doing coding or whatever? I thought, I guess if we do it together, then we can go through the process, um, uh, which will work a lot better if you, yeah, ask questions or add comments, you know, as we go, obviously.

Um, one thing that does occur to me is in this notebook, actually, this is, I find quite this is quite awkward to have so much data here. Um, so what I might do actually is instead put them into, into, um, text files. Um, so this one is the source, right?

So in bash, um, if you type cat and read, and then, uh, this means redirect to a file, right? So we could go to file called source dot text. Um, it's now reading from standard in, it's reading from the input, right? So I can paste like so. And then to tell, um, basically in Unix to say, I finished this file, you hit control D.

Okay. And so if I was to now VIM that you can see it's there. Okay. So that's how you can quickly and easily, there's lots of quick and easy ways to create text files. Wait, wait, wait, Jeremy. How did you do it? So, sorry, I got confused with the prompt because there was this gift thing and I said, wow, get, uh, uh, you know, and it's just, it's just the name of the directory I'm in.

Yes. Yes. Yes. I figured it out to post. All right. Uh, so it's just, right, just, it was just this less than sign which pipes to the greater than sign. Yeah. Yeah. Or greater than sign. Yeah. Right. So the main thing I guess the main like just to put this together, if I just type cat, right?

And then I type text, it just prints out whatever I type it. Okay. So that's what cat does. Um, the reason it's called cat is actually concatenates things. If you feed it multiple things, it adds them together. If I, uh, I can redirect from, um, a file, which means instead of me typing things in, it'll, it'll get its input from a file.

So that would cause it to print it out. Or if I redirect its output, then whatever I type in will go to the file. So one way to copy things, for example, would be to read things into cat and then output things into something else. Like a really dumb way to copy, but like, you know, it does the job, right?

Um, so yeah, cat just anything cat bring gets into standard in goes to standard out, standard in being the input to a, a Unix command instead of being the output from a Unix command. So if you do cat, uh, greater than file name, it will still let you type in stuff.

Right. So that's what I did before. Right. Is I pasted and then at the end I hit control D. Right. So now if I cat and take it from that, uh, there's, but I just typed. Okay. Control D at the end control D means end of file in Unix.

Um, yeah. So if I, sorry, let me move you over here. Yeah. So if I hit control D at the end, that's that, then it says, Oh, you're all done. You might've seen something similar, um, um, uh, um, like, I think it's like this. Yeah. That thing. I know.

Okay. And at the end you type whatever you typed. So like, but there's no reason to do that. You can just, cause you could just use control D. Cool. Yeah. If you use this double less than side, it means keep reading until you see that string. That's quite a here, doc.

Um, this is the mystify salon. Yes. Yes. All right. So let me show you that again. I'm going to do it again from my destination, right? So let's grab all that. And by the way, knowing how to do things like select to the end of line and select to the end of file and stuff like, you know, using command and control and shift and end at home, that stuff's really important to know.

It varies between Mac and PC. So if you don't know how I just selected all that, then it's definitely worth Googling that. Okay. So I've just copied that. So I just want to put that into cat, redirect the output to destination dot text. Right. Paste control D, control D.

I don't know why I had to press it twice there. That was strange. Maybe I had to hit I don't know anyway, did the job. Okay. So actually, so I guess like my starting point normally is just to kind of like import my like standard set of things that I wish Python had, which is called fastport.utils.

Oops, import stuff. So as some folks have pointed out before, some languages have things called a prelude, which is like the kind of stuff that people like to always have available. This is kind of my version of it with a prelude. And one of the things it does is it imports some things from the standard library, Python standard library that I always use, and it also imports some things that fast core adds to the standard library.

So one of the things it adds is path.lyp.path. So path, okay, like so. And so path.lyp.path has a read text. Okay, so that's better. One thing that I don't particularly like is that the standard representation of strings in Jupyter uses backslash N. If you want to replace it with actual near lines, you can say print.

Or you know, like you can just do this. And so just remember curly brackets. So this means do this as a bash command, and curly brackets means read this Python variable and put it into the bash command. All right, so then we can do something similar for destination. One thing that people complain about with my code quite often is my use of abbreviations, like you might reasonably ask why not at least put the E there, and it's just totally fine.

You could put the E there. But just to explain, I quite like to have similar things be similar lengths, because it makes it really easy for me to then like have lines next to each other that operate on those two things, and all the bits will be in the same place, and so my eyes can immediately see if there's some unexpected difference or something.

So it's not just me being trying to be difficult, it's, you know, there's actually a reason that I quite like doing that. Just not to say everybody has to do that, that's why I quite like to do that. And there's also something to be said for like having a standard way of coding, that then you just don't think too much about how you code, you know, so like I just have STEM standard way I tend to name things, and then I don't spend time thinking about naming things too much.

That's cognitive load I can focus in on solving the problem. All right, so I guess the first thing we might want to do then is we basically, we probably want a dictionary that goes from the name of the thing to the location of the image right. And so then basically then we'll just go through each one of these here and replace the name with the value of that when we look it up as a key.

So there's a thing called find all, which you give it a regex and it finds all the places of that regex. Do you guys tend to use regexes? Is there anybody here who like doesn't really use regexes or not too much? Yeah, so regexes are what we call it a DSL, a domain specific language.

They are, yeah, they're not Python, really, Python happens to have support for them, but they very much don't look like Python. I actually tend to think of them as a notation, and notation is one of my favorite topics. The notation is a way of representing some potentially complex domain in a concise and expressive and flexible way.

So for example, a notation that you've definitely used before is this one, right, which is called math notation. If you play music in the Western tradition, then you will have seen the staff-based music notation. If you juggle, you might have come across the juggling notation. If you've done quantum stuff, you might have come across the Feynman diagram notation.

So notations are, yeah, they're expressive ways to represent things. And regexes are a notation for finding stuff in text. Not many, honestly, things in computing have got to the point that they're so well understood and studied that we've got them to the point that they are a notation. Regex is one, and my view is often, most of the time, perhaps, when something has got to that point, we should learn that notation because it's like a way of composing things together very concisely that can solve a wide class of problems.

Jeremy, would you recommend learning things like Auchen said also long term? I wouldn't recommend Auchen said, I would recommend Pearl because Pearl is a superset of Auchen said, and as such, it's more expressive than either because you can combine everything from Auchen said and find and pretty much everything from Python as well.

So yeah, at some point in your life, it's well worth Googling for Pearl one-liners, and diving into that rabbit hole. So another nice thing about regexes is because Pearl's regexes were so good, they were built by a linguist, Larry Walls, it's not surprising, perhaps, that they used almost everywhere.

So JavaScript, Python, Pearl, C, via the PCRE library, they all use the same regexes. Things are slightly different, in VIM you have to add a few more backslashes to things, but it's actually possible to turn on a VIM mode, which is almost identical to Python and Pearl, which is called the very magic mode.

So you can turn on very magic mode, and then VIM basically is the same as everything else. Okay, so... I got a quick question about like 20 minutes of this, I wasn't here last time, so what are we trying to do? Yeah, this is not a from last time, this is what we're trying to do, is this something new.

So what we're trying to do, thanks, is Daniel creates these nice descriptions of everything in these sessions, but this is how his images come out, which is not very helpful. So I thought it would be nice if we could, for him, make a script or something that would allow him to put the correct images in here.

And I don't know why it comes out this way, but that's fine, he's got a process he's happy with. And in this process, the images end up, you know, he can easily paste them all at the end, right, so here's all the images, and so the images in his, that he pasted at the end look like this, right, so they have names, right, and then in the forum post they appear like this.

So we have to replace this basically with this, but with probably with this size would be my guess. In fact, let's just check that, so yeah, that's what he wants, I guess, fixed test error. I wonder which size he wants. So fixed test in source path, 690 by 184, and where was that fixed error, okay, that's at the end, and then in this destination path, I wonder if these are the actual sizes, did he, let's have a look, did he say?

I think these are the actual sizes, I'm not sure why it has the 900 standard size or something, it seems to have, presumably that's what he wants, that's presumably the size he wants, I guess, let's have a look, so if I copy that, this post is to test image stuff for Daniel paste, okay, so that's the size it appears there, and then what if it says 900?

Oh, it doesn't really make any difference, well. If you were to try it without, it should also work without, it would just. Oh yeah, it would work, I just think like he's, like I assume that some of the images he's intentionally trying to resize, it depends. Maybe this is for his notes up, well yeah, I mean he's got two different sizes, one of them is for his notes app, I assume, and one of them, I'm not going to assume this is the size he actually wants.

Maybe it's already as big as it can show, and yeah, that would be my guess, I think so. If you right click and open it in a new tab, would that, or would that just show the original? I think that'll show the image, let's have a look at some more, oh wait, does it always say 900?

Oh, some are 1200, I see. I think all of the X by Y is the one when he drops them into the interface, and it just takes whatever the size. I would say so, so I think this is proper, let's assume this is actually what he wants. I think that's a reasonable guess, okay, so you can see sometimes I just judge, you know, grab bash commands when I'm fiddling around, just because, yeah, sometimes, I don't know, it's just like an easy way for me to quickly check things, so grep, so actually grep doesn't take normal regexes, but you can, and I need to get into a habit of doing this, yeah, you can use minus capital P to use Pell-compatible regular expressions, so when you're looking for like, can I use normal regular expressions, specifically the thing you generally want to search for is PCIe, they're called Pell-compatible, so apparently we can do this, not that it'll make any difference in this case, but no, this one, okay, what about egrep?

Nope, okay, so that maybe it's in some more recent, oh, you know, maybe the best thing is not to use egrep, but instead to use rg, which is grep, which I guess I have to install. I noticed that, is that a different version of grep that you use? Yeah, so rg is like, so basically like for pretty much all the classic Unix tools, somebody's rewritten it in Rust and made it better, or C++ or go, you know, increasingly it's Rust.

I don't know what grep was written in, but like it's basically like in this kind of general category of like, better versions of classic Unix tools, and I try to like, get into the habit of using the newer better versions, so even though it takes some retraining. So yeah, rg is the kind of...

I meant to ask about that yesterday because I noticed you were using that, and I thought maybe it's for recursive grep or something. Oh yeah, yeah, no, it's actually a program, which amongst other things seems to be highlighting the thing I'm searching for, which is cute, and showing the line number.

And Jeremy, you find that "brew install" doesn't mess with your mamba-forge installation, are those orthogonal pretty much in your functions? No, it should be fine, yeah, I mean, I'm not in paper space here, right? So like, I wouldn't use... I tried filling with "brew" in paper space because there is a Linux "brew" nowadays.

It seemed okay, but it uses up a lot of space, so I thought just using mamba to install binaries like "rip grep" in paper space is probably the best option, you know, because it doesn't use any more space than necessary, but you know, the two shouldn't get in the way, like they'll both add themselves to the path, right?

So opt-home-brew-bin and mamba-forge-bin. So they're just both in the path, yeah, I can't see why they would get in the way of each other. Okay. All right, so find all looks for a pattern in a string, right? So you know, I tend to like to like to create like a really simple version of something just to make sure I understand a command before I dive into it.

So I reckon we should be able to find the word "fix" in our source, right? And there it is, okay, it's appeared more than once, okay, there it is, right? So then if we generally with regexes we use backslashes quite a lot to mean certain things, but Python uses a backslash to mean something else, which is that the next character is a control character.

So to tell Python that treat backslashes as backslashes, you put an R before the string. So this looks for the, you know, backslash-F fix test, in fact, you know, if I just show you here, backslash-N is normally a new line, but if I put an R there, it's not a new line.

Actually, this would be easier if I say print. So that prints new line fixed test, and that prints backslash-N fixed test, okay. So we're going to look for stuff of this form, that's our source, right? So I would be inclined just to paste it in here, okay. So square brackets have a special meaning in regex, so we can use a backslash to say don't use a special meaning, ditto with pipe, ditto with parentheses.

Let's get rid of all those, okay. And so this is going to be the name of something. And so if we want to remember some block of text, we can put it in parentheses, right. So the thing we're going to try to find here is basically, I think probably anything that's not white space will be fine.

So backslash-S means not white space, and plus means one or more. I don't think we care about the size, so we'll just skip over this. And then this is actually something we do want to keep, which is the actual file name we're going to end up with. So I'll create parentheses for that and put my backslash-S plus there as well, okay.

So that's looking pretty hopeful, so what it's done here is found 29 things, which looks something like this. I put parentheses twice here, which is why it's appearing twice. That's better. Does that make sense? So it's basically showing us each of the parenthesized expressions. And so actually, we don't need this bit to be parenthesized because I don't think we care about the original size, okay.

And so we should be able to create a dictionary from that because we've now got a list of tuples. I never quite remember how this works, but yeah, there you go. So the list of tuples, if you pass it to dict, it'll create a dictionary. And I think there's something to be said for programming in an interactive environment that allows us to gradually build up a thing that works and then assign it to a variable or stick it in a function or whatever.

So now we should be able to search for "found add to class". And we do. So we've got the dictionary we wanted, does that make sense so far? Yeah, I just have a question about that you got rid of the size. So if you don't put the parentheses, does that mean it will just ignore that?

Yeah, I mean, it has to be there, right? So if we said, oh, look for AAA, well, that's not there, right? So it won't find anything. So it's still searching for it. It's just not storing it. So it's finding an exclamation mark, open square bracket, finding and remembering a bunch of non-whitespace characters, followed by a pipe sign, followed by a bunch of non-whitespace characters, which it doesn't remember, followed by a closing square bracket, followed by an opening parenthesis, followed by a bunch of non-whitespace characters that it does remember, followed by a closing parenthesis.

So putting parentheses makes it remember essentially keep track? Correct. It does two things. It also groups things, which is a bit confusing that it does two things. But yeah, in this case, the thing we're using for is the fact that it remembers things and will end up in the output of re.findAll, amongst many other things.

If you just do re.match or re.search, it will also remember them. It just returns slightly different things. re.findAll is one of the easiest things to use those, so I think it's good. Okay, so now we need to basically search and replace in destination, looking for stuff like this, okay?

So this is our destination. Kind of want to look at the end of it. Okay, here's two things we want to change, right? So I'm just going to, like, use the last few characters just so I can see what's going on. So I'm just going to put that in a variable for now, okay?

So there's a thing called re.sub for substitute. It's funny, a lot of Python programmers complain about me using three-letter abbreviations, but Python apparently is allowed to use three-letter abbreviations, re.substitute. So we're going to find a pattern and replace it with something else, and we're just going to search in SunStream.

So for example, if we replace space with star nd, okay, that's basically how it works. Or you can search for a regular expression. So let's search for that, okay? And again, we're going to use r because we're going to use backslashes. We're going to search for a literal square bracket.

We're going to search for a literal vertical bar, okay? And you can see that's been replaced with a star. And so this thing here is the file name, and the bit before the dot is what we're going to look up. So I'm going to do -- so we're going to capture this.

And the thing we're going to look for is everything except for a dot, okay? So to say everything except for a dot, in square brackets, you put the things to look for, and a carat means things you don't want to look for. So this is everything except a dot.

And this says to capture it. So remembering, I call it remembering, it's actually called capturing. Dot has a special meaning, normally, which is anything at all, so that's a literal dot. It's not always PNG, so I'm just going to say any three characters. In fact, regardless of whether it's jpeg or -- oh, here we are, oh, it's also sometimes it's jpeg.

Could be four characters. Okay, no worries. Okay, well, anything -- could do -- oh. I know, we could just do some letters. So backslash w is a word symbol, so basically letters and numbers and stuff. So we'll have a bunch of those. Okay. Now, interestingly, in this case, this has got a pipe 900.

This has got a close square bracket. So there's a few ways we can do this. I'm going to show you -- okay, I've got to show you the more interesting way, which is that -- no, let's do it the simpler way. Okay, so the simple way is rather than looking for any word symbol, let's just look for anything that's not a close square bracket.

So this is going to be slightly confusing, but basically this is a regex that searches for any a's or b's or c's. This is a regex that searches for anything that's not an a or a b or a c. This is a regex that searches for anything that's not an open square bracket.

So we want to find a bunch of things that are not a square bracket, plus means one or more. And then there's going to be two close square brackets. Okay. So that didn't work, which is good, because now I can show you how I go about debugging these things.

So to debug these things, I would just gradually make this simpler and simpler until it starts working and that way we'll be able to figure out why it's not working. So I'm going to delete all of this. Okay. So that didn't work. So let's keep deleting. Okay. So that one did delete.

Oh, okay. I see the problem. So you can see here, it's just replaced the first letter, which wasn't what I wanted, right? I wanted to grab a bunch of these. So this here says, oh, this here says anything that's not a dot, right? But we actually want one or more things that aren't a dot.

That's better. Okay. So one or more things that aren't a dot. So we can go back and now replace that up here with one or more things that aren't a dot. There we go. So that's now successfully replaced all that with a star. So that tells us that we've got our search working correctly.

What confused me is the charate in the square brackets, because I know that the charate is a symbol for start of line. Oh, yeah. That's true. So I had to Google it and it turns out that if it's inside the square brackets, it means not. But if it's outside, it means start of line.

Yeah. Yeah. No one's going to claim that necessarily this notation is spelt the best. I guess it was made pre-unicode, you know, so it had to rely only on ASCII signs. And so I don't think there's enough ASCII symbols. So it ends up having to reuse ASCII symbols in ways that are entirely incompatible with each other.

Yeah, that's correct. So if it's not inside square brackets, it means start of line. If it is inside set brackets, it means the complement of the set, the opposite of the set. The dot which is inside bracket don't mean any character. No special character. Yeah. That just means a dot.

And I think in square brackets, except for except for carrot is literal. Yeah. So you could do this to make it extra clear. Yeah. In the chat, I shared link to PyTech.org, which is nice because it has a cheat sheet. So whenever I'm working on the regex myself, I never remember.

This is based on Rabilar that was very famous in the Ruby world. It's nice for testing your regexes. But also if we expand the cheat sheet, which is yeah, and then now if you put a string in your test string, it will and you can put a couple of strings there.

It will show you what it's doing. That's how I figured out the regex. I went to one of these sites. And then the most crucial bit here is the regular expression cheat sheet. When you click on it, it expands and you have all these things that you can use.

Yeah, I think regex 101 is the one I've tried before. Which I think has a bit more of an explanation, if I remember correctly. So I like this that you've got the quick reference. But you've also got this explanation that matches this character, matches the character. So a capturing group, that's something that remembers, is a capturing group.

A single character that is not one of these. Oh, yeah. So the first like learning a notation is hard, you know. And so like almost any notation people don't, as a matter of course, learn at school, generally gets categorized into the weird, complicated, annoying thing category, you know. But there's nothing like more or less weird or annoying about regex than basic arithmetic notation.

It just isn't something we learn at school, you know. And it's yeah, you know, arithmetic takes us some years to learn, regex. Has anybody learned regex recently, got a sense of how long it takes to learn, like days, months, weeks? First time I started using it, I think it was actually last year's FASTAI course, where you introduced it.

And yeah, I always saw it before and I thought it was kind of like, you know, these weird magical symbols that I'd never understand. And then basically, I like got a basic understanding of it, really useful tool. And then every few months when I have to come back and use it for something, I just use one of those like online regex tools to kind of like give myself a jumpstart to get back into it.

Yeah. Yeah. I mean, it comes up so much. It's like, I would say it's notation worth mastering, you know, which I wouldn't say about that many things. And mastery requires probably some fairly intentional practice over a period of time. Yeah. But yeah, certainly the kind of like use it from time to time and learn a little bit more each time also also works.

So I'm going to show you something which I would guess most Python programmers don't know, but which is amazing, which is that this thing here, the thing we're replacing it with star doesn't have to be a string. It can be a function. So here's a function that returns star.

And that does the same thing, right? Or return, we're going to be at past the thing that's being replaced. So you know, just one thing we could just do is just print that out. OK, so we're getting past an ari.match object. And so you could better handle this. So an ari.match object, we can also get your audio, I think, or this is what you mean.

Can you guys hear me? I can hear you. I can. I can. I can't hear anyone. Sorry, my computer did something on its own, it's a bit weird with audio, sorry about that. OK, so I think to play with a match object, we should probably try and create one, which I think if we go ari.search, we'll get a match object.

So let's search for that pattern in that string. OK, so there's a match object. So hitting dot and pressing tab isn't a bad idea just to see like what kind of stuff we can do. That looks nice, groups. Oh, it doesn't seem to do anything. Ah, it's a default, got it.

This is confusing with groups because group zero is everything, right? So there's groups in group. So group is something where you give an index or name and so zero gives you everything that was matched and one gives you the first thing that was captured. So that's actually what we want, right?

So if we here did return star x.group1 star, OK, you see what's happened there? So again, I'm doing a lot of exploring as I go. And so like I find using this approach, if I'm working with my code, I basically never get stuck because every step I'm doing is so small and it's from a known place.

But it's a small increment and I'm kind of keeping most of the steps along the way. So it's really, yeah, it's very hard to ever get lost or stuck. So yeah, so now what we have to do is look up the thing in found, right? So found, there we go.

OK, so now we've got to put it in the right format. So actually, yeah, we basically, yeah, this is interesting. We actually want to keep this bit, right, if it exists. So what we can do, yes, we want to keep that bit if it exists. So this thing here where we're searching for anything that's not a square bracket isn't quite what we want.

I think we actually need to specifically find the extension, right? So we're looking for a full stop and then an extension. OK, so an extension is a bunch of letters, right, is a bunch of letters. So backslash w plus. Strictly speaking, it should be three or four letters most of the time, but that's OK.

We'll just say backslash w plus, right? And then next after that, there's either going to be a closed square bracket or there's going to be pipe followed by a bunch of digits. So in other words, there's going to be optionally pipe followed by a bunch of digits. And I want to keep that because we want to put it in there if it exists.

So we're going to look for pipe followed by a bunch of digits, backslash d as a digit. OK, so we're going to look for all this, right? Now to say that that is optional, you use question mark. And so I'm just going to change this to zero just so we can print out the whole thing to make sure it's working.

Oh, and we don't want to do that anymore. Let's see. OK, so it seems to have worked, right? And in fact, what we could even do is just say, print out the groups. And that way we'll see, OK, it's got fixed test error, pipe 900, and fixed issues, none.

So you see how the optional thing is coming through as none here, right? So what we want to do is then look up group one, right, which is this. And then if it exists, we then want to put in the pipe 900, OK, switches x dot group two, not inside square brackets, found x dot group one, oh, and that's the end of curly brackets there, and start curly brackets there.

There we go, upload, blah, blah, blah, dot png, 900, oh, and so then this string is going to start with exactly the same thing we had before, which is that, and it's going to end with two square brackets, OK? So we get rid of our stars. OK, we do, slightly annoying.

So or is a Boolean operator, which returns the thing on the left if it's true, and the thing on the right otherwise. And so because none, string of fives is the string none, but it is also considered falsey. So this will turn none into an empty string. OK, well, let's try that on the whole thing.

So one easy way to, you know, when you're doing something on a subset to change it to the whole set is you just go delete, like so, all right. So we've got a key error, which is understandable. So we're missing good mix. So let's see if that's actually missing or not.

So let's have a look in the source and search for good. OK, there is not a good mix. So what I'd be inclined to do then is change square brackets to dot get, because dot get lets us provide a default. So let's use that as a default. All right.

Looks hopeful. Oh, you know what actually would be nicer? I think this is going to end up kind of having like just a broken image symbol. I think instead what I'd rather do is grab all this and say if we found it and do that, otherwise return. That way we'll actually be able to see it.

There we are. Interesting image. So let's test it. Ah, okay, so I did it, sure, oh, okay, so I think I made a mistake. The destination format is not that at all. The destination format is actually this format. It's actually exclamation, it's square bracket, okay, so that's not correct.

If res, it's exclamation mark square bracket. Doesn't really matter what the name is, but I guess give it a name. And then, Interesting. Size if there is one, just the this, then close square bracket, and then a parentheses, and then the file name. Okay, is that right? Oh, I've got an irie.match object, that's not right.

Oh, it's, yeah, this. That looks better, doesn't it? Copy. Paste, oh, that looks helpful. Aha. How about that? How about that? Yeah, some of these are too big, but Daniel can easily change. I mean, let's test it actually. So for 3333, let's see if we can change the size.

Sometimes it puts a little percent sign, but we can put in. Does that work? Hmm, discourse, image size, oh, comma. Right, it was a bracket in the comma. A bracket in the comma, sorry. Mm-hm, yeah, I think it was, cuz the next comment they say just by adding. By adding comma 20%.

You still have to have the pipe in there. You think so? Yeah, the end, but he's like a quick just. Yeah, so at the end. Yeah, the last sentence there. Yeah. So that might be, you could just do just the comma 50%, I assume after a bracket, maybe that would work.

Well, in here, it's got the before the bracket. Oh, not the bar thing. Oh, the pipe. Yeah. Let's try. Yes, okay. Maybe take the dimensions out. Ah. So, here we are, 50%. Okay, so I think we probably shouldn't be putting in his sizes because they actually want to keep the sizes.

So let's change it. Oh, by the way, it opens and closes the output of a cell, which is quite handy. All right. So. I guess we're going to have two things. We're going to have the size and the file name. So that's fine. So all we need to do then is to capture this.

So it's not a dictionary anymore. Okay, and so then we could say found and we could do a dictionary comprehension. So for name comma size comma file in that, we're going to go from a name to a tuple of the size and file name. Okay. So. We're now going to go x.group, okay.

And so that means we don't need this pipe 900 bit anymore. So we don't have to remember that. Okay, and instead, we've now got the name and the size. The size and the name are the two things that are gonna be in this tuple. And so we're gonna go pipe followed by the size.

And then >> There is extra curly braces in the size. >> Sorry? >> There is extra curly braces around size. Okay, why did this one not work? Fix issues.png, fix issues, fix issues. Oh, okay, so remember how I told you earlier that parentheses do two things. They both group and capture.

So when I removed the parentheses, it stopped grouping, which meant the question mark now referred only to the backslash d plus. So actually I need the parentheses there. Okay, that fixed that. All right. Okay, and so sometimes that's missing. So we'll call that res after all. We'll call that res here.

Do that, okay. Let's see how that looks. Copy. Paste. Ah, cool, so look at that. They've got names, and you can change their sizes. Awesome. I think we're done. Are we done? Yeah, okay, so these ones here are too big. Let's fix them now. Yeah. Just now, okay, yeah, it's a stupid thing.

All right, so let's change his. All right, so let's delete that. So, Next step. Is to turn this into an app, right? Okay, so which bits do we need? So we don't need this head. Don't need that tail. Don't need the RGs. Chuck this inside here. Don't need that.

Okay, so let's restart the kernel and run it all just to make sure. Okay, so that was just that, I guess. Cool, all right, so a function for this. All right, so this is basically replace image. Place image, there we go. Jeremy, what that does, this seven cell seven applies the function to the DST contents basically.

It goes to the search through that string. Yeah, it's gonna look for this regular expression. And then each time it finds that regular expression, it'll call this function passing in the match object that the regular expression gets. Thank you. All right, no worries. So this is like a very versatile approach to doing just about anything you can think of with text really, search for regular expression and replace it with a function.

Okay, so if we have, okay, so let's create our function which is gonna be fix images. Okay, we're gonna be passed in a source and a destination. Okay, and this, if you haven't done this before, you might be surprised to discover you can define a function inside a function.

And the reason I'm doing that is that the first thing we're gonna do is we're gonna search for We're gonna search, we're gonna create this dictionary, right, of things to look for. And then this function here refers to that dictionary. So this is a function that kind of only makes sense inside here.

And then we're going to return this, right? Turn this. So we should now be able to print fix images passing in our source and destination. There we go. Great. So let's install Gradio. Actually, we've got the latest version by using minus U for upgrade. And I haven't used Gradio much at all, except when we did that lesson.

So I've forgotten everything. So I might need some help with this. Where are we? Yeah. Okay, so we import Gradio. Gonna create interface. And the function is fixed images. Oh, okay, let's just talk a while. Okay, now what's this input thing? Inputs is sketchpad outputs. Oh, I see. We can just say label docs.

Is there a different kind of label for like a large bit of text? Should be like a text box or something like that, maybe. Yeah, something. Here we are, text box. Great. Here we are, max lines. Yeah. Okay. Inputs, wait, and then do we. Okay, so if we pass a string, it's gonna construct it.

And not like otherwise we construct it manually. Is that how this works? >> It said that there's a shortcut if you put just text, it would work, I think. If you go to the, I think I saw it when you were scrolling. I string shortcuts. >> Oh, text area would have seven lines.

I see, I see, I see. Which isn't that many, so let's just try to make it their way. So input is. That. And output is that. Okay. And they've got that new grid flexboxy thing we might be able to use to get one under the other cuz we don't really want them side by side, do we?

Okay, so. Is there a way to upload a file? An image there is. Oh, wait, here's something called file, a file for uploading a generic file. I guess he's probably gonna copy and paste it from the forum. So maybe we should just do it like that too. Yeah, let's just do it here.

Can we still run stuff? We can, it's nice. Cat source.text. Oh, source and output, that's not right. We need two things to pass to fix images. So does that mean we put square bracket here or something or a dictionary? Inputs, string, component, words and strings. Match the number of parameters.

All right. Okay, so that's our source. That's cool, that's named them, that's nice. That's our destination. Yes, submit. Cool. All right, that seems to be working, doesn't it? So for, all right, so Gradio needs a script. So I guess we go to spaces first, right, hugging face spaces. I've forgotten everything.

And we create a space. Okay, and we call it a Daniel image fix. Right, it's a Gradio space. Okay, clone. You could just create the app file right there if you wanted to. Create the app file. In the UI, I don't know if that might be easier. Oh, can you?

How do you say something? Is there a hint to create the app.py file right in your browser alternatively? Oh, I didn't know that exists. Cool. Yeah, I guess it's kind of like GitHub only, so just- Yeah. Yeah, yeah, absolutely. Okay, so we don't need that stuff. We're gonna need that.

We're gonna need like a requirements.txt or something, don't we? Okay, so we commit this. Does that look right? Is it a requirements.txt we need? What is the thing to get? Yeah, I think so. Yeah, requirements.txt. And I think you just need to put fast score in it. Yes, okay.

And it automatically have Gradio. Name it requirements.txt containing fast score. I love doing this stuff just through the web GUI. It's just so wonderfully lazy. Okay, and that should be it, right? Yeah, I think so. Just, yeah, it has to build the app. So, yeah. Okay, it says it's done.

So, refresh. It says building. Because I think it builds for each commits, then you probably build when you committed the app.py and then it's building again when you commit it. Yeah, I just want to say that I want to say the latest logs, you know. It's got secrets. Yeah.

I like the way this stuff's all getting kind of standardized now around this idea of just like some key values to all secrets that you can chuck in there. Everything looks pretty similar, doesn't it? This is annoying. Runtime error. Okay, so hopefully that means we've got new logs we can see.

Oh, space not ready. Oh, that's not very helpful. Logs is now empty. Great. Can you try rerunning the building process so like understanding is restart the space it says. Okay. Or I guess the I don't know the difference between the factory reboot or the restart. Let's hear that your space could use a GPU.

What does that mean? Is that a thing? I don't know. Like I think that provided if you like email them or something like that it's a custom kind of thing. Oh, all right. I don't like emailing people. Case by case basis. Makes me feel like I'm being judged. Is it happening, I think.

Yeah, it's a little slow, I guess. Yeah. I want to ask how long do you plan to keep this live coding running? Is it just indefinitely? Yeah, I, I've got a plan, actually. Okay. I hope you guys don't think it's too crazy, but I'm just one moment. Okay. All right, so why is it still building?

Yes. So hopefully, you know, I'll get the course out in a couple of weeks. At that point, I'm thinking of like resetting this as a walkthrough in which, you know, things are actually better organized. And so I hope you guys can still join. I mean, it will be stuff you're already familiar with at this point, but certainly be helpful to have a nice to me to have familiar faces and people who can help.

So hopefully, that'll be a lot more people because it'll be open to everybody. And over a period of a few weeks, you know, we'll catch up to where we are now as a group. But for the couple of weeks before that, I'm planning to do a complete change, which is to do two weeks of APL.

So I don't know if you guys are aware of APL, but APL is just about the world's oldest programming language that's still widely used. And it's actually, we talked about notation earlier, it's actually a, it's actually a notation. So APL was originally developed as a notation, not as a programming language.

And at one, Iverson won the Turing Award, which is kind of like the Nobel Prize of computer science for it for this paper about it, which was written about 20 years after he created the notation. APL is a shoe. So the most common, why is this not working? Oh, because they're not using Windows.

I have to press that. So the most widely used APL implementation, there's a lot of them, but the most widely used one is called dialogue. And yeah, it's basically, it's basically math. Okay. Okay, looks like math. Imagine if you started with math, which itself has been developed over hundreds of years by very smart people.

And then one of the smartest people in the world being Ken Iverson, then took everything from that and combined it with tensor analysis ideas from physics, which have been developed by mainly Albert Einstein and many other people. And then combine that with ideas from computer science, and then have a large group of people continuously work on that from 1960 through to 2022.

So it's kind of 60 years of continuous development, and that gives you APL. So just to give you a taste. In math, to add up a series we use capital sigma. And capital sigma means only one thing, it means add up a series. If you want to multiply together a series, you have to use something completely different, which is capital pi.

APL instead has this idea that says, you can take a function like plus, and you can modify it using something that they call an operator so plus is a function slash is an operator doesn't mean divide, divided by means divide. And this operator, what it does is it takes a list.

That's a list. Right. And it inserts this between every pair of things in the list, which is the same as sigma. Right. In math. And so here's how to do the same thing as capital pi math. Right. So for example, here's. So then there's a bunch of other symbols.

Right. So for example, a symbol which actually finds it way. So lots and lots of ideas from APL have found their way into other programming languages. One of them is a lot of programming languages have something called Iota, which means the same thing as range in Python. Say Iota six.

It means almost the same thing as range. It's a range plus one, if you like, rather than zero to five is one to six. And this is the this is how sequences and series are defined in math. We in math, we start at one. So if I want to do factorial, right, I could do apply time slash sorry, apply time slash to Iota six.

So that's going to take one, two, you actually read right to left in APL. So that takes this series here and sticks times between every pair of things in it. So, 1 times 2 times 3 times 4 times 5 times 6. You got the idea? And so, I'll give you an example of another operator.

Backslash is the same as slash, except it basically, it's cumulative. It shows me the results as I go. So, this is 1. 1 times 2. 1 times 2 times 3. 1 times 2 times 3 times 4. 1 times 2 times 3 times 4 times 5. 1 times 2 times 3 times 4 times 5 times 6.

So, it's basically, yeah, it's a notation. It's built on mathematical notation. Can you handle a compass number as well? Yes, absolutely. Yeah, absolutely. So, complex numbers are written with j, a complex number. And so, one of the interesting things about APL is every function, well, nearly every function, maybe every function, has both monadic and dyadic forms.

The dyadic form means it takes two arguments, one on the left and one on the right. So, here are the dyadic versions of plus, minus, divide, and times. But there's also monadic versions. And so, for example, so, if I wave my mouse over any of these, it tells me, so, the dyadic version of plus is plus, obviously.

The monadic version is conjugate, which is a complex number thing. So, the conjugate of real number 2 is 2. The conjugate of the real number 2y plus 3 is 2i minus 3. So, yeah, it's, yeah, it's kind of, in some ways, a superset of mathematical notation. And so, yeah, it's not just plus, minus, times, divide, but see all these different things at the top?

It's all of these as well. Some of which you'll recognise, like epsilon, which, as you would expect, means membership as dyadic. That also has a monadic form. That's why, you know, so, it does a lot more things than normal math notation. And so, some of them, like, are really quite interesting.

So, for example, there's something called upstyle, which is, looks like this. And it returns the maximum of those two things. Now, where that gets interesting is, what if we do maximum slash? What did that do? Well, that did the maximum of 4 and 3. That's right, the maximum of 5 and 4.

And then, it was the maximum of that and 6. And then, the maximum of that and 4. And then, the maximum of that and 3. So, in other words, it's 5, upstyle 4, upstyle 6, upstyle 4, upstyle 3, which, when you think about it, is the maximum of the list, right?

So, a lot of the kind of things that in normal math notation, we have to, like, invent something in the paper as we go, or whatever, in APL, it's this kind of, like, natural extension. So, yeah. So, I thought it'd be fun to have a couple of weeks of exploring this.

And it's actually very helpful for PyTorch, TensorFlow, and NumPy programmers, because those ideas were, in many ways, stolen from APL. So, for example, just like you can do an APL, a number plus a list, you can do that in APL, but APL invented it. Right? And does it in kind of, like, often more interesting ways.

One of the fun things about APL is defining functions. Things tend to be a bit more consistent than a lot of other languages. So, in Python, for example, you define a function with, like, kind of a unique, you know, syntax. In APL, to define a variable, you use arrow.

And to find a function, you use a variable as well. It's just that the function goes in curly brackets. And you can pass one thing to the function, in which case it'll be called omega. Or you can pass two things to a function, which case it'll be called omega and alpha.

So, if I want to define plus, I would go alpha plus omega. And I now created my own operator. And you can use any Unicode symbol, so you can actually build up your own notation. Right? And so, it gets kind of pretty interesting, because a lot of, like, for example, there's an operator called power, which repeats a function n times.

And so, for example, you can define exponent literally as repeat power n times. And so, then you can, like, come up with your own versions of repeating things a bunch of times in ways which aren't necessarily in math, but might be quite helpful in whatever you're doing. Anyway, so that's my plan.

What do people use APL for nowadays? Honestly, there's two main areas. So, APL is one of a class of what's called array languages, of which there's three main ones in use, APL, K, and J. The array languages are most commonly used in hedge fund trading, which is partly a historical thing.

That's where the money is, I guess. And so, that's a group of people who don't care about trends as long as they can make money. So, when they kind of realize this is a really good way of expressing mathematical ideas, they kind of really dived into it. And in particular, Arthur Whitney, who helped create APL and went on to create K, he developed a kind of a extended version of APL called A+ at Morgan Stanley.

So, Morgan Stanley did a lot of stuff in A+. Yeah, so, nowadays, K, actually, there's a whole database built on K called KDB, which is considered perhaps the fastest database in the world for a lot of things. The whole K implementation is so concise that it fits in the cache on a CPU, which is pretty amazing.

Because, as you can imagine, with this kind of expressiveness, you can often write pretty sophisticated programs in one or two lines of code. Yeah, it's also used in kind of like legacy big business stuff, because it's been around a long time, you know, but I don't think that's a very interesting use of it.

But then, like, it's starting to get popular, I mean, popular, niche popular again, just as, like, people interested in math and notation, you know. So, some of the ideas have made their way into mainstream math. So, for example, something that, you know, pretty much any working mathematician will be familiar with is Iverson brackets.

This is a type in Iverson, it says Iverson bracket, right? Which is basically the idea that you can put a Boolean expression and make it one or zero, and once you make Booleans ones and zeros, you can manipulate them in mathematical ways, you know. And so, that idea comes from APL.

And so, for example, which of these things is greater than the corresponding thing in, probably all that, that's not very good, in iota five rather. At least on my end, I cannot, oh, okay, because you're at the bottom, so it's getting a little bit covered by the, in Zoom.

Is it okay? Yeah, okay, I see that line fine, yeah. Cool. Yeah, so, you know, once you recognize that you can do things like this, and if you return ones and zeros as the truth values, you could be like, oh, like how many times was that true, you know, stuff like that, you know.

Yeah, so anyway, so like some of the ideas have made their way into math and coding and stuff like that, so maybe that's kind of the main thing it's used for in some ways, but my interest is just kind of to look for ideas and things like that, I guess it's kind of a useful thing.

Yeah, a lot of people, including me, who have spent time with array programming, feel like it's the most mind-opening thing they've done in computer science, because it's like going to this alien world where they've spent 60 years going in a different direction, and suddenly realizing like, and a lot of the smartest people who have worked in computer science were on that path, not our path, and it's like, wow, what have they been doing?

So like, I actually find it very enjoyable, because you end up reading interesting papers from the 60s and 70s and stuff, and it's just like, oh my god, you know, and so for example, I don't know if you saw, but Mathematica came out with a new version of Mathematica today, which is not very helpful.

Um, So the latest version of Mathematica, which yeah, came out yesterday or the day before, basically says, oh, we've invented this new thing called Threaded. And anyway, it actually turns out if you read it, that it's the same thing as what's called the rank conjunction in APL and J, which has been around for decades.

So it's like one of these things where it's like, oh, you know, ideas that are decades old are sometimes only just finding their way into modern languages. Yeah, like Mathematica. It's also a really, it's a really great way to learn math or big parts of math. Yeah, because as you go through it, for example, that's a writer's question, does it have complex numbers?

So as you go through it, my plan is to kind of go through each glyph. And so some of those glyphs are going to be like, okay, well, this is the conjugate of complex numbers. What on earth does that mean? So like, you know, really gives you a chance to explore that.

And then in particular, the language called J, which was developed by the developer as APL as a kind of getting all the best ideas from APL over the decades and making them better, actually comes with a whole bunch of, they call them labs, which basically take you through really interesting mathematical ideas like polynomials, you know, and all this stuff like using J as the notation.

And I prefer that to normal math notation because I already always know exactly what it means. You know, it has a totally consistent meaning. And yeah, so yeah, so that's my plan for next week. Actually, I come across PDP before my old boss is work for Morgan Stanley. And I think they still have the free version.

Maybe I need to take a run with the memories less than 4G. They actually have free version as well. They do have free versions now. And he, last time we tried to do some IoT applications, so contact all the different sensor for machinery. And they come by and actually better and the performance faster than Panda as well.

So he do all the configuration in KDP and then give me the file and then I start doing the visualization. So yeah, but he used to tell me take six months to actually train a person to actually can read it. So you can get us up and running. Yeah, yeah.

Well, you know, we'll just get up and running. So I've actually, so like, I don't know much APL at all, to be clear. So this is not like teaching you this is a shared exploration. I've done a little bit of like a little bit of J before. And then two or three weeks ago, I reached the point in teaching my daughter and so I teach my daughter and her best friend math, I tutor them.

And we reached the point a few weeks ago where we were up to doing sequences and series, you know, like sigma notation. And I started trying to teach them and they had no idea what I was talking about. And I was like, I always thought of sigma notation as actually being extremely easy, because like, if you explain it to me, you'd just be like, oh, well, it's like this list comprehension with some on the front, you know, it's like, it's a very, it's just like, oh, that's exactly what it is.

But of course, they didn't have any of that kind of idea of indexing or anything. So, you know, kind of trying to say like, Tn equals Tn minus one plus one is a arithmetic sequence, you know, or whatever, you know, like sigma i equals one to six of i.

They're just like, what's Tn? What's i? Like, what's going on? So then we stopped trying, you know, there's like one failed lesson. I was like, okay, forget all that. I'm going to teach you APL and NumPy instead. And so we did like three lessons of APL and NumPy. And then I said, okay, so here's that thing, sigma, you know, i equals one to five of i.

That's this, that's plus slash iota five. And they're like, oh, oh, that's all. Okay. You know, or, you know, in NumPy, Np, well, I didn't use Np dot because I use wildcard import. Oh, that's all. So, yeah, so that's why I've been like re-engaging or engaging more deeply with APL.

But I think it's beautiful, you know, I think it's just a beautiful, a beautiful notation. And it reminds me in some ways of learning Chinese, like once I started learning Chinese, it was like, oh my God, there's this whole culture of thousands of years. Num, you know, or APLs like that, but, you know, there's this whole culture of 60 years.

You know, there's this whole. And recently, I tried to convert some MATLAB mathematical formula into Python, actually quite painful. Yeah, doing some signal processing. Cool. How did our thing, oh, look, there's a thing here. So please try it and tell me if you find anything broken. I'll put it in the chat.

Oh, why is there an M there? That's better. All right. Thanks, all. Bye. Thank you. Looking forward to being here. All right. Awesome. Bye.