DjangoCon Europe 2019 - Lightning Talks Day 3
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Maloney, Curtis
Winterbottom, David
Godwin, Andrew
Wallroth, Tom
Bhimjyani, Harsg
et al.
Maloney, Curtis - Another view on handling settings Winterbottom, David - Heretical Django practices Godwin, Andrew - The Beginning of Real Time Wallroth, Tom - Deus State Machine: Yet another state machine Bhimjyani, Harsh - Managing Elasticsearch in Django like a pro N. N. - Django for Social Good Kolibri ...
 So I am from Namibia and I've been a high school teacher for the past three years. I've taught computer studies to learners of ages between 13 and 19. And right now I'm a full-time student and we are not there yet. Are we there? Okay. So, okay, so last year I was at JungleCon Europe 2018 and I gave a talk at the conference. And one of my friends was also an organizer at that conference. So when I went back home, I also wanted to be an organizer. Back home, I organized back on Namibia and I organized lots of Python workshops and events back home. I work a lot with high school learners as well. We organize a workshop, not a workshop but a conference for high school learners. So I was interested to learn how the international world organized conferences and I also wanted to be an organizer. So I wrote to the organizing team when I knew where the conference was going to be. And I would like to thank the organizing committee for welcoming me and for making the whole journey of organizing a conference such a pleasant one. And also while we were organizing, we, most of us had not done such a big, big, big conference before. So we had a lot of mentorship and help from the guys who organized JungleCon Europe 2018 from Heidelberg. So we would like to thank you guys for your guidance and for your support throughout the organizing of the conference. So let's give them a hand of applause. APPLAUSE We are there now. Hear me? Ah, there I am. Oh, that light's nasty. So somebody did a talk yesterday about configs and settings and how to deal with them in environment variables and so on. And I didn't 100% agree with it, so I wanted to present a different view on handling settings. Many people like using multiple files. I don't think so, no. Main reason is because of the concept of update anomaly. Maybe you have your static files in one file and then you change it in another one, but then they don't match and they should match. And okay, yeah, there are ways of dealing with this, but sometimes that's a discipline we're not always so good with. So there are several tools that I've built along the time, thank you, Russell, for dealing with this sort of problem. Also, environment variables definitely agree with environment variables because they're driven by the running environment. It's not something that's controlled by your application, it's something controlled by the environment in which your application runs. That's the whole concept of environment variables. But remember that you need safe fallback defaults. If the environment variable doesn't set something, you need something so that, for instance, if you're running in development or staging, you don't go and touch your production database. That can be bad. So here's some tools. The first one is one called Django Classy Settings. Can I have some hands up about who has ever heard of or used this tool before? Cool, hey, even some, wow, okay, good. So basically, you import it, the class-based settings was the original name. You define a class, anything that's shouty snake case sort of names will be exported from it when you get there. And then you can, of course, because it's a class, you can inherit and extend and so on. You might have your staging settings, your production settings, and of course in your production settings, you want to set the debug to be false. You don't want to have to remember that. And then you can just use this to go and say, hey, I'm going to switch which mode I'm running in, fall back to local by default, but maybe find staging or production when we move to staging and production. Also, you can pull apart and compose your settings in multiple classes. So you might have to reddit settings and then just say, okay, here are my reddit settings, all the settings are kept together. I want to mix them into my development settings and so on. It also supports environment variables. So you can decorate your, your, a method to say this is an environment variable. It'll use the name of the method to decide which environment variable to get, or you can prefix it as well to say put Django on the front of it. Additionally, you can specify the type you want it cast to, and that can be any callable to determine how to read it. Then sometime later, I came up with a thing at work that stumped me that I needed a much cleaner way of describing configuration and this was outside the context of Django. We didn't just need a setting file. And so I came up with Confucius because since that time Python 3 had come along and Python 3 has type annotations, we love type annotations, don't we all? Don't we? Yes. I know Tom does. So here's, here's the basic idea with Confucius. You import the base config and from that you subclass your config, then you go and define your default values and their types. And it will do the work for you of pulling them out of the environment if they're defined, casting them to the type that you've said, and giving them to you when you need them. And you use it just simply like a constant. So here's really a singleton pattern defined in Python. I know people don't like that too bad. Your config is a singleton. Let's admit it. Additionally, here's some examples of using it. Come from the read me. You can just go and run it and it will start it. You can override your port. And then we see it's nicely typing Y to be, yes, to be true, so that we don't have to think about that sort of thing. How do we do that with Django? It's a little more clumsy than the other version, but it's actually doing exactly the same thing as class-based settings was doing, Django class settings. Or, hands up, who's using Python 3.7? Can anybody know now that your modules in 3.7 can have a get-atter? It will produce a get-atter function for you that will look itself up for whatever you need, which means that anything you don't define in your settings class will be looked up in your config class. And of course, all your config objects can also have methods that refer to themselves to pull out their own values. If you don't agree with me, come and point out why I'm wrong. At the sprints, of course. You're all coming to the sprints, right? Okay, thank you. Thank you. David? Our next speaker is David. So our time is here, so you can have a look always there and know which time where you are at. Right, so I also wanted to talk about Africa, right, since we came all the way anyway. Right, so a little bit of the history about PyCon Africa, or PyCon in Africa. Oh, we are here. I'll continue in just a few minutes. Right, hello. My name is David. I work for Optimus Energy, who are a renewable energy supplier in the UK. And I want to talk to you about heretical Django practice that we follow, which I think is quite useful to everybody. It actually follows on really nicely from a little section of Tom's talk, and also from the talk earlier on about the 10,000 commit Django project and the challenges that come with that. So a bit of context, we too also have a massive Django kind of mono repo, like 40,000 commits, 2,500 migrations. We've been working on it for kind of three years. We've got to the point where we're kind of outgrowing Django, or some parts of it at least. So some of the things that are super useful when you get started, you're trying to build things quickly, kind of model forms, the admin, things like that, are starting to kind of hold us back in a way. We want to enforce certain kind of architectural rules and layers and some of these things that kind of cross concerns a little bit. We've started to kind of phase them out. And so we've come up with a whole suite of kind of fairly heretical conventions that we found really useful, and we have them published in a public style guide that you can visit. But let's have a look at one of them, which I think is quite interesting. That is to only pass Python primitives to your templates. So that means that what you're passing has got to be just things that will serialize to JSON really. So strings, ints, floats, you can't pass model instances under this kind of convention or query sets. Okay, so let's just expand a little bit on how you do that before we examine why. So if you have a view class, you've got to get context method responsible for returning this dictionary. And in that method, you need to serialize every kind of domain object, which typically is a model instance or query set. But in our case, in other projects, we have other domain objects floating around, kind of data classes, that kind of thing. And the best way to do that is to use a serializer from the Django REST framework, because that is what they're really good at doing. Taking objects and turning them into Python primitives that you can then serialize to JSON. So let's quickly walk through example view. So say you were writing a website for a Django con like this, and you want to have a page that lists all the talks. So you've got a talk model, you have a list view like this, very conventional. But in your get context data, let's quickly walk through it. So the first thing we're going to do is we're going to pop off the object list item, which is the query set. And we're popping it off to ensure we don't actually pass object list into the template. And then we're going to pass that into some template serializer class, which I'll show in the next slide. And this is just standard Django REST framework serializer, where we pass the query set as the instance. And say many equals true in this case. But if you had a detail view, you wouldn't need to use the many equals true part. And then we just write that data into the context and return it very straightforward. And this is what a template serializer looks like. This is just a standard Django REST framework serializer. You could have a model based one if you like. And we're just kind of popping off attributes or just reading attributes straight off the instance that has been passed in. Or you can walk down into its related models and grab things off there. You can call methods off the instance itself or call methods that you define on your serializer. And then you have a normal template where you're just, you're now just dealing with kind of Python primitives. There's no model methods there. Okay, so that's the practice. I know why would you do this kind of strange practice? Because it's quite unconventional. You know, new Django developers joining your team will be confused by this practice that they've never seen before. It's quite verbose. You're writing quite a lot of code in your kind of view class that you never had to use to before. You know, you can write view classes in Django that are incredibly concise. It's more work upfront. So the biggest reason is it avoids the temptation, fall off the stage, to bundle application logic, business logic onto your models. I've seen this time and time again over the five or six years I've been writing Django. And it annoys me quite a lot. It's where you end up, like Tom said, where you've got a nice list view, but somehow you've ended up calling all these model methods that make kind of 15 SQL queries in a network call. And somehow you're, and this is why your page is now taking 30 seconds to load. You can't do that when you use this pattern because you're forced to explicitly do all your I.O. upfront. This has been annoying me so much that I wrote a snarky blog article called Why Your Django Models Are Fat. And so just to expand on that, so we've got this explicit I.O. which is really useful. Because you've pre-computed all your template context, it's a really nice hook point to cache those variables, to compute some aggregate variables, kind of statistics that apply to the whole list of things you're passing in. And it's actually a really nice step towards converting your view into a kind of REST API. That's certainly part of our strategy at Octopus, is to slowly convert some of our existing Django views into REST APIs or GraphQL APIs. And you've already kind of got your serializer that does it for you, so you're virtually there. And so to take away from this, Django REST framework serializer is super useful, not just in the context of actually writing a Django, sorry, writing a REST framework kind of view. This pattern of serializing template context can be useful, mainly if you have large applications to be going on for a long time. And then starting to outgrow Django. And please have a look at our other conventions because there's lots of other useful stuff there. Thank you. Thank you. Andrew. Andrew. Andrew is our next speaker. I think something is wrong with you. This one, this one. Try to turn it off. Okay. It's not working. Is it? Okay. There we go. All right. Hello, everyone. I'm here to talk to you about a synchronous real-time programming in space. Very importantly. So in particular, a very certain part of space, this. This is the lunar lander. If you've not seen it, it went to the moon quite a while ago now. But the important part of it is, because we are computer programmers, this. This is the Apollo guidance computer. It has a whopping four kilobytes of memory. It weighs 30 kilograms. And the only interface is that tiny thing there on the side, the disky, the display and key interface. Now, there's a particular part of this computer called the pings, which of course, being NASA, is a long acronym for the primary guidance navigation and control system. Crucially, the Apollo lander was actually partially computer controlled. It was sort of an autopilot that took them down onto the moon's surface. And when it was running, that approach program was like reading the surface radar, working out how fast it was going, plotting the courses. That took the tiny little processor in the Apollo guidance computer to about 85% load. And so they're like, well, you know, that's pretty good. That's a good headroom we have on that. We're pretty happy with that as a safety margin. And then at some point in the descent, the astronauts wanted to use a bit more. They wanted to know, well, how high are we? How quickly we're approaching? So they turned on command 1668, Delta H, how high are we? That adds 10% extra load. So if we're keeping track, 95% load, still great. The processor is very happy. Everything's going really lovely. This, however, is the problem. This is the rendezvous radar for the lunar lander. It points at the other bit of the mission that orbits the moon, works out where it is and tries to keep track of it. Now, in all the testing, it was fine. And then they went to production and things weren't fine. Specifically, what they did in the real lunar lander is they hooked up that antenna to a different 800 megahertz source to the one the computer was using to run itself. If you've ever done anything with frequency, you know, this is a very bad idea. What happened was the radar went out of sync and started seeing the command module phase in and out of existence and get very confused. And what this means is it kept interrupting the computer going, I've lost it. I've got it. I've lost it. And just using up extra cycles. In fact, 13% of cycles. Now, if you're not good at maths, that is 108% of the CPU. That's not good. Now, crucially, this would have, before we had the idea of real-time processing, completely screwed the mission. They were about to pull the abort and manually boost themselves back up off the moon, fail the moon landing, and Apollo 12 would have been an historic one. But the key thing that happened was some very, very clever programmers got there first. They invented stuff that had never been used before to save that moon landing. So the disk and the computer raised what's called alarm 1202. What actually was happening by the scene series, they had written the very first real-time scheduler for this tiny little computer. It had a series of programs. The programs had priorities. It's like a normal Unix system. It's weird. And the ones with higher priorities ran first. And so what happens is like the one at the bottom here is the bit that makes you land. It's kind of important. And the one at the top is where am I? Kind of important, but less important. And when you run out of CPU cycles, it doesn't just stop. It runs the ones that are important and the ones that aren't important don't get run. And so services starts running and not finishing and overlapping itself, and it uses up all four kilobytes of that memory. And that's what the alarm is. It's saying, I run out of memory, I have to reboot myself. Thankfully, the astronauts were sensible, knew what this meant, and they switched it to an easier version of autopilot. So they used up less cycles. The memory wasn't being overloaded, and they were all fine. But the key thing to know is this is the work of one person. How? Thanks, Hal. Years before Apollo 11, the whole computer part of Apollo 11 was an afterthought. They were like, well, the computer's probably important. A navigation probably is, but how we'll take care of it. He invented the box car executive, which is the literal current still, state of the art in real time programming. It does this priority scheduling. He understands that, sorry, he didn't read it. This is the old one. My mistake. This one is bad. This one has a fixed time allocation. If they were running this, the Moon landing would have failed. He invented the new one, the new executive. He made that system up from scratch. That design that they use in the 60s is still state of the art for modern spacecraft today. And so it's an amazing story of just predicting and doing great engineering from scratch, working up a whole new idea and starting the whole beginning of real time programming. And if you want to know more tales from this and many other things that really did not go well on the Moon missions, there's a great website here where you can read about them. Thank you very much. Thank you. Thank you, Andrew. Thank you. So our next speaker is Tom. And yes, our little story about Africa. So Python in Africa started showing activity in 2010 and 2011, and this happened in South Africa, Kenya and Cameroon. And for the next four years, PSF only got funding for Python South Africa, so there was no other activity shown within that time. So we are ready for our next speaker. All right. Can you hear me? Hello? Yeah. Okay. All right. I built a thing called Deer State Machina, which is yet another state machine for Django. And I'm trying to solve race conditions in concurrent model updates with that because everybody has the same problems in their models when doing just about anything in Django. So again, hi. I'm Tom Ballrod. And I work at tier, like one of the scooters companies that you might have seen down on the road, and we are hiring. And so nobody likes race conditions. And so race conditions happen all the time to everybody using Django. Maybe they don't know it, but they happen. So if you run Django in multiple processes, or if you run them on multiple servers, if you have background tasks like salary or other task worker queues, then you'll have race conditions in your code because the same code is going to be executed in multiple threads at the same time. So whenever you are on single thread essentially. So to have an example, we've got this cat, this Schrodinger cat, which has three states. It might be alive, dead, or unknown. And there are two straight transitions for that cat. So we've got survive or rip as state transitions. And we check if the state is unknown before we go in the state because going from alive, going from dead to alive wouldn't make any sense, right? So the problem with this code is that at the moment that we check the state, it could have changed in the database already. So we've got to make sure that this doesn't happen. So what we could do is just to grab it in a transaction, call a database lock, and make sure that the state now is the same in the database. But the problem is that we still have a race condition here because the self is cached, it's the local cache of what has been in the database before. So we still have the same problem as before. So we have to, like, after we acquire that lock, we have to reread the model from the database to get where we want to be. And now we're kind of safe, but this isn't thread safe yet. And it's kind of a hassle to get this right. And so I built the estate macina, and you can just import it and use it in your code. So this is what it would look like. This is the state machine for the cat, and you would wrap all your states in, like, this state instance, and your state transitions would be just methods on the state machine. And you can create your state machine transitions using those transitions where you just, like, you go and say, OK, from unknown to alive, this would be the survive transition, right, or from unknown to dead, this would be the rip transition. And to use this in your model, you can then, instead of having all the code in your model, you would just have the state machine with the new state machine field in your model and reference the state field, that is the integer field, as it used to be before. And so for the usage, you would just call those methods on the state machine and it would do all this stuff automatically for you. It would check if it's in the right state to be able to transition and so on. So what's different between what we had before and what we have now is, like, there's no safe call, because if you do a state transition, you want to have it persisted in your database, so you do or do not. There's no try. And what's also different is that there's no state checking. So if you want to call that survive call, you can be sure that you are in the state unknown for the cat and you don't have to make that check for yourself. So in a nutshell, what this thing provides for you is, like, if you have a state machine in one place, this is where you keep all your model transitions, like the changes of your model, you wouldn't call safe manually anymore. And the state transitions also define how your model is changed. So you know when a certain field is changed, you know it is part of that state transition, for example. It's very practical for debugging, for example. And of course, we have no more race conditions. So check out the code. It's on GitHub and in the PIPI repository. And yeah, so I hope you will enjoy that. APPLAUSE Okay, thank you, Tom. Right, so there's been a change of things a little bit. So our speech-to-text translators are not going to be with us for the rest of the night. They have to catch a flight. I know. So there's a little bit of a twist also in our lightning talks. Before we continue with the next speaker, we have a little surprise for you. So we are about to welcome Mikkel. He is going to do a little performance for us, and he has been with the school for a year now. And he's amazing at what he does. So he's about to show us how good he really is. APPLAUSE Right, so around the party venue, there are also food places that you can go to and have some food before the party. So you can go to a hotel and leave your laptop and stuff and still come back around the venue and have something to eat. Okay, let's give a stage to Mikkel. APPLAUSE APPLAUSE APPLAUSE APPLAUSE APPLAUSE APPLAUSE APPLAUSE APPLAUSE APPLAUSE APPLAUSE APPLAUSE I must say, I love Afuku. I love both of you. Thank you. You have to come back here. Right. So, back to Pai Kwan in Africa. LAUGHTER Right. So, I said for the next four years, since 2010, Then in 2015, Paekwon Namibia was the next conference in Africa. Daniela, where are you? He is the special person to Namibia because he helped bring Paekwon to Namibia. Thank you, Daniela. Are we ready? Right, in 2016, we saw more development in Africa. We saw Paekwon Zimbabwe and Paekwon Nigeria as well, followed by that was Paekwon Ghana and then Paekwon Kenya. Now the next one that we really are looking forward to is Paekwon Africa in August. So I will be there. I don't know about you, but I will definitely be there. So are we ready? No, no, no, don't worry. I have more stuff about Africa. Right, so a few facts about these beautiful countries in just a few minutes. Yes. Oops, I have no control of it. Okay, awesome. Right. Sorry for the delay. Yeah, my name is Harsh Bimjani and I'm a full stack developer at Ambient Innovation. I'm here to talk about managing elastic search in Django like a pro. So if you had a chance to use integrated search in your Django project using elastic search, you may have come across this package, Django Haystack. It's quite popular, very easy to use, tons of features. Well, it has a great ORM for querying the elastic search and has a lot of different data management features like updating the index, rebuilding the index. And yeah, so there's a very good amount of data flowing in that, but it has a problem. It is not quite updated to the latest version of elastic search. To be honest, it's very bad. And yeah, so it supports elastic search less than 2.0 and current version of elastic search is kind of 7.0, so we have to find an alternative. Well, thankfully, there is another package that does that. This elastic search DSL. Well, this is kind of a high-level path in client which is provided by Elastics themselves, which provides a nice, beautiful ORM for us, but we still have to kind of manage the data by ourselves. Let's take a look at it. How is the ORM for it? Well, this is somewhat looks like a basic elastic search query. Elastic search, you can, in elastic search, you have to kind of like send and receive requests using Rust API, so everything is via JSON. But Elastics.DSL does this nice ORM for us, so it's quite very easy to use, and it has a very similar to the raw query of elastic search format. So it's pretty nice, but we still have to figure out the problem for the data flow, which Hasak provides us, and it's quite nice, and this thing lacks it. So I decided to build a management system for myself. Well, let's take a look at creating the index. This is kind of a very similar format to your Django Resprimwork serializer, or in that way, we usually inherit from the different superclass that is provided for by Elastics.DSL, but in this case, we inherit from a superclass that I created in the abstract index. We are not going to go deeper into that, it's kind of a lot of logic. So this is how it is done, but we have a new feature here, it's called getUpdatedField. This one, you have to provide a datetime field of your model, and it will index only the data that was updated in the last hour or two hours or whatever. This is kind of the management command that it provides. You can index the document, update the document, specify which index you want to update or clear the index or the age factor in that which will use the updated field that you provided, and it will only update the posts that were created in the last one or two hours. The whole implementation of this is, I didn't have much time to create an open source package for it, kind of a fork of this which depends on Elastics.DSL, so I created an article for it. You can search for it, and it's quite popular one, so you may be able to find the whole implementation there, including the abstract index code, and thank you. Thanks, Harsh. So a few facts about Africa. I'll start with Ghana. Ghana is a country in West Africa. It shares borders with every coast, Burkina Faso and Togo. Ghana has over 28 million people, and 70% of the population are Christians. Ghana gained independence on the 6th of March, 1957. It has about 80 languages spoken. Ghana has over 70 ethnic groups, and we are almost there. Don't be. I have more countries. Nigeria. Nigeria is in West Africa. It has over 200 million people. I come from a 2.5 million country, so I don't know how 200 million people can live in one country. I can imagine the traffic. Ghana shares borders with Niger, Chet, Cameroon, Benin, and the Atlantic Ocean. It has 521 languages. That's crazy. None of them are extinct, by the way. It has more than 50% of Muslim, and it has over 250 ethnic groups. Another country. Zimbabwe. My neighbor. Are we skipping the slides? I have more countries on my list. Okay. Right, Zimbabwe. It's in Southern Africa. It has over 16.5 million people. One of the amazing tourist attraction places is Zambesi River and Victoria Falls. You can see Zambesi River from Namibia as well. The former president, Robert Mogabe, ruled from 1987 to 2017 when he resigned. That's a long time. English is the main language. They have 16 official languages, and 70% of the people speak Shona. We're just going to do it without the slides. Okay. Oh, actually, yes. One more minute, sorry. I'm running out of Africa. Right. Cameroon. Cameroon is in Central Africa. One of those countries that I want to visit as well, because it's a bit special. It has more than 25 million people. The official languages are French and English. So in the north, the north part gained independence from France in 1960, and then the southern part of Cameroon gained independence from Britain in 1961. I guess this country had a lot of interest because it was colonized by two different countries. I mean, are we there yet? So Cameroon has Catholics, Protestants, and Muslims, with Catholics being more than 40% as the majority. And they have approximately 250 languages as well. And, yeah, all right. Go ahead. Cool. Hello, everybody. My name is Rafael Aguayo. I work for a nonprofit organization called Learning Equality, and we build educational technology to empower learners and teachers. And today I'm going to be talking about Django for Social Good. Specifically, I'm going to be talking about our main product, Calibri. The word Calibri might sound familiar to some of you, because it actually means hummingbird in a variety of different languages. And the hummingbird is a symbol of strength, hope, and migration. So here we have a picture of Jonathan, who lives in the mountains of Guatemala. He's a smart and curious student, but he has a problem. He doesn't have access to resources for a high quality education, but Jonathan is not alone. Over one in three children lack access to a quality education. So yeah, like I was saying, Jonathan is not alone in that. And so there's a wealth of educational technology that is available online, but over half of the world is still offline. So that means that there's over 400 million children who could benefit from technologies like Calibri. Calibri doesn't fly alone, though. We have an ecosystem of products to go along with Calibri. We have Calibri Studio, which is an online repository of educational resources. We have Calibri Toolkit, which is a resource for teachers and implementers to effectively use Calibri in the classroom. And the best part about this is that it's free and open source. And I'll put the link to the repo at the end of the slides. And of course, it uses Django and Django REST framework for the backend. So we take openly licensed educational resources, and we make them importable into Calibri so that learners can use and access them. So our goal is to have a Calibri run on legacy hardware or low cost devices like the Raspberry Pi. So we have various different methods to install it. We have PECs, we have PIP install, we have Debian installer, we have Windows installer. So we really want to make this software as easy to access as possible. And another great part is that you don't need internet to run the software. So you download it once over connection, and then you can have it forever. And so the software is designed to run without an internet connection, but when we do have a connection, we do try to make use of that by downloading usage metrics. So these are some of the common use cases that Calibri can be used in prisons, in refugee camps, or rural areas. For example, someone can take a Raspberry Pi and load Calibri and content on it and go, let's say, 200 kilometers to a far away village, and they also bring client devices for the students to use. And then they can access this content, this high quality content. And so go ahead, take your phones out. Take a picture or punch it in, enter it into your browser. But just some closing remarks. So the reason we're able to build this software is because it's based already on open source software on Django. So I think it's amazing that something that was designed to be a CMS can be repurposed to benefit society like this. And so the next time you come up with an idea or a project, so yeah, the next time you come up with an idea or a project, don't try to make the next big social media network. I don't want to have to make another social media account. I don't want to see pictures of your cats or dogs. Instead, I want you to try to come up with something that will benefit the lives of people who need it most. I like to think of programming as a superpower where you can build anything that you can imagine. So I say use this superpower so that you can be a superhero to someone like Jonathan. Thank you. Thanks, Rafael. I would like to call upon Kato. Sorry. Yeah. Kato, come and tell us a little bit about the sprints. Hello. So come do the practical. The sprints. What are the sprints? The sprints are your... Oh, hang on. I skipped one. Your chance to get involved. Okay. The pony's hungry. So first of all, where are they? They're at the Kulcha Hussat in the Bay. That's there. You can look that up on the website. When you go to the website, there are two addresses. One is here and one is the sprint venue. I found this out on Wednesday when I went to the sprint venue. So here's a little... Here's a Google map. This one here is the sprint venue. Check when you put it into your map that it's next to that big lake there and then go there. Not to come here. Right. What are the sprints? The sprints are an opportunity for us to get together. They're an opportunity for us to talk about problems and they're an opportunity for us to solve them. Okay. That's it. You could write docs. You could fix bugs. You could help triage tickets. You could do that in Python or not. You could work on something that wasn't software related at all, like a community project of some kind. You could work on anything. You don't have to know. There are some people who know what they're going to work at the sprints and they'll say at the beginning of the day, I'm going to work on this any moment to help me. If you don't know what you want to work on now, that's fine. Come and we'll help you find something to work on. Okay. I'm going to be there all day. My main focus is going to be on helping people. So come. You can do it. Okay. If you've never contributed to Django before, the sprints are the perfect opportunity to get involved. So please come along. Please join in. Let's do it. Let's feed the pony. Thanks. Thank you. All right. So we have come to the end of things. We'll see you in the next video.
 So I am from Namibia and I've been a high school teacher for the past three years.  I've taught computer studies to learners of ages between 13 and 19.  And right now I'm a full-time student and we are not there yet.  Are we there?  Okay.  So, okay, so last year I was at JungleCon Europe 2018 and I gave a talk at the conference.  And one of my friends was also an organizer at that conference.  So when I went back home, I also wanted to be an organizer.  Back home, I organized back on Namibia and I organized lots of Python workshops  and events back home.  I work a lot with high school learners as well.  We organize a workshop, not a workshop but a conference for high school learners.  So I was interested to learn how the international world organized conferences  and I also wanted to be an organizer.  So I wrote to the organizing team when I knew where the conference was going to be.  And I would like to thank the organizing committee for welcoming me  and for making the whole journey of organizing a conference such a pleasant one.  And also while we were organizing, we, most of us had not done such a big, big, big conference before.  So we had a lot of mentorship and help from the guys who organized JungleCon Europe 2018 from Heidelberg.  So we would like to thank you guys for your guidance and for your support throughout the organizing of the conference.  So let's give them a hand of applause.  APPLAUSE  We are there now.  Hear me? Ah, there I am.  Oh, that light's nasty.  So somebody did a talk yesterday about configs and settings and how to deal with them in environment variables and so on.  And I didn't 100% agree with it, so I wanted to present a different view on handling settings.  Many people like using multiple files.  I don't think so, no.  Main reason is because of the concept of update anomaly.  Maybe you have your static files in one file and then you change it in another one,  but then they don't match and they should match.  And okay, yeah, there are ways of dealing with this, but sometimes that's a discipline we're not always so good with.  So there are several tools that I've built along the time, thank you, Russell, for dealing with this sort of problem.  Also, environment variables definitely agree with environment variables because they're driven by the running environment.  It's not something that's controlled by your application, it's something controlled by the environment in which your application runs.  That's the whole concept of environment variables.  But remember that you need safe fallback defaults.  If the environment variable doesn't set something, you need something so that, for instance,  if you're running in development or staging, you don't go and touch your production database.  That can be bad.  So here's some tools.  The first one is one called Django Classy Settings.  Can I have some hands up about who has ever heard of or used this tool before?  Cool, hey, even some, wow, okay, good.  So basically, you import it, the class-based settings was the original name.  You define a class, anything that's shouty snake case sort of names will be exported from it when you get there.  And then you can, of course, because it's a class, you can inherit and extend and so on.  You might have your staging settings, your production settings, and of course in your production settings, you want to set the debug to be false.  You don't want to have to remember that.  And then you can just use this to go and say, hey, I'm going to switch which mode I'm running in, fall back to local by default, but maybe find staging or production when we move to staging and production.  Also, you can pull apart and compose your settings in multiple classes.  So you might have to reddit settings and then just say, okay, here are my reddit settings, all the settings are kept together.  I want to mix them into my development settings and so on.  It also supports environment variables.  So you can decorate your, your, a method to say this is an environment variable.  It'll use the name of the method to decide which environment variable to get, or you can prefix it as well to say put Django on the front of it.  Additionally, you can specify the type you want it cast to, and that can be any callable to determine how to read it.  Then sometime later, I came up with a thing at work that stumped me that I needed a much cleaner way of describing configuration and this was outside the context of Django.  We didn't just need a setting file.  And so I came up with Confucius because since that time Python 3 had come along and Python 3 has type annotations, we love type annotations, don't we all?  Don't we?  Yes.  I know Tom does.  So here's, here's the basic idea with Confucius.  You import the base config and from that you subclass your config, then you go and define your default values and their types.  And it will do the work for you of pulling them out of the environment if they're defined, casting them to the type that you've said, and giving them to you when you need them.  And you use it just simply like a constant.  So here's really a singleton pattern defined in Python.  I know people don't like that too bad.  Your config is a singleton.  Let's admit it.  Additionally, here's some examples of using it.  Come from the read me.  You can just go and run it and it will start it.  You can override your port.  And then we see it's nicely typing Y to be, yes, to be true, so that we don't have to think about that sort of thing.  How do we do that with Django?  It's a little more clumsy than the other version, but it's actually doing exactly the same thing as class-based settings was doing, Django class settings.  Or, hands up, who's using Python 3.7?  Can anybody know now that your modules in 3.7 can have a get-atter?  It will produce a get-atter function for you that will look itself up for whatever you need, which means that anything you don't define in your settings class will be looked up in your config class.  And of course, all your config objects can also have methods that refer to themselves to pull out their own values.  If you don't agree with me, come and point out why I'm wrong.  At the sprints, of course.  You're all coming to the sprints, right?  Okay, thank you.  Thank you.  David?  Our next speaker is David.  So our time is here, so you can have a look always there and know which time where you are at.  Right, so I also wanted to talk about Africa, right, since we came all the way anyway.  Right, so a little bit of the history about PyCon Africa, or PyCon in Africa.  Oh, we are here.  I'll continue in just a few minutes.  Right, hello.  My name is David.  I work for Optimus Energy, who are a renewable energy supplier in the UK.  And I want to talk to you about heretical Django practice that we follow, which I think is quite useful to everybody.  It actually follows on really nicely from a little section of Tom's talk, and also from the talk earlier on about the 10,000 commit Django project and the challenges that come with that.  So a bit of context, we too also have a massive Django kind of mono repo, like 40,000 commits, 2,500 migrations.  We've been working on it for kind of three years.  We've got to the point where we're kind of outgrowing Django, or some parts of it at least.  So some of the things that are super useful when you get started, you're trying to build things quickly, kind of model forms, the admin, things like that, are starting to kind of hold us back in a way.  We want to enforce certain kind of architectural rules and layers and some of these things that kind of cross concerns a little bit.  We've started to kind of phase them out.  And so we've come up with a whole suite of kind of fairly heretical conventions that we found really useful, and we have them published in a public style guide that you can visit.  But let's have a look at one of them, which I think is quite interesting.  That is to only pass Python primitives to your templates. So that means that what you're passing has got to be just things that will serialize to JSON really.  So strings, ints, floats, you can't pass model instances under this kind of convention or query sets.  Okay, so let's just expand a little bit on how you do that before we examine why.  So if you have a view class, you've got to get context method responsible for returning this dictionary.  And in that method, you need to serialize every kind of domain object, which typically is a model instance or query set.  But in our case, in other projects, we have other domain objects floating around, kind of data classes, that kind of thing.  And the best way to do that is to use a serializer from the Django REST framework, because that is what they're really good at doing.  Taking objects and turning them into Python primitives that you can then serialize to JSON.  So let's quickly walk through example view. So say you were writing a website for a Django con like this, and you want to have a page that lists all the talks.  So you've got a talk model, you have a list view like this, very conventional.  But in your get context data, let's quickly walk through it.  So the first thing we're going to do is we're going to pop off the object list item, which is the query set.  And we're popping it off to ensure we don't actually pass object list into the template.  And then we're going to pass that into some template serializer class, which I'll show in the next slide.  And this is just standard Django REST framework serializer, where we pass the query set as the instance.  And say many equals true in this case. But if you had a detail view, you wouldn't need to use the many equals true part.  And then we just write that data into the context and return it very straightforward.  And this is what a template serializer looks like. This is just a standard Django REST framework serializer.  You could have a model based one if you like. And we're just kind of popping off attributes or just reading attributes straight off the instance that has been passed in.  Or you can walk down into its related models and grab things off there.  You can call methods off the instance itself or call methods that you define on your serializer.  And then you have a normal template where you're just, you're now just dealing with kind of Python primitives.  There's no model methods there.  Okay, so that's the practice. I know why would you do this kind of strange practice?  Because it's quite unconventional. You know, new Django developers joining your team will be confused by this practice that they've never seen before.  It's quite verbose. You're writing quite a lot of code in your kind of view class that you never had to use to before.  You know, you can write view classes in Django that are incredibly concise. It's more work upfront.  So the biggest reason is it avoids the temptation, fall off the stage, to bundle application logic, business logic onto your models.  I've seen this time and time again over the five or six years I've been writing Django.  And it annoys me quite a lot. It's where you end up, like Tom said, where you've got a nice list view,  but somehow you've ended up calling all these model methods that make kind of 15 SQL queries in a network call.  And somehow you're, and this is why your page is now taking 30 seconds to load.  You can't do that when you use this pattern because you're forced to explicitly do all your I.O. upfront.  This has been annoying me so much that I wrote a snarky blog article called Why Your Django Models Are Fat.  And so just to expand on that, so we've got this explicit I.O. which is really useful.  Because you've pre-computed all your template context, it's a really nice hook point to cache those variables,  to compute some aggregate variables, kind of statistics that apply to the whole list of things you're passing in.  And it's actually a really nice step towards converting your view into a kind of REST API.  That's certainly part of our strategy at Octopus, is to slowly convert some of our existing Django views into REST APIs or GraphQL APIs.  And you've already kind of got your serializer that does it for you, so you're virtually there.  And so to take away from this, Django REST framework serializer is super useful, not just in the context of actually writing a Django,  sorry, writing a REST framework kind of view.  This pattern of serializing template context can be useful, mainly if you have large applications to be going on for a long time.  And then starting to outgrow Django.  And please have a look at our other conventions because there's lots of other useful stuff there.  Thank you.  Thank you.  Andrew.  Andrew.  Andrew is our next speaker.  I think something is wrong with you.  This one, this one.  Try to turn it off.  Okay.  It's not working.  Is it?  Okay.  There we go.  All right.  Hello, everyone.  I'm here to talk to you about a synchronous real-time programming in space.  Very importantly.  So in particular, a very certain part of space, this.  This is the lunar lander.  If you've not seen it, it went to the moon quite a while ago now.  But the important part of it is, because we are computer programmers, this.  This is the Apollo guidance computer.  It has a whopping four kilobytes of memory.  It weighs 30 kilograms.  And the only interface is that tiny thing there on the side, the disky, the display and key interface.  Now, there's a particular part of this computer called the pings, which of course, being NASA, is a long acronym for the primary guidance navigation and control system.  Crucially, the Apollo lander was actually partially computer controlled.  It was sort of an autopilot that took them down onto the moon's surface.  And when it was running, that approach program was like reading the surface radar, working out how fast it was going, plotting the courses.  That took the tiny little processor in the Apollo guidance computer to about 85% load.  And so they're like, well, you know, that's pretty good.  That's a good headroom we have on that.  We're pretty happy with that as a safety margin.  And then at some point in the descent, the astronauts wanted to use a bit more.  They wanted to know, well, how high are we?  How quickly we're approaching?  So they turned on command 1668, Delta H, how high are we?  That adds 10% extra load.  So if we're keeping track, 95% load, still great.  The processor is very happy.  Everything's going really lovely.  This, however, is the problem.  This is the rendezvous radar for the lunar lander.  It points at the other bit of the mission that orbits the moon, works out where it is and tries to keep track of it.  Now, in all the testing, it was fine.  And then they went to production and things weren't fine.  Specifically, what they did in the real lunar lander is they hooked up that antenna to a different 800 megahertz source to the one the computer was using to run itself.  If you've ever done anything with frequency, you know, this is a very bad idea.  What happened was the radar went out of sync and started seeing the command module phase in and out of existence and get very confused.  And what this means is it kept interrupting the computer going, I've lost it.  I've got it. I've lost it.  And just using up extra cycles.  In fact, 13% of cycles.  Now, if you're not good at maths, that is 108% of the CPU.  That's not good.  Now, crucially, this would have, before we had the idea of real-time processing, completely screwed the mission.  They were about to pull the abort and manually boost themselves back up off the moon, fail the moon landing, and Apollo 12 would have been an historic one.  But the key thing that happened was some very, very clever programmers got there first.  They invented stuff that had never been used before to save that moon landing.  So the disk and the computer raised what's called alarm 1202.  What actually was happening by the scene series, they had written the very first real-time scheduler for this tiny little computer.  It had a series of programs.  The programs had priorities.  It's like a normal Unix system. It's weird.  And the ones with higher priorities ran first.  And so what happens is like the one at the bottom here is the bit that makes you land.  It's kind of important.  And the one at the top is where am I?  Kind of important, but less important.  And when you run out of CPU cycles, it doesn't just stop.  It runs the ones that are important and the ones that aren't important don't get run.  And so services starts running and not finishing and overlapping itself,  and it uses up all four kilobytes of that memory.  And that's what the alarm is.  It's saying, I run out of memory, I have to reboot myself.  Thankfully, the astronauts were sensible, knew what this meant,  and they switched it to an easier version of autopilot.  So they used up less cycles.  The memory wasn't being overloaded, and they were all fine.  But the key thing to know is this is the work of one person.  How? Thanks, Hal.  Years before Apollo 11, the whole computer part of Apollo 11 was an afterthought.  They were like, well, the computer's probably important.  A navigation probably is, but how we'll take care of it.  He invented the box car executive, which is the literal current still,  state of the art in real time programming.  It does this priority scheduling.  He understands that, sorry, he didn't read it. This is the old one.  My mistake. This one is bad. This one has a fixed time allocation.  If they were running this, the Moon landing would have failed.  He invented the new one, the new executive.  He made that system up from scratch.  That design that they use in the 60s is still state of the art  for modern spacecraft today.  And so it's an amazing story of just predicting and doing great engineering from scratch,  working up a whole new idea and starting the whole beginning of real time programming.  And if you want to know more tales from this and many other things  that really did not go well on the Moon missions,  there's a great website here where you can read about them.  Thank you very much.  Thank you.  Thank you, Andrew.  Thank you.  So our next speaker is Tom.  And yes, our little story about Africa.  So Python in Africa started showing activity in 2010 and 2011,  and this happened in South Africa, Kenya and Cameroon.  And for the next four years,  PSF only got funding for Python South Africa,  so there was no other activity shown within that time.  So we are ready for our next speaker.  All right. Can you hear me? Hello?  Yeah. Okay.  All right. I built a thing called Deer State Machina,  which is yet another state machine for Django.  And I'm trying to solve race conditions in concurrent model updates with that  because everybody has the same problems in their models  when doing just about anything in Django.  So again, hi.  I'm Tom Ballrod.  And I work at tier, like one of the scooters companies that you might have seen down on the road,  and we are hiring.  And so nobody likes race conditions.  And so race conditions happen all the time to everybody using Django.  Maybe they don't know it, but they happen.  So if you run Django in multiple processes,  or if you run them on multiple servers,  if you have background tasks like salary or other task worker queues,  then you'll have race conditions in your code  because the same code is going to be executed in multiple threads at the same time.  So whenever you are on single thread essentially.  So to have an example, we've got this cat, this Schrodinger cat,  which has three states.  It might be alive, dead, or unknown.  And there are two straight transitions for that cat.  So we've got survive or rip as state transitions.  And we check if the state is unknown before we go in the state  because going from alive, going from dead to alive wouldn't make any sense, right?  So the problem with this code is that at the moment that we check the state,  it could have changed in the database already.  So we've got to make sure that this doesn't happen.  So what we could do is just to grab it in a transaction,  call a database lock, and make sure that the state now is the same in the database.  But the problem is that we still have a race condition here  because the self is cached, it's the local cache of what has been in the database before.  So we still have the same problem as before.  So we have to, like, after we acquire that lock,  we have to reread the model from the database to get where we want to be.  And now we're kind of safe, but this isn't thread safe yet.  And it's kind of a hassle to get this right.  And so I built the estate macina, and you can just import it and use it in your code.  So this is what it would look like.  This is the state machine for the cat,  and you would wrap all your states in, like, this state instance,  and your state transitions would be just methods on the state machine.  And you can create your state machine transitions using those transitions  where you just, like, you go and say, OK, from unknown to alive,  this would be the survive transition, right, or from unknown to dead,  this would be the rip transition.  And to use this in your model, you can then, instead of having all the code in your model,  you would just have the state machine with the new state machine field in your model  and reference the state field, that is the integer field, as it used to be before.  And so for the usage, you would just call those methods on the state machine  and it would do all this stuff automatically for you.  It would check if it's in the right state to be able to transition and so on.  So what's different between what we had before and what we have now  is, like, there's no safe call, because if you do a state transition,  you want to have it persisted in your database, so you do or do not.  There's no try.  And what's also different is that there's no state checking.  So if you want to call that survive call,  you can be sure that you are in the state unknown for the cat  and you don't have to make that check for yourself.  So in a nutshell, what this thing provides for you is, like,  if you have a state machine in one place,  this is where you keep all your model transitions, like the changes of your model,  you wouldn't call safe manually anymore.  And the state transitions also define how your model is changed.  So you know when a certain field is changed,  you know it is part of that state transition, for example.  It's very practical for debugging, for example.  And of course, we have no more race conditions.  So check out the code.  It's on GitHub and in the PIPI repository.  And yeah, so I hope you will enjoy that.  APPLAUSE  Okay, thank you, Tom.  Right, so there's been a change of things a little bit.  So our speech-to-text translators are not going to be with us for the rest of the night.  They have to catch a flight.  I know.  So there's a little bit of a twist also in our lightning talks.  Before we continue with the next speaker, we have a little surprise for you.  So we are about to welcome Mikkel.  He is going to do a little performance for us,  and he has been with the school for a year now.  And he's amazing at what he does.  So he's about to show us how good he really is.  APPLAUSE  Right, so around the party venue, there are also food places that you can go to  and have some food before the party.  So you can go to a hotel and leave your laptop and stuff  and still come back around the venue and have something to eat.  Okay, let's give a stage to Mikkel.  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  APPLAUSE  I must say, I love Afuku.  I love both of you.  Thank you.  You have to come back here.  Right.  So, back to Pai Kwan in Africa.  LAUGHTER  Right.  So, I said for the next four years, since 2010,  Then in 2015, Paekwon Namibia was the next conference in Africa.  Daniela, where are you?  He is the special person to Namibia because he helped bring Paekwon to Namibia.  Thank you, Daniela.  Are we ready?  Right, in 2016, we saw more development in Africa.  We saw Paekwon Zimbabwe and Paekwon Nigeria as well,  followed by that was Paekwon Ghana and then Paekwon Kenya.  Now the next one that we really are looking forward to is Paekwon Africa in August.  So I will be there.  I don't know about you, but I will definitely be there.  So are we ready?  No, no, no, don't worry.  I have more stuff about Africa.  Right, so a few facts about these beautiful countries in just a few minutes.  Yes.  Oops, I have no control of it.  Okay, awesome.  Right.  Sorry for the delay.  Yeah, my name is Harsh Bimjani and I'm a full stack developer at Ambient Innovation.  I'm here to talk about managing elastic search in Django like a pro.  So if you had a chance to use integrated search in your Django project using elastic search,  you may have come across this package, Django Haystack.  It's quite popular, very easy to use, tons of features.  Well, it has a great ORM for querying the elastic search and has a lot of different data management features  like updating the index, rebuilding the index.  And yeah, so there's a very good amount of data flowing in that, but it has a problem.  It is not quite updated to the latest version of elastic search.  To be honest, it's very bad.  And yeah, so it supports elastic search less than 2.0 and current version of elastic search  is kind of 7.0, so we have to find an alternative.  Well, thankfully, there is another package that does that.  This elastic search DSL.  Well, this is kind of a high-level path in client which is provided by Elastics themselves,  which provides a nice, beautiful ORM for us, but we still have to kind of manage the data  by ourselves.  Let's take a look at it.  How is the ORM for it?  Well, this is somewhat looks like a basic elastic search query.  Elastic search, you can, in elastic search, you have to kind of like send and receive  requests using Rust API, so everything is via JSON.  But Elastics.DSL does this nice ORM for us, so it's quite very easy to use, and it has  a very similar to the raw query of elastic search format.  So it's pretty nice, but we still have to figure out the problem for the data flow, which  Hasak provides us, and it's quite nice, and this thing lacks it.  So I decided to build a management system for myself.  Well, let's take a look at creating the index.  This is kind of a very similar format to your Django Resprimwork serializer, or in that  way, we usually inherit from the different superclass that is provided for by Elastics.DSL,  but in this case, we inherit from a superclass that I created in the abstract index.  We are not going to go deeper into that, it's kind of a lot of logic.  So this is how it is done, but we have a new feature here, it's called getUpdatedField.  This one, you have to provide a datetime field of your model, and it will index only the  data that was updated in the last hour or two hours or whatever.  This is kind of the management command that it provides.  You can index the document, update the document, specify which index you want to update or  clear the index or the age factor in that which will use the updated field that you  provided, and it will only update the posts that were created in the last one or two hours.  The whole implementation of this is, I didn't have much time to create an open source package  for it, kind of a fork of this which depends on Elastics.DSL, so I created an article for  it.  You can search for it, and it's quite popular one, so you may be able to find the whole  implementation there, including the abstract index code, and thank you.  Thanks, Harsh.  So a few facts about Africa.  I'll start with Ghana.  Ghana is a country in West Africa.  It shares borders with every coast, Burkina Faso and Togo.  Ghana has over 28 million people, and 70% of the population are Christians.  Ghana gained independence on the 6th of March, 1957.  It has about 80 languages spoken.  Ghana has over 70 ethnic groups, and we are almost there.  Don't be.  I have more countries.  Nigeria.  Nigeria is in West Africa.  It has over 200 million people.  I come from a 2.5 million country, so I don't know how 200 million people can live in one  country.  I can imagine the traffic.  Ghana shares borders with Niger, Chet, Cameroon, Benin, and the Atlantic Ocean.  It has 521 languages.  That's crazy.  None of them are extinct, by the way.  It has more than 50% of Muslim, and it has over 250 ethnic groups.  Another country.  Zimbabwe.  My neighbor.  Are we skipping the slides?  I have more countries on my list.  Okay.  Right, Zimbabwe.  It's in Southern Africa.  It has over 16.5 million people.  One of the amazing tourist attraction places is Zambesi River and Victoria Falls.  You can see Zambesi River from Namibia as well.  The former president, Robert Mogabe, ruled from 1987 to 2017 when he resigned.  That's a long time.  English is the main language.  They have 16 official languages, and 70% of the people speak Shona.  We're just going to do it without the slides.  Okay.  Oh, actually, yes.  One more minute, sorry.  I'm running out of Africa.  Right.  Cameroon.  Cameroon is in Central Africa.  One of those countries that I want to visit as well, because it's a bit special.  It has more than 25 million people.  The official languages are French and English.  So in the north, the north part gained independence from France in 1960, and then the southern  part of Cameroon gained independence from Britain in 1961.  I guess this country had a lot of interest because it was colonized by two different  countries.  I mean, are we there yet?  So Cameroon has Catholics, Protestants, and Muslims, with Catholics being more than 40%  as the majority.  And they have approximately 250 languages as well.  And, yeah, all right.  Go ahead.  Cool.  Hello, everybody.  My name is Rafael Aguayo.  I work for a nonprofit organization called Learning Equality, and we build educational  technology to empower learners and teachers.  And today I'm going to be talking about Django for Social Good.  Specifically, I'm going to be talking about our main product, Calibri.  The word Calibri might sound familiar to some of you, because it actually means hummingbird  in a variety of different languages.  And the hummingbird is a symbol of strength, hope, and migration.  So here we have a picture of Jonathan, who lives in the mountains of Guatemala.  He's a smart and curious student, but he has a problem.  He doesn't have access to resources for a high quality education, but Jonathan is not  alone.  Over one in three children lack access to a quality education.  So yeah, like I was saying, Jonathan is not alone in that.  And so there's a wealth of educational technology that is available online, but over half of  the world is still offline.  So that means that there's over 400 million children who could benefit from technologies  like Calibri.  Calibri doesn't fly alone, though.  We have an ecosystem of products to go along with Calibri.  We have Calibri Studio, which is an online repository of educational resources.  We have Calibri Toolkit, which is a resource for teachers and implementers to effectively  use Calibri in the classroom.  And the best part about this is that it's free and open source.  And I'll put the link to the repo at the end of the slides.  And of course, it uses Django and Django REST framework for the backend.  So we take openly licensed educational resources, and we make them importable into Calibri so  that learners can use and access them.  So our goal is to have a Calibri run on legacy hardware or low cost devices like the Raspberry  Pi.  So we have various different methods to install it.  We have PECs, we have PIP install, we have Debian installer, we have Windows installer.  So we really want to make this software as easy to access as possible.  And another great part is that you don't need internet to run the software.  So you download it once over connection, and then you can have it forever.  And so the software is designed to run without an internet connection, but when we do have  a connection, we do try to make use of that by downloading usage metrics.  So these are some of the common use cases that Calibri can be used in prisons, in refugee  camps, or rural areas.  For example, someone can take a Raspberry Pi and load Calibri and content on it and go,  let's say, 200 kilometers to a far away village, and they also bring client devices for the  students to use.  And then they can access this content, this high quality content.  And so go ahead, take your phones out.  Take a picture or punch it in, enter it into your browser.  But just some closing remarks.  So the reason we're able to build this software is because it's based already on open source  software on Django.  So I think it's amazing that something that was designed to be a CMS can be repurposed  to benefit society like this.  And so the next time you come up with an idea or a project, so yeah, the next time you come  up with an idea or a project, don't try to make the next big social media network.  I don't want to have to make another social media account.  I don't want to see pictures of your cats or dogs.  Instead, I want you to try to come up with something that will benefit the lives of people  who need it most.  I like to think of programming as a superpower where you can build anything that you can  imagine.  So I say use this superpower so that you can be a superhero to someone like Jonathan.  Thank you.  Thanks, Rafael.  I would like to call upon Kato.  Sorry.  Yeah.  Kato, come and tell us a little bit about the sprints.  Hello.  So come do the practical.  The sprints.  What are the sprints?  The sprints are your...  Oh, hang on.  I skipped one.  Your chance to get involved.  Okay.  The pony's hungry.  So first of all, where are they?  They're at the Kulcha Hussat in the Bay.  That's there.  You can look that up on the website.  When you go to the website, there are two addresses.  One is here and one is the sprint venue.  I found this out on Wednesday when I went to the sprint venue.  So here's a little...  Here's a Google map.  This one here is the sprint venue.  Check when you put it into your map that it's next to that big lake there and then go there.  Not to come here.  Right.  What are the sprints?  The sprints are an opportunity for us to get together.  They're an opportunity for us to talk about problems and they're an opportunity for us  to solve them.  Okay.  That's it.  You could write docs.  You could fix bugs.  You could help triage tickets.  You could do that in Python or not.  You could work on something that wasn't software related at all, like a community project of  some kind.  You could work on anything.  You don't have to know.  There are some people who know what they're going to work at the sprints and they'll say  at the beginning of the day, I'm going to work on this any moment to help me.  If you don't know what you want to work on now, that's fine.  Come and we'll help you find something to work on.  Okay.  I'm going to be there all day.  My main focus is going to be on helping people.  So come.  You can do it.  Okay.  If you've never contributed to Django before, the sprints are the perfect opportunity to  get involved.  So please come along.  Please join in.  Let's do it.  Let's feed the pony.  Thanks.  Thank you.  All right.  So we have come to the end of things.  We'll see you in the next video.
