 So, Steve will now speak about why two developers do have first, so have fun. Hi there. I'm an engineer that works for B-H-G-E, used to be G-E oil and gas, and use Python quite a lot of my work. And this is why I think that it's a very good idea to actually produce a command line interface, even if you go over something that's eventually going to have a nice GUI interface or a web interface. Let's see how we go. Okay. There's lots of things to think about before you actually start doing your GUI. What controls are going to be putting on there? What you need it to do? The functional things, which actually comes down to your code. After all, the really important part, unless you're a graphics designer, which I know there's a few here, is what does the code do? Does it work? Putting a GUI on can take a lot of time, and if you're not a graphics designer, tends to produce a mess for many of us struggle with that sort of thing. It's great on the coding, but getting it looking nice and working, two different challenges. Personally, I think putting a GUI on at the beginning can leave you trapped in things that you don't actually need and spending a lot of time on the GUI development before you've done any coding. A lot of the experts always say that separating your code into a front end and a back end, a business engine, or a GUI, are a good practice. Putting a command line interface in first tends to be a nice slender thing and gives you a degree of that separation. Obviously, some things pretty much hopeless without a GUI. A drawing package, graphics editing packages, you're going to have to put that in. But a lot of the modules within those might well be suitable for having a command line interface anyway and should be developed separately. You can find that if you put a command line interface in for your development, you end up with useful separate utilities as part of your package. One of the obvious areas that you're going to definitely want a GUI, photo editing, photo manipulation. Image magic is one of the most widely used image manipulation programs and it's all on the command line. Any GUIs you get is bolt on. Think twice before you start with a GUI. What's really nice if you put a command line interface in, there are a couple of tools that will let you automatically create at least the first draft of your GUI. If you've developed your code to work on the command line, tested it working on the command line, you know the code's working. It maybe got to the useful utilities. If you can then bolt on a GUI rapidly, that might be the end of the job. Or turn it over to the graphics designer. Having done your code with the command line, you decide things like, that needs to be a flag or that needs to be a file. You decide what you actually need. Once you decide what you need, that tells you what you want in your GUI. Flags are going to be options, tick boxes or toggle menus. A file is going to be the drag or drop or a file selector. Multiple files, same thing. If you've got things that are exclusive choices, they're going to end up being radio buttons. But till you start coding, you're not going to find out. Unless you've got a really good spec. Frankly, that doesn't happen very often. You've got a couple of choices. You can either make your own mapping from your command line options to a GUI, or there's a couple of choices. GUI and Quick. Which of those you use depends on a couple of issues. If you've developed your command line using arg pass, then it's in the standard library. You can use GUI, and that will create you a WX widgets, WX Python, GUI interface. There's actually a couple of choices within the GUI library of how you go about it. But they're incredibly useful. If you've used CLIC for your command line, that's very popular. That generates your GUI for you using Quick, or gives you the option of doing it with Quick. That will give you a QT5 GUI. Personalistic, clearer QT rather than WX, because there's licensing issues that my employer doesn't like with QT. WX is a much simpler licensing model, but may vary between you. Personalistic, I also like using the arg pass method because it basically comes down to something that's stored in a dictionary. It's a lot easier to manipulate the dictionary if you can decide to roll your own GUI generation than it is if you've got to parse, help and doc strings, which is what QT does for you, what CLIC does for you. I'm going to be concentrating on the WX widgets-based and arg pass apologies to anyone that loves CLIC. I think CLIC's great, but in this case, we're going to skip it. There's lots of examples in how to use arg pass. How many people have used it in the past? A vast majority. How many haven't? Not many. We don't need to go too much into what arg pass gives you, but a quick couple of examples. In this case, we're creating in our parse arguments a parser to do our parsing for us, adding a bit of information into it, adding a couple of arguments that we want, one or more input files. I know the text is a little bit small on that, and I'm not sure if I can zoom on this. Let's try. I don't have the option, I'm afraid. I will be posting the actual code up onto GitHub. Let's try it. You've been featuring this idea since this last time I tried that. We've got a parser being created, giving some information to store for the helps, and we've added three arguments. One logic flag, reverse. It's fairly meaningless, that example. Obviously, if we go to the command line, we can just run that with... Give it no information, it gives us our base message. If we ask for help, it tells us what our options are, and in this particular case, if we just give it a file name, then it tells us what the options have been selected. Which have been the defaults. If we decide to go across to the simplest GUI version, we need to add two whole lines to our code, an import of GUI and a decorator. The only difference between the two files. Now when we run it, our GUI. Not bad for two lines, is it? Okay, it's rough and crude, but it does more or less the job we need. One of the things I don't particularly like about it, is that your files is a type in or paste in field, but luckily, arg pass does give us a way around this. Yeah, WX Python is available and pip installable on most platforms, and is Python 3 compatible now since version 4, which is a big step forward, as is the pip install before it was in the Xe to install, which was a little bit more troublesome, and you couldn't use it in virtual environments very easily. They made great strides on that. So, if we go to our third demo, third example, we've got exactly the same code again. This time, we're using GUI parser instead of our standard parser. Yeah, and we've added to our infile option an override of widget equals file chooser. So, not a huge difference. This time, when I run it, we get a slightly different GUI. We've got a browse button, and we can pick our file or files, and when we run it, it does everything nicely for us. You can see there we've got our details of the file that's been opened as an IOS stream. Yeah. So, generating a GUI from command line once you've got the command line is easy. Yeah. It's not the prettiest GUI. It's a good starting point, though. Just for that example of rolling your own, I pointed out that one of the things that distinguished click and arg pass is that arg pass isn't parsing your doc strings. It's generating... You're actually supplying a set of ad arguments. Yeah. Those ad arguments, when you look at it, it could pretty much be a dictionary. A dictionary entry. Yeah, because you've got for a particular line a list of names to put it in, and then a set of parameters, which are named parameters. It sounds like a dictionary to me. Yeah. So, of course, when we come to rolling our own, we can use the same sort of trick in here. I've got a list of dictionaries, one for the command line arguments, or command line and one page up. A base set of arguments, a set of optional arguments, command line arguments, or command line only arguments, and graphic GUI only arguments. This is an example of rolling your own. Yeah. Basically, I'm parsing those and using those to generate a WX interface myself, and just to give you a flavour of what that looks like. Now, this one, I've actually got a little bit sneaky, and it runs from the command line with no arguments. It will start the GUI, and I've got a drag and drop area rather than a file chooser, but you can also use it from the command line with exactly the same code. If it got command line arguments, it processes them and runs. It doesn't start the GUI. So, we've got the best of both worlds. Quickly run through the rest of the slides. We've got options of running it, installing it. Think about it. A command line interface, a CGI web interface is going to take pretty much the same parameters. A microservices interface is going to take the same parameters and parse them between, and if you're pipelining things, then you can do that again. It's all the command line. You can automate your tests, make sure you've got your business loads. You haven't got to pay someone to click on things, or spend a lot of time mocking things up, or automating GUI clicks. You can just test your GUI separately, and if you happen to have to do a GUI in Arabic, or Chinese, or something like that, the reasonable chance you won't even understand what the labels on the buttons are yourself. Get your back-end right, and you're a long way there. Once we've done that, you can package it up into an EXE. Plenty of ways of doing that if you were on Windows, or into an app for Mac. I'm afraid I don't do much Mac, so generating apps is a little bit outside my field. Or, as I said, put it inside a container, or on a web server, you've got all the options available. Once I actually managed to get the code up loaded into GitHub, that would be the URL that the code and the slides would be available at. Any questions? Thank you. It depends on what you're doing. For the GUI, I wanted to have the option of preserving which tickboxes were selected. I didn't want that option available for the command line, so just separating them out into two separate lists made life a little bit easier. I could, in my dictionary of entries, I could use the command line so I could use the command line so I could use the command line so I could use the command line so I could use the command line in my dictionary of entries for all of them. I had the option of putting extra parameters in that argpass wouldn't take that the GUI needed, and just filtering them if I was building the command line makes life very easy. It would be nice to actually get a slight change to argpass to give it an option for ignoring any parameters you don't understand in this context. But then again, moaning about anything that doesn't understand is probably a good idea most of the time. If so, that's great. That would be good. Anyone else? Yeah. Have you ever created results with choices? Because my company is switching from argpass to SNAP because you can do non-modules so you can first select a module that you want to have in the spring. Yeah. I've not used that particular approach, but I've got a command line framework that you can access to the module which either click or argpass can give you. The magic of the if-def main is very useful. I've had a lot of bits of larger programs that have actually turned out to be more useful and more popular than the whole program or certainly more used. But because I'd put a wrap around them to be able to test them as a standalone, hey, we can use that. Need it. So I've not tried that particular package and used it. Anyone else? In general, it tends to the automatic generation tools tend to just go on the order of the arguments and do their own thing. Obviously if you're with the role of your own example, I've got to choose and say, right, these are all going to be in a block or a group and then you can do it. I was pleasantly surprised how easy it was to generate your own automatically-generatable GUI rather than generating a GUI separately. There's pretty much a one-to-one. Almost every GUI and of course you can take the same approach for rolling your own. If you want to use a different GUI library altogether, one that's not supported then that's fine. You just work out your mappings and say, right, from my list of arguments these are the options I need to produce and the types of the options and just about every GUI library that I've come across gives you a way of selecting files or file paths. It gives you a way of selecting on-off options a way of making choices a way of triggering events. Not a lot else to do. Any more? Yeah? Is it possible to get the code that generates the GUI so that you can do minor customisations? Yeah, it's all open source code. The library generates the GUI for you but in the background it generates some code that would rather be possible to get that code. You could adjust the library. The current libraries that don't, as far as I know actually generate a GUI code as such. I think there's actually a couple of other libraries that do the same sort of thing that generate Java GUIs for you, for the web interfaces and those you could probably tweak afterwards. I'd discourage that personally because it's much better to change the way that the generation generates it so it will always generate it right. So when you make a change you've got your change in your new GUI. If you've got a customisation step in between then you're going to be on holiday one day when a really urgent change needs making and the customisation steps not going to happen. Yeah? And then, hey, that code that has got, it's a total mess. Yeah? Also when the libraries are updated you always need to read how you're doing it, yeah. Because these are open source libraries if you come up with a good way and it's a real improvement you usually find the author will be willing to take it on and incorporate it in the library or you can fork the library and it's in the same direction. The joy of open source. Okay, last one. It is, you can use a redirect to standard out to a standard out window. You can capture your standard out and redirect it to it and where that redirection occurs to you've normally got a choice about so you could have a component within your GUI to capture the standard out. The only problem is of course that if the library fails to be built you're not going to be able to see your log. Okay. Right, and my time is just about up, I think. Yeah, it's about up. Okay, thank you Steve. Thank you.