 Hi there. I'm Jeremy Howard from Fast.ai and I'd like to tell you a bit about why I like Jupyter notebooks and help you maybe find some new ways that might help you really like them as well. I feel like this is kind of a dangerous thing to say. I like notebooks because every time I do to a serious software engineer type they tell me all the reasons that I should not like Jupyter notebooks and they kind of act like I must just be ignorant and don't understand the better ways to code. But actually I've built a lot of good stuff in Jupyter notebooks and I've been coding for, gosh, about 30 years over that pretty much every day. I've used a lot of different IDEs, a lot of different editors and Jupyter notebooks seriously makes me at least twice as productive and I have a lot more fun. I've built a number of popular software libraries like these ones in Jupyter notebooks, in particular Fast.ai, which is perhaps the most popular PyTorch Deep Learning API other than PyTorch itself I guess, and is very widely used at many companies, many researchers, many universities and so forth. One of the cool things you'll see in the Fast.ai library is that actually the documentation which you see here it's got all these examples scattered throughout it and most things like links to source code and links to papers and links to other parts of documentation and actually you can click on any part of that documentation at the top and the opening colab button and if you do that then suddenly you'll see that entire documentation appear as an interactive experimental playground you can play with yourself because you see all the documentation is written in Jupyter notebooks and actually not just the documentation but all of the code itself for the library and all of the tests and they're actually all in the same notebooks so if you start looking at one piece you can see everything you can see as you see here the implementation of this combined cosine scheduler you can see the examples you can see the tasks you can see the documentation and you can start playing with it straight away to experiment with some different values and see how it works look at the inputs and outputs and so forth. I think that's really cool. The way that I do this is by using something called nbdev for notebook development nbdev is a really amazing project which I'm going to tell you a lot about at the end of this talk the second half of this talk but basically what nbdev does is it lets you create Python modules directly from your notebooks you can export changes from your editor back to your notebook if you want to change things in an editor or IDE directly it automatically creates searchable documentation it automatically creates pypy and condor installers it will run your tests in parallel and the tests are in notebooks it will handle continuous integration it will handle version control stuff and so forth it's really really nice. I write all kinds of stuff in notebooks and here's an example of a little server I made and so I made this little server and it's a github or a git webhook server and the nice thing is that I haven't really done much stuff directly using pythons built-in HTTP handler classes before so I started experimenting with them and I did so in a notebook and as I experimented I took down notes for myself and I started creating examples and little tests and this now becomes part of the documentation and the source code and the tests of the library I ended up building which is called fast webhook so you can see that you can kind of you can write any kind of code in notebooks and you can end up exporting it into a real library and now anybody can download fast webhook and then they can see not only the final result but the process I took to get there and understand my thinking understand the apis I'm using understanding the parts of the Python standard library I'm using because it's all documented in this process so a lot of other people are now using nbdev and one of the best comments I've seen is from Hemel Hussain from github who said tests docs and code are part of the same context and are co-located so this is what happens when you write with nbdev and he says there is no other programming environment that exists like this that I'm aware of you can even make notes to yourself about why something works the way it does very easily while you're running the code and it isn't an afterthought this is fundamentally why I have a problem working in anything besides nbdev because not only does it make the code more approachable to others but forcing you to write docs actually forces you to think about the code more and my personal projects at use nbdev I often refactor my code to be simpler and better after forcing myself to explain it and I have the exact same experience it really makes a difference to my workflow and a lot of this is really thanks to the underlying jupiter notebook system which nbdev sits on top of silver gutter and I silver is my co-author on fastai he is also my co-author on the deep learning for coders book which has been incredibly popular including some big names you probably know about who really like it this whole book was written entirely in jupiter notebooks and then we exported it directly with a single little script we wrote into ASCII doc set it off to O'Reilly and they published it into this beautiful book and a lot of people have commented on how nice this book looks how how good it feels it's got color and nice little icons and all the stuff you'd expect a really nice index and so forth so we've created a book that we're really proud of and a lot of people really like and if you want to write a book yourself as well you can you can pip or condor install fast doc which silver and I have made available this is the exact same thing that we use to make our book and you can run a single command fast doc convert all and it will convert all of your notebooks into a publication quality book or at least the ASCII doc source for it which you can then send to a publisher or you have to do is write the book here's another example of something that we created with jupiter notebooks which is a very popular course and of course people really really like nearly everybody seems to like this course which we're so proud of because we spend a lot of time trying to get it right and the whole thing is actually or nearly the whole thing is actually taught in jupiter notebooks and the students then take these notebooks and what we do is we clear out all of the pros and all of the outputs and we ask the students to try to go through the notebook and figure out what's going to happen next and why are we doing this it's a great way to kind of force people to think about like oh did I really understand this do I really know what's going to happen and then they can run it and check and if the answer is different to what they expect to then they can experiment it's a really terrific way to learn and pretty much all of our students have said that once they get into it they really adore it they really find it terrific overall the key thing I guess that I like about jupiter notebooks is that they support literate programming. Literate programming is something that I have been fascinated in ever since I read about it in the early 90s developed by Donald Knuth the famous computer scientist who describes it as a methodology that combines a programming language with a documentation language thereby making programs more robust more portable more easily maintained and arguably certainly I find more fun to write the main idea is to treat a program as a piece of literature addressed to human beings rather than to a computer and this is certainly the way that we now write code with notebooks and nvdev and I think we actually go beyond literate programming to what I call exploratory programming where we're using our notebook as a kind of a journal like a scientist's journal and then when we're done we'll go back and we'll try to clean it up as best as we can and we'll make that part of what we publish so for example here's the actual source code from nvdev itself right and at the very start Silva and I didn't know much about what is a Jupyter notebook really behind the scenes and as we started exploring and realizing it's just json and printing it out that became part of our documentation and source code and you can see we start to create and export functions as we go along and that becomes part of the library so then when somebody else comes along and wants to contribute to nvdev or to any project written with nvdev they don't really need a huge amount of handholding and helping them get involved because they can see not just the final result but the process to get there and the thinking and the choices that were made along the way because they're all part of the notebooks and they can even see the the tests and see how the tests are related and it's all there in one place so overall notebooks give us a live coding environment it's live in the sense that you're working directly programming against those live objects the actual the system that you're building them in has the state has the the actual current state of all of the variables and all of the systems in memory and you can directly interact with it this idea goes back a really long way one of the most famous examples of a live coding environment is small talk this one here from small talk 80 and as you can see here as the code is running things are actually happening on the screen and anybody involved in small talk in those early days will tell you that this was a critical part of why this was such a productive system and why it was such a loved system and a lot of people say there's never really been anything like small talk again we're kind of almost rediscovering things from decades ago there are other interesting examples of live coding here's a great one from somebody called Sam Aaron who actually does live coding as performance here is him writing music with code in real time so i think that's pretty cool here's something which is even cooler this is Brett Victor a brilliant designer and a brilliant thinker showing a real live coding environment he created which allows him to create games in a whole new way i mean not just games you could use this for so many things but here's an amazing example using it to build a computer game to bounce off my turtle pause the game and now hit this button here which shows my guy's trail so now i can see where he's been and when i rewind this trail in front of him is where he's going to be this is his future and when i change the code i change his future so i can find exactly the value i need so when i hit play he slips right in there so i'm going to say i've never managed to build code in a way where the people watching it went whoa and then started clapping uh it's certainly something to aspire to and you can see how much people really love this idea of actually interacting with a live coding environment Brett Victor's been very inspirational one of the things he inspired was chris latmer who is the guy who created lmvm he created swift and he built the amazing playground system which as you can see here as the code is running you can actually see what it's doing and you can even plot it and so forth another great example of a popular and important and powerful live coding system so i was so proud when actually chris himself said he thinks that nbdev is a huge step forward for programming environments and so for that to come through chris was a huge validation for us that somebody we really admire thinks that we're absolutely going in the right direction most people however are not using this kind of live coding environment despite the decades of work that's kind of gone into these kinds of systems and the productivity that we've found comes from it here's how a lot of people code and i'm going to give an example here you'll see why in a moment of a very successful coder named Joel Groves this is Joel here and he's good enough to actually do coding which he puts out on the internet if you want to watch and i watched it to see exactly what this looks like and what he does like a lot of people do is he has a what's called a line oriented ripple down here this is something where you can type in a line and it returns a line and then the rest of it is a kind of a standard editor ID this is vs code which is one of the best or maybe the best editor around so what happens is he codes you can see here that he has to kind of go back up to find something he's done before it's the wrong thing and then he has to edit it and then he's got an assertion error now he has to go somewhere else and then comes down here again now he's getting this kind of weird situation of some state that's come from the code and some state that's come from the things he's typing and now he's going back up here and trying to edit this and now bringing it back down here again he's doing the error you know as i watch this i find this painful you know i don't want to write code like this i kind of feel like this picture is jolson this is too much but i feel like a lot of real programmers tell me that you know this is how you should code and it kind of feels like they're saying hey you know we should go back and use line oriented ripples to everything like editing we're used to edit with ed the unix editor which was a line oriented editor and as you can see the basic approach is exactly the same as what jol was using for manipulating python now these line oriented ripples um you know it's it's not a great way to edit text very sure of us use ed nowadays and i would argue that it's not a good way to work with any kind of code objects it is linear there's a reason that we have line oriented ripples and that's because we're used to code like this if we enter maximum slash y we get the maximum element in the vector y so you can see here he is typing one line at a time and it's printing one line at a time by the way this is apl which is decades ahead of his time and still one of the best brilliant programming languages in the world um but i would argue that we should be moving beyond the type a line and have a line printed approach that was developed for this kind of coding so these kind of um editing environments uh like a vs code um vs code is a brilliant piece of software but i refer to as a dead coding environment because you're not interacting with live code and that leads to errors you get um this this kind of gap between the system you're working on and the final result you're creating so Joel actually wrote a fantastic book um which despite being fantastic it has some errors in it and the kind of errors are very interesting this is from his errata page the errors that say the code you can't actually run it right so this this line of code doesn't work and this line of code doesn't work one of the really interesting ones was not only this line of code doesn't work but hey you've got a code repo where it does work and so there's this kind of like gap between the actual code you're doing and the book that you're writing and then they come out of the sink and your readers end up confused because the code doesn't run all the code in our book runs um not because we're particularly brilliant but just because we ran it all in a notebook and so all the outputs you see are the actual outputs that came out of the notebook now of course one of the libraries might change or there might be a breaking change to python or something there could be something which could cause it at some point in the future to break but at the point that we wrote it and as far as I know right now still um the code is correct and it works because as I said it's the code that will be actually ran there was no it's not a dead coding environment it was a live coding environment we used to create the book and the book directly comes from and is that code so why am I talking about Joel's book and Joel's um coding approach that's because actually he a couple of years ago did a brilliant presentation called I don't like notebooks um and in this presentation um he explained why he thought we shouldn't be using notebooks and actually notebooks are not the right approach to building effective software or doing effective teaching and the reason I feel like I need to talk about it today is because he is such a brilliant communicator and such a funny guy um that this presentation has become incredibly influential and pretty much any time I say I like notebooks somebody will say uh that's not a good idea haven't you seen that presentation where that guy explained why they're terrible so I really feel like in order to tell you why I like notebooks I also have to tell you why Joel is wrong um which he is I really feel like he's wrong I've got a lot of good stuff in notebooks and as you'll see I think the points he made are based on misunderstandings or at least sometimes that now out of deck um because his slides are brilliant I'm going to use a lot of them and also so you can see exactly what I'm responding to um whenever I use his slide I'm going to show this little icon in the bottom right hand corner um you'll see it the next 12 slides are actually all from his presentation I haven't edited them because I want to make sure you see exactly what he showed and one of the things he did say in his presentation is I am not a notebook expert which is great it's nice to be self-deprecating and to kind of have that caveat but he's still expressed very strong opinions and people still as I said really think he must be right they tell they tell me that I am making a mistake to think that I like notebooks so I was actually worried when he first told me that he's planning to write the talk that he did because I know he's a brilliant communicator and I know he's really funny and I thought uh oh a lot of people are going to listen to this and say um oh I guess we shouldn't use notebooks because Joel has made a compelling case that we shouldn't and this slide is actually from his presentation he actually said in his presentation hey this look at the look at what Jeremy said I guess he thought it was kind of funny that I told him don't write this presentation and he wrote the presentation and so now I feel like I have to come back and say like okay let's let's set the record straight here so here's what he said he said he had a lot of strong opinions I don't agree with any of them but here they are he said notebooks discourage good habits he said notebooks encourage bad habits he said notebooks encourage bad processes he said that notebooks hindu ripro oh hindu reproducible and extensible science uh he said that notebooks are a recipe for poorly factored code uh he said that notebooks make make it easy to teach poorly I don't think it's a notebooks fault that that guy's going to get over the head I don't do that when I teach with notebooks by the way he said notebooks make it hard for me to teach well so um he didn't just state these he gave reasons and here are some of the key reasons or the key reasons that he expressed um the first one he expressed uh was that notebooks have tons and tons of head and state that's easy to screw up and difficult to reason about um which is strange I I don't find this myself um and he made the point that uh notebooks or he says are dangerous I don't know if I agree they are dangerous but he thinks notebooks are dangerous unless you run each cell exactly once in order I was like oh my goodness how am I going to do that uh wait Jupiter has a single button you can press to do that it's actually not that hard if you really think it's so important to run each cell in order you have a way to do so um personally I think it's actually really really important to have this ability to go back and fiddle with things to change things to see what happens I like having the ability to go back and run in order but I also like having the ability to actually as we discussed manipulate the live coding environment in real time to experiment and to say what if that's a critical part of this but you do need a way to ensure that in the end the whole thing works uh and not only does Jupiter have a couple of ways to do that there's restart and clear output so it should be restart and clear output to be restart and run off made a mistake there and in cell there's also a few options such as run cells to here or run all cells um and nbdev actually has something which runs all of your notebooks all of your cells in order for you for a whole directory that's the main thing I use um another concern he stated was that um that you can't copy and paste code and outputs from a notebook into Slack or he also gave the example of that pull requests and issues in um GitHub now this is an example of trying to do things the same way you've always done them without thinking about what's the actual problem you're trying to solve now the actual problem you try to solve is to say here's what I'm trying to do please explain why this doesn't work or here have a look at this example I'm showing or whatever and here's how it actually looks it's actually way better than cutting and pasting into Slack when we get a pull request or an issue here's a bug report co-lab notebook reproducing the behavior now I click on that and I get a whole notebook fully self-contained where I'm not just seeing this person's claim or I type this and this happened but I can actually try it and that means I can then actually try to fix it right there and then um and this is particularly helpful in because all of the fast ai documentation all of the fast ai book and all of the fast ai courses are also available as notebooks so people can use that as a starting point and I could or I can say like oh did you try the code in the book if you have a non-working example could you modify the book notebook to show us how yours doesn't work um and so forth so rather than saying how do I copy and paste into Slack or GitHub the question should be how do I understand the problem that a user is having or understand the idea that a user is telling me about and the answer to me is by providing an actual live coding environment I can see that in and it's so easy to do with Jupiter. Something else I really like about Jupiter is you can use something like what I really enjoy at Review NB to look at pull requests and pull requests don't just show me the code that's changed which is fine they do it's very nice but they also show me the outputs that have changed and the documentation is right next to it so here's somebody change to test right and rather than thinking oh I wonder if those scales are any good and then having to go back and load in their PR and run it and then have a second version of the code and run that and compare the two in Review NB I can see them right next to each other and I can say oh yeah this actually does look like a more clear example to me and I can see the documentation is right next to it and I can see exactly what's going on there's lots of ways of sharing notebooks another is to press this button this is the gist of button here's a notebook that I created and you can copy and paste images directly into a notebook so here's one of those copied and pasted in and if I click that button then it automatically gives me a shareable gist URL so I can paste that into Slack that's at least as easy as copying and pasting from iPython and of course I get the benefit that I'm copying and pasting not just text but pictures and you know a lot of us are working with things other than just text nowadays we want to be able to show plots you know histograms of things and analytics we want to be able to show pictures we can be able to show videos we're not just working with text all the time and so with something like this you can really show a much more complete example a lot of the time it's really nice and easy to do another concern as you can see we still got our little pictures down here there's still Joel's code sorry Joel's slides another concern he had was that he thinks that notebooks are harder to reproduce and this one he didn't really explain why he thought that way and I don't fully understand the the thought process here all of the same ways that you can use for dependencies in regular python libraries like requirements.txt or environment.yaml or whatever or setup.py you can use exactly the same thing for notebooks but in practice though you know notebooks I really love because when you provide a notebook you can just provide a cell at the top which creates the environment you need so for example you can open any chapter of the fast AI deep learning practical deep learning for coders book directly on colab by clicking on a link without any installation and the first line or the first cell installs everything you need and away you go so really to me I feel like notebooks make it much easier to ensure that you have something that's reproducible and you can also see what the programmer did step by step to really make sure that what you're seeing is what they were seeing look you can certainly make bad notebooks you can certainly provide bad reproducibility environments but I don't think it's anything to do with notebooks themselves you know it's to me this is an environment that actually makes that easier to do well so the other thing that Joel talked about quite a lot was this idea of good software engineering and he made some pretty bold claims that good software engineering can't be done or is extremely hard to do in notebooks and he used these characters quite a lot these mirfs and basically you know he's saying like you should all follow the rules of good software engineering but you know it's kind of like this idea that you should copy and paste code and outputs into Slack you know that's how people might have done things before but you know maybe the rules of software engineering in a dead coding environment or in a line oriented rep or or whatever are not the same particularly you know compared to a dynamic language in a live coding environment and also the rules for a data scientist who's doing research and their focus is on speed of iteration and on rapidly eyeballing visualizations to see whether they're say their microscopy images are actually getting easier to see or harder to see to take an example of a project I've been involved in a lot recently these are kind of going to be different to the rules the so-called rules of somebody who's creating a crud app or a e-commerce app to send a payment to a Stripe API so I think we've got to be careful about the idea of rules and think about domains and domain expertise and environments so here's another slide from Joel and his concern was that notebooks are not good for modularity and he's giving example here of some of his code which he's saying is very nicely modular I mean sure but why can't you do the exact same thing in notebooks and in fact fast AI that the library I told you about that we wrote entirely in notebooks actually the modularity is so good that we have a peer reviewed peer reviewed paper about the approach to modularity that that we took and about how the kind of decoupled API that we created I'm sure it's not perfect but a lot of people have used it and have liked it and people are studying it as an example of modularity it's definitely not the case that notebooks somehow make it impossible or even difficult to create modular code I'd say the same thing about testability I don't know if this is from Joel's tests I guess it probably is again this is one of his slides he's showing here examples of tests tests are great but in this kind of approach to this kind of regular approach to coding and these dead coding environments the tests live separately to the code that's being tested and it's very easy for somebody to look at the code and not even notice the tests or they'll have to kind of flick back and forward between the two and they don't really it's not easy to connect which test is really working on which part of the code or else in notebooks and also with nbdev in particular the tests live right next to the thing they're testing all right and they'll include pros explaining what it is they're testing so here we've created a thing called unbuffered server I think it was in the cell above the one I took a screenshot of here and so here I've created a test handler to test it that sends the response and writes okay and here's something that checks whether that starts a server and then checks whether it actually receives that okay or not so it's really nice having the tests in the notebook and then nbdev provides a way to run all the tests across lots of notebooks and report on the overall result and that can be run in continuous integration and nbdev gives you that actually out of the box if you use the nbdev template you get this kind of continuous integration testing for free you don't have anything to do it just works which I think is super cool. Another of Joel's concerns from his slides is that notebooks somehow encourage a less sophisticated approach to learning so you hit shift enter to execute a cell and go to the next one maybe people just do that without thinking I mean it's possible people could could do that I would say even that is better than people just reading the text and having nothing to do but as I described actually what we do is we have a little script that just removes all of the pros except for headings and all of the outputs and and then we give this to the student and then they can run through each one and before they run it we say have a think about what this is going to output and think about why and think about why we're doing it and then if you guessed wrong you know or figured wrong you can actually experiment because you're in a live coding environment here so you can actually see well where did that go wrong and what actually happens so I actually think this is a great way of learning and a lot of our students have told us they think it's a great way of learning I don't think I've ever heard anybody say that this ability to work interactively in this environment is decreasing their ability to learn so another thing that Joel said and gave a few examples is that notebooks are way less helpful than my text editor which in his case is with Zora's VS Code and he said some things are easier demonstrated I'm going to show the opposite of his demonstrations which is actually that Jupiter is more correct and more helpful than his IDU so here's an example let's get a URL contents of a URL and if it returns something valid it's like something truthy then we'll return a otherwise we'll return one so this is obviously going to return something truthy so this should be a string and as you can see it's giving me IDE completion for a string VS Code saying code gisby completion for a number not for a string got bit length casefold conjugate okay so VS Code doesn't know because VS Code it's doing the best it can and it's kind of pretty brilliant you know given that limitation but it doesn't know Jupiter knows because you ran the code so it actually knows what you're working with and it can actually because Python's a dynamic language it supports this kind of dynamic introspection of what is actually inside b and what can b do and so that's what Jupiter can use so Jupiter is just really really really helpful because it can be really helpful VS Code does the best it can but it can never be totally correct it would literally be impossible without it actually trying to match the same stateful approach as Jupiter because Python is dynamic because it's not fully typed and even if you do use types for something like b above you'd have to use a union type you still wouldn't actually know what the type is so then Joel said okay here's what you could do to win me over and convert me to a notebook user he said give me IDE style auto complete well as we discussed IDE style auto complete is not the be all and end all it's actually not fully correct having said that Jupiter also provides IDE style auto complete if you give it types then it will figure out what you mean and if you give it functions like open that return a file again it will figure out what you need so we have IDE style auto complete he said give me real time type checking LinkedIn okay here is part of Fastcore library as you can see it's like a dozen lines of code and it actually gives you real time actually correct type checking so here you can see I'm calling foo which is taking an int and a string and if you pass it an int it's checking oh it does in fact fail all right and again it can do this correctly only because it seems you could only because it's actually running the code the approaches that most people are taking to this kind of type checking is my pi and my pi is not about 12 lines of code my pi is about a hundred thousand lines of code and it's complex code involving multiple different languages and it's never going to be correct it can't be fully correct because it's impossible for it to know exactly the types of all of your pieces of data because it's not actually running the code and python is dynamic with python the only way to know what something actually contains is to run the code also my pi means you have to tell python what every type is and honestly every other language is moving towards auto detection of types of figuring out what types are automatically particularly early movers like f sharp but nowadays even stuff like java c sharp c plus plus you can have like an auto type and it fixes out for you python is kind of moving in the opposite direction and if you want to go the my pi static analysis ide approach you're going to have to spend a lot of time doing manual typing another thing joll said he wanted to see to win him over is a better story around dependency management sure why not as i said notebooks can already support all the same approaches that that normal python projects can handle nbdev makes it even easier you can just add a line to your settings.ne with a list of requirements if there's some special one for pip and condo you can add those special ones for development time only you can add those and away you go that will automatically make all of those things be installed for you when you run the notebooks so we certainly have that um he also said he's looking for first class what is going on there first class support for refactoring code out of notebooks into modules and uh i agree this is absolutely critical and this is really the key number one first thing that nbdev does you start with some code like this and again this is some source code of nbdev nbdev of course it's written in nbdev it's a notebook and then it automatically creates an actual python project so those all exist joll did not expect that to happen he said the reality is you're not going to provide you with all these things and i'm not going to switch to notebooks so so be it um so hopefully i've convinced you that um there's no reason for you not to like notebooks and that uh it's not the case that real software developers have to use other tools um but actually notebooks really can be really great let me explain more about how and why this happens and to do that i'm going to focus on in particular nbdev and i've already mentioned the basic things that nbdev does for you um let's look more at how that works and exactly what we need to do um so here is an example of uh code uh in a notebook and you can see here that i've got an export comment so nbdev uses a small number like two or three different special comments to tell it what to do and this export says make this part of my python project uh this doesn't have an export um so it's not part of the python project now one of the things i like to do um this is another thing that joll talked about as being a problem for him with notebooks he said it's hard to do is splitting a class into separate cells and actually uh with um the faster libraries using um nbdev and fast core it's not at all difficult to do here's a class and i've just got the internet in it here and i can create it right and then later on i just use this patch decorator to add this method to this class and so this is actually going to impact the documentation as well the documentation of process comment will end up down here and the documentation of class in it notebook processor in it's going to end up up here and so it really helps the code reader understand things step by step each one has uh tests and examples kind of as it happens um and as you read through the documentation you can see each piece one at a time this is a really nice to me way to build up more complex classes um all of the um uh pieces of nbdev all get built out of a single simple little settings file settings.ini and it's really nice because you can provide all of the information just in one place so rather than having a version number over here and in it dot pi and over there and set up dot pi and over here in your documentation um you have it once and it's used everywhere ditto for your description ditto for your um source of your documentation and ditto for your uh get repo information it's just there in one place and then everything will use that for you you don't have to put it in multiple places and think about how to maintain it and synchronize it talking of synchronization not only can you start with a notebook and turn it into this code which you can then open in in this case they're open vim or you can open it in vs code or whatever you can edit it and your editor like vim or vs code and it will sync it in the opposite direction too and update your notebook and so some things are easier to do in editors like particularly kind of you know search and replace across multiple files and stuff like that um uh or if it's an unfamiliar code base it's nice to be able to use the tags to kind of jump across between files you can edit as you go and then synchronize back to the notebook um so then uh how does the synchronization work well there's two ways you can do it you can either put this is the last um cell in each notebook notebook descript and that will um take the notebook you're working in and all the other notebooks and convert them into um modules uh or at the command line you can run nvdev building um and so I I have a bit of I have this in every notebook that I use because it's kind of nice to stay in the notebook environment um this is more something I tend to do as part of my release process um there's a lot of little niceties that nvdev tries hard to make nice for you to to kind of make your code as correct and as um you know close to best practices as possible at least kind of our view of best practices one of the best practices that we think are important is done to all uh done to all is the thing that python provides for you where you get to list what are the exported symbols in your module uh if you don't provide done to all and nearly nobody that's not an nvdev user provides it um then it exports all the symbols not just the symbols which um or anything without a leading underscore not just the ones that you've um actually directly typed in as your code but everything you import also gets exported and that very quickly can lead to namespace pollution um but with uh an nvdev module because we automatically create a done to all for you which includes only the things that you requested be exported that means that you can see the imports for example from fastcore.transform which is part of an nvdev library there's just stuff from fastcore.transform or else if you look at um something from alannlp.nn.util you get copy, JSON, logging, default, etc you know this is not stuff created by alannlp.nn.util um and so because this is um uh built you know using the traditional vs code approach um it really is too much work to manually create done to all uh so the alannlp folks don't do it just like pretty much every uh other python library not all of them um tk for example um which comes with python does define done to all um which is nice but i don't know very many non-nvdev projects um so here's another nice thing with the documentation in the docs you can just put your symbols in Bactics and then when you create the docs which you get it's automatic um and it can be part of your ci system in fact that is by default um you can see it actually creates hyperlinks so nvdev knows how to actually look up each of these symbols and hyperlink to them even uh things like this which are part of like different libraries um so this is a really nice feature which allows you to help out your users um so that they can see exactly what you're talking about by jumping to other parts of the docs um and of course some things uh shouldn't be hyperlinked like these this is a parameter name um and so those will not end up hyperlinked um so the documentation which gets built for you supports you know all the kinds of features you might imagine a hierarchical menu to take you to any part of the documentation pages a table of contents for each page you can have badges opening colab headings links all that kind of stuff um so the documentation you know comes out pretty nice i think um so here's what happens you just run nvdev build docs and it takes a second or so it's all done in parallel or you can have something like a github action or whatever continuous integration system you use and call the fastai workflows build docs github of action um so then uh you can open those docs directly um as a notebook um uh and one of them is special which is the one called uh index dot ipie nv index dot ipie nv will automatically be turned into a readme dot md for you as well so no more worrying about trying to keep your uh files synchronized to make sure that your home page and your readme is saying the same thing now we actually do that for you automatically um uh we also of course make sure that it's not only the notebook but the home page on your documentation website and even your pi pi and conda descriptions will all end up showing you the same information from your index notebook so in this way because we're just saying build stuff in one place do it once and then we'll make sure that everything syncs up for you it makes it trivially easy to to create really nice user experiences for your users so for me even when i create tiny simple little projects i always do them in nbdev because that way i know that i can you know in a minute or two provide installable uh um libraries and documentation just in case anybody else is interested in using my work and often i find you know even for stuff that i think is pretty niche there's always a few people who are interested in using it too um here's an example actually um fast webhook which i mentioned before it's really just written for myself uh fast ai i wanted a webhook that would um send out a tweet anytime there was a release um but i did it um i wrote it in like two hours i guess and then i um just hit make release and because i made it from nbdev template it automatically created the conda package and the pi pi package for me and everything was all set up which is really nice um one of the challenges with working with notebooks on version control is you can get some really ugly diffs that won't even load in notebooks um uh nbdev will actually ensure that those diffs are turned into what i would call a notebook level diff which is to say it always ensures that your notebooks can be opened um if there's a difference only in cell outputs it just ignores them and just picks one because you know you can just rerun it um if there's actually a difference between you know in in a cell two people have changed the same cell then it'll actually show you the diff tags in a notebook you can open it up and jupydo and fix it up um all of your tests run in parallel with nbdev test nbs um using as many cores as you have um so this is a great way to ensure that every notebook runs from the top to the bottom and has the actual outputs that you're expecting um lots of nice little pieces like math equation support uh all the latex equations work nicely uh you use it in your markdown and it pops up in your both in your notebooks and in your documentation um we're using cat tech which is a really nice fast library um for that um and there are other things that we power as well not just um publishing libraries but nbdev also powers fast pages which is a increasingly popular blogging system where you can write jupydo notebooks and it turns it into a blog and this is really nice for anybody who is often trying to communicate technical content involving uh equations and or code uh visualizations no more um copying and pasting um uh gist center medium or copying and pasting you know outputs um you know plot outputs into files um when you can do the whole thing in a notebook there's nothing to think about it it just works which makes life very easy and as we discussed earlier fastdoc takes notebooks and turns them into publication quality um books um so i hope that you might give it a go and see why i like jupydo notebooks um you can just go to nbdev.fast.ai which is of course a um nbdev powered documentation site and um you can just click a button and uh it will create your nbdev repo for you and you can get started um thanks so much for watching and uh i hope that you try this out and find that you like jupydo notebooks too. Thanks