DjangoCon_2019_-_Day_3_Lightning_Talks_0_7883.png DjangoCon_2019_-_Day_3_Lightning_Talks_7884_12131.png DjangoCon_2019_-_Day_3_Lightning_Talks_12132_12263.png DjangoCon_2019_-_Day_3_Lightning_Talks_12264_17795.png DjangoCon_2019_-_Day_3_Lightning_Talks_17796_26543.png DjangoCon_2019_-_Day_3_Lightning_Talks_26544_35687.png DjangoCon_2019_-_Day_3_Lightning_Talks_35688_39095.png DjangoCon_2019_-_Day_3_Lightning_Talks_39096_39659.png DjangoCon_2019_-_Day_3_Lightning_Talks_39660_40415.png DjangoCon_2019_-_Day_3_Lightning_Talks_40416_41663.png DjangoCon_2019_-_Day_3_Lightning_Talks_41664_42455.png DjangoCon_2019_-_Day_3_Lightning_Talks_42456_43139.png DjangoCon_2019_-_Day_3_Lightning_Talks_43140_43367.png DjangoCon_2019_-_Day_3_Lightning_Talks_43368_43463.png DjangoCon_2019_-_Day_3_Lightning_Talks_43464_43535.png DjangoCon_2019_-_Day_3_Lightning_Talks_43536_43751.png DjangoCon_2019_-_Day_3_Lightning_Talks_43752_44351.png DjangoCon_2019_-_Day_3_Lightning_Talks_44352_44639.png DjangoCon_2019_-_Day_3_Lightning_Talks_44640_44795.png DjangoCon_2019_-_Day_3_Lightning_Talks_44796_44843.png DjangoCon_2019_-_Day_3_Lightning_Talks_44844_46403.png DjangoCon_2019_-_Day_3_Lightning_Talks_46404_50579.png DjangoCon_2019_-_Day_3_Lightning_Talks_50580_56171.png DjangoCon_2019_-_Day_3_Lightning_Talks_56172_59039.png DjangoCon_2019_-_Day_3_Lightning_Talks_59040_59171.png DjangoCon_2019_-_Day_3_Lightning_Talks_59172_59555.png DjangoCon_2019_-_Day_3_Lightning_Talks_59556_59783.png DjangoCon_2019_-_Day_3_Lightning_Talks_59784_59867.png DjangoCon_2019_-_Day_3_Lightning_Talks_59868_59939.png DjangoCon_2019_-_Day_3_Lightning_Talks_59940_60287.png DjangoCon_2019_-_Day_3_Lightning_Talks_60288_60359.png DjangoCon_2019_-_Day_3_Lightning_Talks_60360_60443.png DjangoCon_2019_-_Day_3_Lightning_Talks_60444_60527.png DjangoCon_2019_-_Day_3_Lightning_Talks_60528_62747.png DjangoCon_2019_-_Day_3_Lightning_Talks_62748_62939.png DjangoCon_2019_-_Day_3_Lightning_Talks_62940_66575.png DjangoCon_2019_-_Day_3_Lightning_Talks_66576_74063.png DjangoCon_2019_-_Day_3_Lightning_Talks_74064_74371.png